diff --git a/.impeccable/design.json b/.impeccable/design.json index 73962735..74b73848 100644 --- a/.impeccable/design.json +++ b/.impeccable/design.json @@ -173,7 +173,7 @@ "refersTo": "button-primary", "description": "浅色内容区的主要操作,使用可读深金而不是亮金。", "html": "", - "css": ".ds-btn-primary { height: 34px; padding: 0 14px; border: 1px solid #856632; border-radius: 8px; background: #856632; color: #fff; font: 500 13px/1.5 'JetBrains Mono', 'Microsoft YaHei', monospace; cursor: pointer; transition: background 150ms cubic-bezier(.22,1,.36,1), border-color 150ms cubic-bezier(.22,1,.36,1); } .ds-btn-primary:hover { background: #6A5129; border-color: #6A5129; } .ds-btn-primary:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(133,102,50,.20); } .ds-btn-primary:active { transform: translateY(1px); } .ds-btn-primary:disabled { opacity: .55; cursor: not-allowed; transform: none; }" + "css": ".ds-btn-primary { height: 34px; padding: 0 14px; border: 1px solid #856632; border-radius: 8px; background: #856632; color: #fff; font: 500 13px/1.5 'JetBrains Mono', 'CaiWu CJK', monospace; cursor: pointer; transition: background 150ms cubic-bezier(.22,1,.36,1), border-color 150ms cubic-bezier(.22,1,.36,1); } .ds-btn-primary:hover { background: #6A5129; border-color: #6A5129; } .ds-btn-primary:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(133,102,50,.20); } .ds-btn-primary:active { transform: translateY(1px); } .ds-btn-primary:disabled { opacity: .55; cursor: not-allowed; transform: none; }" }, { "name": "Secondary Button", @@ -181,7 +181,7 @@ "refersTo": "button-secondary", "description": "次要操作保持白底、暖灰边界和正文墨色。", "html": "", - "css": ".ds-btn-secondary { height: 34px; padding: 0 14px; border: 1px solid #D8D2C7; border-radius: 8px; background: #fff; color: #171717; font: 500 13px/1.5 'JetBrains Mono', 'Microsoft YaHei', monospace; cursor: pointer; transition: background 150ms cubic-bezier(.22,1,.36,1), border-color 150ms cubic-bezier(.22,1,.36,1); } .ds-btn-secondary:hover { border-color: #A17D3E; background: #FBF8F1; } .ds-btn-secondary:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(133,102,50,.20); } .ds-btn-secondary:active { background: #F7F0DE; } .ds-btn-secondary:disabled { opacity: .55; cursor: not-allowed; }" + "css": ".ds-btn-secondary { height: 34px; padding: 0 14px; border: 1px solid #D8D2C7; border-radius: 8px; background: #fff; color: #171717; font: 500 13px/1.5 'JetBrains Mono', 'CaiWu CJK', monospace; cursor: pointer; transition: background 150ms cubic-bezier(.22,1,.36,1), border-color 150ms cubic-bezier(.22,1,.36,1); } .ds-btn-secondary:hover { border-color: #A17D3E; background: #FBF8F1; } .ds-btn-secondary:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(133,102,50,.20); } .ds-btn-secondary:active { background: #F7F0DE; } .ds-btn-secondary:disabled { opacity: .55; cursor: not-allowed; }" }, { "name": "Text Field", @@ -189,7 +189,7 @@ "refersTo": "input-default", "description": "紧凑、清晰、具有可见标签和深金焦点状态的业务输入框。", "html": "", - "css": ".ds-field { display: inline-flex; min-width: 220px; flex-direction: column; gap: 5px; color: #171717; font-family: 'JetBrains Mono', 'Microsoft YaHei', monospace; } .ds-field-label { color: #595959; font-size: 12px; font-weight: 500; line-height: 16px; } .ds-field-input { height: 34px; padding: 0 10px; border: 1px solid #D8D2C7; border-radius: 8px; background: #fff; color: #171717; font: 400 13px/1.5 inherit; outline: none; transition: border-color 150ms cubic-bezier(.22,1,.36,1), box-shadow 150ms cubic-bezier(.22,1,.36,1); } .ds-field-input::placeholder { color: #595959; } .ds-field-input:hover { border-color: #AFA99E; } .ds-field-input:focus { border-color: #856632; box-shadow: 0 0 0 3px rgba(133,102,50,.20); } .ds-field-input:disabled { background: #EEE9DF; color: #595959; cursor: not-allowed; }" + "css": ".ds-field { display: inline-flex; min-width: 220px; flex-direction: column; gap: 5px; color: #171717; font-family: 'JetBrains Mono', 'CaiWu CJK', monospace; } .ds-field-label { color: #595959; font-size: 12px; font-weight: 500; line-height: 16px; } .ds-field-input { height: 34px; padding: 0 10px; border: 1px solid #D8D2C7; border-radius: 8px; background: #fff; color: #171717; font: 400 13px/1.5 inherit; outline: none; transition: border-color 150ms cubic-bezier(.22,1,.36,1), box-shadow 150ms cubic-bezier(.22,1,.36,1); } .ds-field-input::placeholder { color: #595959; } .ds-field-input:hover { border-color: #AFA99E; } .ds-field-input:focus { border-color: #856632; box-shadow: 0 0 0 3px rgba(133,102,50,.20); } .ds-field-input:disabled { background: #EEE9DF; color: #595959; cursor: not-allowed; }" }, { "name": "Sidebar Active Item", @@ -197,7 +197,7 @@ "refersTo": "sidebar-item-active", "description": "浅黑功能栏上的单一圆形 chevron 活动状态。", "html": "
店铺收款账户账单›
", - "css": ".ds-sidebar { width: 224px; padding: 8px; background: #1D1D1F; } .ds-sidebar-item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 4px; color: #F0E4BF; font: 500 12px/16px 'JetBrains Mono', 'Microsoft YaHei', monospace; text-decoration: none; transition: background 150ms cubic-bezier(.22,1,.36,1); } .ds-sidebar-item:hover { background: rgba(240,228,191,.10); } .ds-sidebar-item.is-active { background: #2A2927; color: #F2E7C5; } .ds-sidebar-icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; } .ds-active-indicator { display: inline-flex; width: 16px; height: 16px; margin-left: auto; align-items: center; justify-content: center; border: 1px solid rgba(246,233,194,.72); border-radius: 999px; background: rgba(246,233,194,.14); color: #F6E9C2; font-size: 14px; } .ds-sidebar-item:focus-visible { outline: 2px solid #F2E7C5; outline-offset: 2px; }" + "css": ".ds-sidebar { width: 224px; padding: 8px; background: #1D1D1F; } .ds-sidebar-item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 4px; color: #F0E4BF; font: 500 12px/16px 'JetBrains Mono', 'CaiWu CJK', monospace; text-decoration: none; transition: background 150ms cubic-bezier(.22,1,.36,1); } .ds-sidebar-item:hover { background: rgba(240,228,191,.10); } .ds-sidebar-item.is-active { background: #2A2927; color: #F2E7C5; } .ds-sidebar-icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; } .ds-active-indicator { display: inline-flex; width: 16px; height: 16px; margin-left: auto; align-items: center; justify-content: center; border: 1px solid rgba(246,233,194,.72); border-radius: 999px; background: rgba(246,233,194,.14); color: #F6E9C2; font-size: 14px; } .ds-sidebar-item:focus-visible { outline: 2px solid #F2E7C5; outline-offset: 2px; }" }, { "name": "Workspace Tabs", @@ -205,7 +205,7 @@ "refersTo": "tab-active", "description": "白色工作区内使用深金活动文字和单一金色下划线的局部标签切换。", "html": "", - "css": ".ds-tabs { display: flex; align-items: center; gap: 36px; min-height: 34px; padding: 0 32px; overflow-x: auto; border: 1px solid #D8D2C7; border-radius: 16px; background: #fff; } .ds-tab { position: relative; display: inline-flex; min-height: 34px; align-items: center; color: #595959; font: 600 14px/1.25 'JetBrains Mono', 'Microsoft YaHei', monospace; text-decoration: none; white-space: nowrap; transition: color 150ms cubic-bezier(.22,1,.36,1); } .ds-tab:hover, .ds-tab.is-active { color: #856632; } .ds-tab.is-active::after { position: absolute; right: 0; bottom: 0; left: 0; height: 3px; border-radius: 999px 999px 0 0; background: #B9954F; content: ''; } .ds-tab:focus-visible { outline: 2px solid #856632; outline-offset: 3px; }" + "css": ".ds-tabs { display: flex; align-items: center; gap: 36px; min-height: 34px; padding: 0 32px; overflow-x: auto; border: 1px solid #D8D2C7; border-radius: 16px; background: #fff; } .ds-tab { position: relative; display: inline-flex; min-height: 34px; align-items: center; color: #595959; font: 600 14px/1.25 'JetBrains Mono', 'CaiWu CJK', monospace; text-decoration: none; white-space: nowrap; transition: color 150ms cubic-bezier(.22,1,.36,1); } .ds-tab:hover, .ds-tab.is-active { color: #856632; } .ds-tab.is-active::after { position: absolute; right: 0; bottom: 0; left: 0; height: 3px; border-radius: 999px 999px 0 0; background: #B9954F; content: ''; } .ds-tab:focus-visible { outline: 2px solid #856632; outline-offset: 3px; }" }, { "name": "Business Panel", @@ -213,21 +213,21 @@ "refersTo": "panel", "description": "使用白色表面、暖灰边界和有限圆角的单层业务容器。", "html": "

账单明细

按账户和日期范围核对交易数据。

", - "css": ".ds-panel { padding: 16px; border: 1px solid #D8D2C7; border-radius: 12px; background: #fff; color: #171717; font-family: 'JetBrains Mono', 'Microsoft YaHei', monospace; } .ds-panel-title { margin: 0; color: #171717; font-size: 14px; font-weight: 600; line-height: 1.25; } .ds-panel-copy { max-width: 70ch; margin: 8px 0 0; color: #595959; font-size: 13px; line-height: 1.5; } .ds-panel:focus-within { border-color: #856632; }" + "css": ".ds-panel { padding: 16px; border: 1px solid #D8D2C7; border-radius: 12px; background: #fff; color: #171717; font-family: 'JetBrains Mono', 'CaiWu CJK', monospace; } .ds-panel-title { margin: 0; color: #171717; font-size: 14px; font-weight: 600; line-height: 1.25; } .ds-panel-copy { max-width: 70ch; margin: 8px 0 0; color: #595959; font-size: 13px; line-height: 1.5; } .ds-panel:focus-within { border-color: #856632; }" }, { "name": "Status Tags", "kind": "chip", "description": "语义颜色只表达真实业务状态,并始终带文字。", "html": "
已核对待处理异常
", - "css": ".ds-tags { display: flex; gap: 8px; font-family: 'JetBrains Mono', 'Microsoft YaHei', monospace; } .ds-tag { display: inline-flex; min-height: 24px; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 500; } .ds-tag-success { background: #F1F6EE; color: #53793E; } .ds-tag-warning { background: #FEF5E7; color: #935F07; } .ds-tag-danger { background: #FAE6E6; color: #B80000; }" + "css": ".ds-tags { display: flex; gap: 8px; font-family: 'JetBrains Mono', 'CaiWu CJK', monospace; } .ds-tag { display: inline-flex; min-height: 24px; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 500; } .ds-tag-success { background: #F1F6EE; color: #53793E; } .ds-tag-warning { background: #FEF5E7; color: #935F07; } .ds-tag-danger { background: #FAE6E6; color: #B80000; }" }, { "name": "Finance Data Table", "kind": "custom", "description": "紧凑、可扫描、数字右对齐的财务数据表。支持列显示/隐藏、拖动排序、恢复默认及按用户和具体表格保存;冻结多层表头,横向滚动条始终可达。导出明确筛选范围和可见列顺序,保留精度并排除密码;允许导入的业务提供模板、预览、校验及失败反馈,只读镜像不写回。", "html": "
订单号收入余额
20260722001¥1,280.00¥8,460.00
", - "css": ".ds-table { width: 100%; border-collapse: collapse; overflow: hidden; border: 1px solid #D8D2C7; border-radius: 12px; background: #fff; color: #171717; font: 400 12.5px/1.5 'JetBrains Mono', 'Microsoft YaHei', monospace; } .ds-table th { padding: 9px 10px; border-bottom: 1px solid #D8D2C7; background: #FBF8F1; color: #595959; font-size: 12px; font-weight: 600; text-align: left; } .ds-table td { padding: 9px 10px; border-bottom: 1px solid #EEE9DF; } .ds-table tbody tr:hover { background: #F7F0DE; } .ds-table .ds-num { text-align: right; font-variant-numeric: tabular-nums; } .ds-table .ds-income { color: #B80000; font-weight: 600; }" + "css": ".ds-table { width: 100%; border-collapse: collapse; overflow: hidden; border: 1px solid #D8D2C7; border-radius: 12px; background: #fff; color: #171717; font: 400 12.5px/1.5 'JetBrains Mono', 'CaiWu CJK', monospace; } .ds-table th { padding: 9px 10px; border-bottom: 1px solid #D8D2C7; background: #FBF8F1; color: #595959; font-size: 12px; font-weight: 600; text-align: left; } .ds-table td { padding: 9px 10px; border-bottom: 1px solid #EEE9DF; } .ds-table tbody tr:hover { background: #F7F0DE; } .ds-table .ds-num { text-align: right; font-variant-numeric: tabular-nums; } .ds-table .ds-income { color: #B80000; font-weight: 600; }" } ], "narrative": { @@ -236,7 +236,7 @@ "keyCharacteristics": [ "深黑工具轨道、浅黑功能栏、浅色内容区,三层边界清楚。", "浅金用于深色导航,深金用于浅色内容区的文字与主要操作。", - "全站使用 JetBrains Mono,标题和数据采用固定字号,不使用流体放大。", + "全站使用 JetBrains Mono 与仓库内置 CaiWu CJK 字体,标题和数据采用固定字号,不使用流体放大。", "页面标题位于内容区右侧,保持 14px;导航使用统一的紧凑字号。", "一、二级导航统一 12px;同一层级的图标、字号和交互状态必须一致。", "表格、筛选器和状态反馈优先,装饰性卡片、阴影和动画受到严格限制。", @@ -250,6 +250,7 @@ { "name": "The Fixed-Scale Rule", "body": "产品界面使用固定 rem 字号,不使用 clamp() 放大标题;桌面与移动端通过布局重排适配,不通过夸张缩放字体适配。", "section": "typography" }, { "name": "The Stable-First-Paint Rule", "body": "关键字号、行高和容器尺寸必须由首屏 CSS 直接提供,不能等待 JavaScript 或异步样式后再缩小,禁止首次进入时出现巨大字体闪烁。", "section": "typography" }, { "name": "The One-Family Rule", "body": "按钮、标签、导航、表格和正文都使用同一字体家族;禁止在数据界面引入装饰性展示字体。", "section": "typography" }, + { "name": "The Cross-Platform Control Rule", "body": "业务控件不得依赖 macOS、Windows 或不同浏览器的原生外观。字体使用仓库内置 Web 字体;下拉框、复选框、日期选择、联想输入使用项目自绘控件;桌面筛选区使用明确 CSS 网格。新页面必须在 Safari 与 Chromium 下验证布局、换行和控件尺寸一致。", "section": "typography" }, { "name": "The Flat-by-Default Rule", "body": "静态业务面板默认无阴影;若已经有 1px 边框,不得再叠加 16px 以上模糊半径的宽阴影。", "section": "elevation" }, { "name": "The No-Nested-Cards Rule", "body": "卡片只用于真实分组;卡片内部不能再套同样外观的卡片。优先使用标题、间距、分隔线和表格分组表达层级。", "section": "elevation" } ], diff --git a/DESIGN.md b/DESIGN.md index 9daed852..5b3ffa6e 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -22,22 +22,22 @@ colors: info: "#006395" typography: title: - fontFamily: "JetBrains Mono, Microsoft YaHei, PingFang SC, monospace" + fontFamily: "JetBrains Mono, CaiWu CJK, monospace" fontSize: "0.875rem" fontWeight: 600 lineHeight: 1.25 body: - fontFamily: "JetBrains Mono, Microsoft YaHei, PingFang SC, monospace" + fontFamily: "JetBrains Mono, CaiWu CJK, monospace" fontSize: "0.8125rem" fontWeight: 400 lineHeight: 1.5 label: - fontFamily: "JetBrains Mono, Microsoft YaHei, PingFang SC, monospace" + fontFamily: "JetBrains Mono, CaiWu CJK, monospace" fontSize: "0.75rem" fontWeight: 500 lineHeight: 1.333 data: - fontFamily: "JetBrains Mono, Microsoft YaHei, PingFang SC, monospace" + fontFamily: "JetBrains Mono, CaiWu CJK, monospace" fontSize: "0.78125rem" fontWeight: 400 lineHeight: 1.5 @@ -180,9 +180,9 @@ CaiWuXiTong 是一个需要长时间、高频率使用的财务工作台。视 ## 3. Typography -**Display Font:** JetBrains Mono (with Microsoft YaHei, PingFang SC, monospace) +**Display Font:** JetBrains Mono (with bundled CaiWu CJK, monospace) -**Body Font:** JetBrains Mono (with Microsoft YaHei, PingFang SC, monospace) +**Body Font:** JetBrains Mono (with bundled CaiWu CJK, monospace) **Label/Mono Font:** JetBrains Mono @@ -206,6 +206,8 @@ CaiWuXiTong 是一个需要长时间、高频率使用的财务工作台。视 **The One-Family Rule.** 按钮、标签、导航、表格和正文都使用同一字体家族;禁止在数据界面引入装饰性展示字体。 +**The Cross-Platform Control Rule.** 业务控件不得依赖 macOS、Windows 或不同浏览器的原生外观。字体使用仓库内置 Web 字体;下拉框、复选框、日期选择、联想输入使用项目自绘控件;桌面筛选区使用明确 CSS 网格。新页面必须在 Safari 与 Chromium 下验证布局、换行和控件尺寸一致。 + ## 4. Elevation 界面默认采用“色调分层 + 细边界”,不是依赖大阴影堆叠。工具轨道、功能栏和内容区通过背景明度形成第一层深度;内容面板通过白色表面与细边界形成第二层。阴影只用于浮层或短暂交互反馈。 @@ -263,6 +265,7 @@ CaiWuXiTong 是一个需要长时间、高频率使用的财务工作台。视 - 标准高度 34px,8px 圆角,白底、1px 边界;标签位于字段上方,12px/500。 - 聚焦使用深金边框和半透明焦点环;占位文字至少使用辅助墨色,不允许低对比浅灰。 - 错误状态使用语义危险色、明确文字和错误图标;不能只把边框染红。 +- 不使用原生 `datalist`、系统日期框或未归一的系统下拉外观承载业务交互;关联选项使用项目自绘菜单或勾选面板,避免 macOS 与 Windows 显示不同。 ### Cards / Containers diff --git a/app/Http/Controllers/Business/SystemizationTodos.php b/app/Http/Controllers/Business/SystemizationTodos.php index 4d758834..20035706 100644 --- a/app/Http/Controllers/Business/SystemizationTodos.php +++ b/app/Http/Controllers/Business/SystemizationTodos.php @@ -26,7 +26,7 @@ class SystemizationTodos extends Controller 'today' => '今天到期', 'upcoming' => '剩余天数', 'pending' => '时间待定', - 'none' => '无提醒', + 'none' => '已完成', ]; private const OWNER_OPTIONS = ['人参', '晨曦', '常仪', '待定']; private const COLUMN_WIDTHS_SETTING = 'business.systemization_todos.column_widths'; @@ -196,6 +196,7 @@ class SystemizationTodos extends Controller 'label' => $status, ]); } + $todoAssignees = $this->peopleOptions('assignee'); return [ 'view' => 'business.pages.systemization-todos', @@ -206,7 +207,8 @@ class SystemizationTodos extends Controller 'todoCategories' => $categories, 'todoContentOptions' => $this->contentOptions(), 'todoOwners' => collect(self::OWNER_OPTIONS), - 'todoAssignees' => $this->peopleOptions('assignee'), + 'todoAssignees' => $todoAssignees, + 'todoAssigneeOwners' => $this->assigneeOwnerMap($todoAssignees), 'todoStatuses' => SystemizationTodo::STATUSES, 'todoStatusOptions' => $statusOptions, 'todoReminderOptions' => collect(self::REMINDER_OPTIONS) @@ -898,6 +900,46 @@ class SystemizationTodos extends Controller ->values(); } + private function assigneeOwnerMap(Collection $assignees): array + { + $derived = []; + SystemizationTodo::query() + ->whereNotNull('assignee') + ->where('assignee', '<>', '') + ->get(['owner', 'assignee']) + ->each(function (SystemizationTodo $todo) use (&$derived): void { + $owners = $this->ownerNames($todo->owner); + foreach ($this->personNames($todo->assignee) as $assignee) { + foreach ($owners as $owner) { + $derived[$assignee][$owner] = true; + } + } + }); + + $map = []; + foreach ($assignees as $assignee) { + if (isset(self::OWNER_ALIASES[$assignee])) { + $map[$assignee] = [self::OWNER_ALIASES[$assignee]]; + continue; + } + $ownerSet = $derived[$assignee] ?? []; + $map[$assignee] = array_values(array_filter( + self::OWNER_OPTIONS, + static fn (string $owner): bool => isset($ownerSet[$owner]), + )); + } + + return $map; + } + + private function personNames(?string $value): array + { + return array_values(array_unique(array_filter( + array_map('trim', preg_split('/[、,,;;\/]+/u', trim((string) $value)) ?: []), + static fn (string $name): bool => $name !== '' && $name !== '—', + ))); + } + private function normalizeOwnerFilterValues(array $owners): array { return collect($owners) diff --git a/resources/views/business/pages/systemization-todos.blade.php b/resources/views/business/pages/systemization-todos.blade.php index aa319e5a..43cce9ce 100644 --- a/resources/views/business/pages/systemization-todos.blade.php +++ b/resources/views/business/pages/systemization-todos.blade.php @@ -50,6 +50,7 @@ .sys-todo-filter__multi-value { font-size:.8125rem; line-height:1.35; overflow-wrap:anywhere; white-space:normal; } .sys-todo-filter__multi-menu { position:absolute; top:calc(100% + .3rem); left:0; z-index:20; display:grid; width:max(100%,13rem); max-height:17rem; padding:.35rem; border:1px solid var(--sys-border); border-radius:.55rem; background:#fff; box-shadow:0 8px 22px rgba(23,23,23,.16); overflow:auto; } .sys-todo-filter__multi-menu label { display:flex; flex:none; align-items:center; gap:.45rem; min-height:2rem; padding:.3rem .45rem; border-radius:.35rem; color:#333; font-size:.78rem; cursor:pointer; } + .sys-todo-filter__multi-menu label[hidden] { display:none; } .sys-todo-filter__multi-menu label:hover { background:var(--sys-gold-soft); } .sys-todo-filter__multi-menu input[type="checkbox"] { flex:0 0 auto; width:1rem; height:1rem; padding:0; accent-color:var(--sys-gold); } .sys-todo-filter__multi-empty { padding:.65rem; color:#777; font-size:.75rem; text-align:center; } @@ -166,6 +167,7 @@ .sys-todo-new-category[hidden] { display:none; } .sys-todo-owner-checks { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.2rem .45rem; max-height:7rem; padding:.4rem; border:1px solid var(--sys-border); border-radius:.45rem; background:#fff; overflow:auto; } .sys-todo-owner-checks label { display:flex; align-items:center; gap:.35rem; min-height:1.6rem; color:#333; font-size:.76rem; cursor:pointer; } + .sys-todo-owner-checks label[hidden] { display:none; } .sys-todo-owner-checks label:hover { color:var(--sys-gold); } .sys-todo-owner-checks input[type="checkbox"] { flex:0 0 auto; width:1rem; height:1rem; min-height:0; padding:0; accent-color:var(--sys-gold); } .sys-todo-page input[type="checkbox"] { @@ -193,6 +195,7 @@ background-size:.72rem; } .sys-todo-page input[type="checkbox"]:focus-visible { outline:2px solid var(--sys-gold); outline-offset:2px; } + .sys-todo-assignee-note { margin:0; color:#777; font-size:.68rem; line-height:1.4; } .sys-todo-upload-zone { display:flex; flex-wrap:wrap; align-items:center; gap:.45rem .65rem; min-height:4.5rem; padding:.7rem; border:1px dashed #cfc3ad; border-radius:.55rem; background:#fcfaf5; } .sys-todo-upload-zone input[type="file"] { position:absolute; width:1px; height:1px; padding:0; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; } .sys-todo-upload-button { display:inline-flex; align-items:center; justify-content:center; min-height:2rem; padding:0 .75rem; border:1px solid var(--sys-gold); border-radius:.4rem; background:var(--sys-gold); color:#fff; font-size:.78rem; cursor:pointer; } @@ -397,13 +400,14 @@
@forelse ($todoAssignees as $assignee) -
@@ -776,7 +780,22 @@ - +
+ 责任人 +
+ @forelse ($todoAssignees as $assignee) + + @empty + 暂无可选责任人 + @endforelse + +
+ +

选择总负责人后可快速定位对应责任人;选择责任人也会自动关联总负责人。

+
@@ -940,8 +959,6 @@
- @foreach ($todoAssignees as $assignee) -