feat(projects): 新增项目、执行、任务等功能
This commit is contained in:
24
AGENTS.md
24
AGENTS.md
@@ -58,6 +58,7 @@
|
||||
- `build/plugins/router.ts`:elegant-router 配置与路由元信息生成逻辑
|
||||
- `src/hooks/common/table.ts`:列表页表格 hook 主入口
|
||||
- `src/hooks/common/form.ts`:表单校验与表单实例 hook
|
||||
- `src/constants/status-tag.ts`:业务对象状态颜色(ElTag type)集中配置
|
||||
- `src/styles/scss/element-plus.scss`:当前项目表格、弹层、按钮、表单密度与公共壳样式标准
|
||||
- `packages/*`:项目内本地共享库
|
||||
- `docs/`:当前工作上下文的一部分,做架构级、权限级、页面规范级改动前优先查阅
|
||||
@@ -136,17 +137,18 @@
|
||||
- 页面组件保持“编排层薄”。页面文件主要负责搜索参数、表格 hook、列定义、弹层开关、接口调用编排,不把大量表单细节和重复交互直接堆在页面根组件里。
|
||||
- 列表页优先拆出同目录下的 `modules/*` 子组件,例如搜索组件、操作弹层、详情抽屉、资源面板等。
|
||||
- 系统管理下现有 `user`、`role`、`menu`、`dict` 页面可以作为参考实现,新增同类页面优先沿用它们的拆分方式。
|
||||
- 搜索组件优先复用 `src/components/custom/table-search-panel.vue` 作为外壳。搜索模块本身应尽量只接收 `model`,只向外发出 `reset` / `search`,不直接承载列表请求逻辑。
|
||||
- 新增或触达列表页搜索组件时,必须按 `docs/table-search-fields-usage.md` 使用 `src/components/custom/table-search-fields.vue` 的 `fields` 声明式配置,不得手写 `ElRow / ElCol / ElFormItem` 搜索区骨架;只有字段存在复杂联动、自定义插槽或 `TableSearchFields` 明确无法承载时,才允许退回 `src/components/custom/table-search-panel.vue`,并需要在实施说明中写明原因。搜索模块本身应尽量只接收 `model` 和必要选项,只向外发出 `reset` / `search`,不直接承载列表请求逻辑。
|
||||
- 列表能力优先复用 `src/hooks/common/table.ts` 中的 `useUIPaginatedTable`、`useTableOperate`、`defaultTransform`。
|
||||
- 表单能力优先复用 `src/hooks/common/form.ts` 中的 `useForm`、`useFormRules`。
|
||||
- 当前项目的真实业务口径是“内网中文优先”。新增业务页不必为了形式强行补全国际化键;但如果是在已有大量 `$t(...)` 的页面或模块内继续开发,优先保持该局部代码风格一致,不要半页中文直写、半页国际化混用。
|
||||
|
||||
## 表格、搜索区与操作列约束
|
||||
|
||||
- 搜索区按钮组保持在最右侧;存在折叠项时,按钮顺序保持为“展开/收起 -> 重置 -> 查询”。
|
||||
- 不要在每个页面重新拼一套搜索区骨架,优先延续 `TableSearchPanel` 的结构和交互。
|
||||
- 搜索区按钮组必须固定在第一行最后一个位置;存在折叠项时,按钮顺序保持为“展开/收起 -> 重置 -> 查询”。这是 `TableSearchFields` 的布局契约,不允许因为查询条件不足、展开/收起或响应式样式把按钮提前到中间位置或挤到后续行。
|
||||
- 不要在每个页面重新拼一套搜索区骨架;常规查询条件必须使用 `TableSearchFields`,通过 `columns` 控制每行格子数和折叠阈值。`columns` 表示首行总格数,其中最后 1 格永远留给按钮区;字段不足 `columns - 1` 时由公共组件补空占位,字段超过时剩余字段进入展开区。类似项目管理入口页这类 4 个查询条件的场景,必须使用 `:columns="4"`,形成“3 个条件 + 按钮区”的首行布局。
|
||||
- 表格操作列优先复用 `src/components/custom/business-table-action-cell.tsx`。
|
||||
- 操作数 `<= 2` 时默认直出;操作数 `> 2` 时优先收敛为 `1 个直出主按钮 + 1 个更多按钮`。
|
||||
- 新增列表页如果使用 `ElCard` 承载需要撑满剩余高度的 `ElTable height="100%"`,`body-class` 优先使用公共类 `business-table-card-body`,该类由 `src/styles/scss/element-plus.scss` 统一维护;不要再为每个页面新增 `xxx-table-card-body` 私有样式。历史页面已有私有类时不强制专项回改,当前任务触达相关页面再按公共类收敛。
|
||||
- 表格、按钮、弹层、表单的尺寸和间距标准优先由 `src/styles/scss/element-plus.scss` 和公共组件承接,不在业务页面散落写新的局部尺寸作为事实标准。
|
||||
|
||||
## 表单与弹层约束
|
||||
@@ -154,10 +156,14 @@
|
||||
- 新增、编辑能力优先沿用 `ElDialog / ElDrawer / ElForm / ElScrollbar / #footer` 这一套标准组合,不额外创造新的弹层交互模型。
|
||||
- 轻中量表单优先复用 `src/components/custom/business-form-dialog.vue`;字段较多、需要保留列表上下文或承载重型控件时,再考虑 `src/components/custom/business-form-drawer.vue`。
|
||||
- 表单分组优先复用 `src/components/custom/business-form-section.vue`。
|
||||
- 现有公共壳组件已内置尺寸预设:`dialog` 的 `sm/md/lg` 对应 `520px/640px/720px`,`drawer` 的 `md/lg/xl` 对应 `480px/720px/960px`;优先使用预设值而不是页面内重复硬编码宽度。
|
||||
- 常规 CRUD 表单优先使用 `label-position="top"`、`ElRow + ElCol` 双列布局、`gutter=16`;普通字段优先 `span=12`,长文本或重量级字段优先 `span=24`。
|
||||
- `dialog` 宽度优先按纯表单字段数分三档:`<= 6` 个字段用 `sm`,默认单列,目标宽度 `520px`;`7 ~ 14` 个字段用 `md`,默认双列,目标宽度 `720px`;`> 14` 个字段用 `lg`,仍以双列为主,目标宽度 `960px`。宽度只做响应式收缩,实际宽度不超过 `calc(100vw - 32px)`;不因为单个 `textarea` 自动升档,也不做列数响应式折叠。
|
||||
- 常规 CRUD 表单优先使用 `label-position="top"`、`ElRow + ElCol` 双列布局、`gutter=16`;普通字段优先 `span=12`,长文本或重量级字段优先 `span=24`。如果整体字段数 `<= 6`,默认按单列表单理解。
|
||||
- 当纯表单 `dialog` 因字段数 `<= 6` 归入 `sm` 时,不能只改 `preset`;字段布局也要同步落到单列,常规 `ElCol` 应使用 `span=24`,除非该弹框已经被明确判定为复合内容特例。
|
||||
- 左右分栏、表单 + 表格、表单 + 树、关系编辑器、时间线、大段说明区这类复合内容 `dialog`,不强行按字段数归类;可按内容复杂度单独评估使用 `md`、`lg` 或更宽值,但只有在无法合理归入“纯表单三档”时才允许特例。
|
||||
- 禁止用页面级宽范围样式直接覆盖整页 `.business-form-dialog` 来统一放大弹框;如确实需要特殊宽度,只能精确作用于目标弹框,且不能误伤同页面其他 `dialog`。
|
||||
- 底部按钮顺序固定为“取消 -> 确认”,并保持右对齐。
|
||||
- 单选组和开关类字段优先复用仓库既有样式钩子,例如 `business-form-radio-group`、`business-form-switch-field`。
|
||||
- 权限控制按钮默认采用“无权限不渲染”口径,不要把纯权限不足的入口做成禁用态再展示给用户;只有业务状态暂时不可操作、但仍需让用户感知入口存在时,才允许保留禁用态。
|
||||
|
||||
## 接口、路由与权限约束
|
||||
|
||||
@@ -201,6 +207,14 @@ const directionLabels = getLabels(row.directionCodes, { separator: ',' });
|
||||
- 当前系统已有页面或接口已经稳定使用某个字典,例如用户所属公司 `company -> system_user_company`。
|
||||
- 如果以上两种都没有,就先让后端或业务明确 `dictType`,不要前端自己命名。
|
||||
|
||||
## 业务对象状态颜色集中口径
|
||||
|
||||
- 各业务域(产品、项目、需求、任务、执行、工单等)的 `statusCode -> ElTag type` 集中维护在 `src/constants/status-tag.ts`,不要在各业务页面或模块内散落硬编码同一份映射。
|
||||
- 通用入口是 `getStatusTagType(domain, statusCode)`,未匹配的 `statusCode` 默认回退到 `'info'`。
|
||||
- 业务模块按域写薄包装暴露给页面调用,例如 `getExecutionStatusTagType(code)` 内部调用 `getStatusTagType('projectExecution', code)`,避免页面直接耦合到 domain 字符串。
|
||||
- 新增对象域时同步两处:`StatusDomain` 增加枚举值;`statusTagTypeRegistry` 添加对应 `statusCode -> StatusTagType` 映射。
|
||||
- 后端契约:未来若状态字典开始返回颜色字段,调用方应优先使用后端值,缺失时再回退到 `getStatusTagType` 的前端兜底映射,不要直接绕开集中配置另写一份。
|
||||
|
||||
## 页面资源与菜单目录约束
|
||||
|
||||
- 页面组件键、页面资源、菜单目录是三层不同概念,不要把它们当成同一个值。
|
||||
|
||||
Reference in New Issue
Block a user