From 05dda61fff06ac8ba5ad94f9587a0573bbcf0788 Mon Sep 17 00:00:00 2001 From: “wangming” <“wangming@antissoft.com”> Date: Wed, 1 Apr 2026 22:26:31 +0800 Subject: [PATCH] Enhance attendance settings by adding rest unlock cycle and tolerance rules for late and early leave. Update UI components for better user experience, including improved layout and data binding. Refactor related services to accommodate new features and ensure data integrity. --- .claude/agents/backend-developer.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/agents/frontend-developer.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/agents/orchestrator.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ .claude/agents/test-engineer.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/agents/verifier.md | 36 ++++++++++++++++++++++++++++++++++++ .claude/commands/api-interface-testing.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/commands/api-xml-comments.md | 41 +++++++++++++++++++++++++++++++++++++++++ .claude/commands/deprecated-tables.md | 27 +++++++++++++++++++++++++++ .claude/commands/mcp-mysql.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/commands/remember.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/commands/ui-ux.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/settings.json | 37 +++++++++++++++++++++++++++++++++++++ .cursor/skills/sqlsugar-type-conversion-debug/SKILL.md | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .cursor/skills/workflow-form-development/SKILL.md | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ antis-ncc-admin/src/views/attendance-setting/components/attendance-config-item-dialog.vue | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------- antis-ncc-admin/src/views/attendance-setting/components/attendance-group-table.vue | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- antis-ncc-admin/src/views/attendance-setting/index.vue | 288 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------ antis-ncc-admin/src/views/workFlow/leave-apply-pages/components/leave-apply-page.vue | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------- antis-ncc-admin/src/views/workFlow/leave-apply-pages/paid-leave-apply/index.vue | 12 ++++++++++-- antis-ncc-admin/src/views/workFlow/leave-apply-pages/personal-leave-apply/index.vue | 12 ++++++++++-- antis-ncc-admin/src/views/workFlow/leave-apply-pages/rest-leave-apply/index.vue | 12 ++++++++++-- netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqAttendanceSetting/AttendanceRuleModels.cs | 15 +++++++++++++++ netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_attendance_group/LqAttendanceGroupEntity.cs | 18 ++++++++++++++++++ netcore/src/Modularity/Extend/NCC.Extend/LqAttendanceSettingService.cs | 16 ++++++++++++++-- netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ netcore/src/Modularity/WorkFlow/NCC.WorkFlow/WorkFlowForm/LeaveApplyService.cs | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 绿纤uni-app/pagesA/components/leave-apply-scene.vue | 58 ++++++++++++++++++++++++++++++++++++++++++++++------------ 绿纤uni-app/service/quota-summary.js | 11 +++++++++-- 绿纤uni-app/unpackage/dist/dev/mp-weixin/common/vendor.js | 26 ++++++++++++++++++-------- 绿纤uni-app/unpackage/dist/dev/mp-weixin/pagesA/components/leave-apply-scene.js | 58 ++++++++++++++++++++++++++++++++++++++++++++-------------- 项目文档相关/sql/2026-3-25/考勤相关表全量重建.sql | 3 +++ 32 files changed, 2167 insertions(+), 346 deletions(-) create mode 100644 .claude/agents/backend-developer.md create mode 100644 .claude/agents/frontend-developer.md create mode 100644 .claude/agents/orchestrator.md create mode 100644 .claude/agents/test-engineer.md create mode 100644 .claude/agents/verifier.md create mode 100644 .claude/commands/api-interface-testing.md create mode 100644 .claude/commands/api-xml-comments.md create mode 100644 .claude/commands/deprecated-tables.md create mode 100644 .claude/commands/mcp-mysql.md create mode 100644 .claude/commands/remember.md create mode 100644 .claude/commands/ui-ux.md create mode 100644 .claude/settings.json create mode 100644 .cursor/skills/sqlsugar-type-conversion-debug/SKILL.md create mode 100644 .cursor/skills/workflow-form-development/SKILL.md create mode 100644 CLAUDE.md diff --git a/.claude/agents/backend-developer.md b/.claude/agents/backend-developer.md new file mode 100644 index 0000000..f205031 --- /dev/null +++ b/.claude/agents/backend-developer.md @@ -0,0 +1,85 @@ +--- +name: backend-developer +description: C# 后端 API 开发专家(SqlSugar 技术栈)。Use proactively. Always use for API endpoints, database operations, business logic, server-side implementation. Always use for 添加接口、实现 API、新增接口、查询接口、修改接口、接口报错、写测试接口、数据库、Service、Entity、DTO. Triggered by backend/server/C#/SqlSugar/ASP.NET. +--- + +你是一名资深 C# 后端开发工程师,专注于使用 SqlSugar 进行高效、可维护的 API 开发。必须遵守本项目规则与用户协作规则中与后端相关的全部约定。 + +## 核心原则 + +- 以"能直接上线"为目标 +- 不做无必要的架构设计 +- 优先补业务逻辑,而不是重构结构 +- 保持与现有项目风格一致 +- **最小化修改**:只动必要的地方,先通读上下游逻辑再改 + +## 适用场景 + +- 创建 / 修改 API 接口(CRUD、统计、业务接口) +- 使用 SqlSugar 进行数据库读写、事务处理 +- 编写清晰可维护的业务逻辑 +- 参数校验、异常处理、返回统一结果 +- 权限、身份校验(如 JWT) + +## 明确不负责 + +- 前端 UI 或交互逻辑 +- 编写或运行测试代码(由 test-engineer 负责) +- 验证功能是否满足需求(由 verifier 负责) +- 重构无关代码或升级架构 + +## 技术栈约束 + +- ASP.NET Core Web API +- SqlSugar(优先使用 SqlSugarScope / ISqlSugarClient) +- 依赖注入、JWT +- 日志:Serilog,遵循项目现有方式 +- **架构**:`Entitys → Interfaces → Services`;**不需要在 NCC.API 创建 Controller**,Extend 里的 Service 可直接使用 + +## 项目强制约束 + +### ID 与枚举 + +- **ID 生成**:一律使用 `YitIdHelper.NextId().ToString()`,禁止 `Guid.NewGuid().ToString()` +- **枚举**:状态、类型等固定值必须用 enum 定义,禁止魔法数字;枚举成员需加 XML 注释 + +### 数据访问与 SQL + +- **分页**:所有列表接口必须支持分页,避免全表扫描 +- **SQL 安全**:使用 `WhereIF` 等条件构造,避免拼接 SQL +- **查询优化**:避免 N+1,优先 JOIN + +### 统计与列表一致性 + +- 统计接口与列表接口必须使用**相同的过滤条件、时间范围、权限控制** +- DTO 字段名称、大小写必须**完全一致** + +### 人员与门店数据 + +- 人员信息优先使用 `BASE_USER`,禁止使用已弃用的 `lq_ryzl` +- 门店归属从 `lq_md_target` 按月份维度读取,禁止使用 `lq_mdxx` 的历史归属字段 + +### API 与接口 + +- **GET 传参**:使用 **data 字段传参**,不使用 params +- **接口注释**:所有 API 方法必须按项目标准写 XML 注释(summary + remarks + param + returns + response code) +- **异常与返回**:统一异常处理,返回友好错误信息 + +## 交付物要求 + +1. 接口方法代码(含路由与 XML 注释) +2. 相关业务逻辑(在现有 Service 或约定位置) +3. 必要的 Entity / DTO 定义 +4. 关键 SqlSugar 查询示例 +5. 简要说明接口用途和调用方式 + +## 交接前必须 + +- **必须执行 build**:`dotnet build`,确保编译通过、无错误后才可交接给 test-engineer + +## 严格禁止 + +- 使用 Guid 或其它方式生成 ID +- 统计与列表使用不一致的过滤条件或 DTO 命名 +- 未验证的统计 SQL 直接提交 +- 自动拆分多层架构、为"看起来专业"而复杂化代码 diff --git a/.claude/agents/frontend-developer.md b/.claude/agents/frontend-developer.md new file mode 100644 index 0000000..82a716e --- /dev/null +++ b/.claude/agents/frontend-developer.md @@ -0,0 +1,59 @@ +--- +name: frontend-developer +description: 前端 UI 开发专家(Vue 2.6 + Element UI)。Use proactively and always use for user interfaces, components, pages, client-side interactions. Always use when user requests 添加页面、实现组件、新增页面、修改页面、弹窗、表单、表格 or mentions UI/frontend/Vue/Element/页面/组件. +--- + +你是前端开发专家,专注用户界面。必须遵守项目规则中的前端规范。 + +## 核心原则 + +- 与现有项目风格一致 +- 最小化修改,只动必要处 +- 弹窗、二级页面、复杂表单 → 单独 Vue 文件,禁止在主页面 template 里写 + +## 适用场景 + +- 页面、组件、表单、交互 +- 调用现有 API(Axios) +- 路由、Vuex 状态 + +## 不负责 + +- 后端 API、数据库 +- 接口测试(由 test-engineer 负责) + +## 技术栈 + +- Vue 2.6 + Element UI +- SCSS (scoped)、Axios、Vuex、Webpack +- Node.js 必须使用 16.20.2 + +## 项目强制约束 + +### 组件与文件 + +- 文件命名:kebab-case(如 user-dialog.vue) +- 表格:统一 NCC-table +- 表单:Element UI,标签右对齐 +- 弹窗 / 二级页面 / 复杂表单必须单独创建 Vue 文件或封装成组件 + +### UI 规范 + +- 卡片:高度 100px,内边距 12px,圆角 12px +- 操作按钮左对齐,统计卡片内容垂直居中 +- 列表需有图标,不同颜色区分类型(颜色不能太多) +- 空值显示"无",列表不换行 + +### 色彩 + +- 主色 `#409EFF`,辅助色 `#67C23A` / `#F56C6C` / `#909399` + +### API 调用 + +- GET 请求用 `data` 传参,不用 `params` + +## 交付物 + +1. Vue 组件代码 +2. API 调用与数据绑定 +3. 简要使用说明 diff --git a/.claude/agents/orchestrator.md b/.claude/agents/orchestrator.md new file mode 100644 index 0000000..04b68d3 --- /dev/null +++ b/.claude/agents/orchestrator.md @@ -0,0 +1,45 @@ +--- +name: orchestrator +description: 任务分析与规划专家。分析任务复杂度并自动委派给对应子代理。Use proactively for task analysis, requirement breakdown, planning. Always use when user describes complex, multi-step, or ambiguous tasks. +--- + +你是一个任务协调者,负责分析用户任务并自动委派给应使用的子代理。 + +## 工作流程 + +1. **分析任务**:判断任务类型(L1/L2/L3)和涉及角色 +2. **自动委派**:对 L2/L3 任务,使用 Agent 工具启动对应子代理,在 prompt 中传入清晰任务描述与必要上下文(子代理无法访问历史对话) +3. **可并行时**:单次发出多个 Agent 调用,子代理并行执行 +4. **显式调用**:用户也可用自然语言显式调用子代理 + +## 任务分级与委派 + +| 级别 | 类型 | 委派方式 | +|------|------|----------| +| L1 | 解释 / 评估 / 判断 / 总结 | 直接回答,不委派 | +| L2 | 仅后端 API | Agent 工具 → `backend-developer` | +| L2 | 仅前端 UI | Agent 工具 → `frontend-developer` | +| L3 | 后端 + 测试 | `backend-developer`(build 通过)后 `test-engineer` | +| L3 | 全栈 / 可并行 | 单次多个 Agent 调用并行执行 | +| 验证 | 验证已有代码 | `verifier`(仅开发测试完成后) | + +## Agent 委派 prompt 要点 + +子代理在全新上下文中启动,需在 prompt 中提供: +- 清晰任务描述 +- 关键业务上下文(项目路径、相关文件、约束条件) +- 交付要求 + +## 强制委派 + +**不得自行实现**以下任务,必须委派: +- 实现接口 / API → `backend-developer` +- 实现页面 / 组件 → `frontend-developer` +- 执行接口测试 → `test-engineer` + +职责:分析、委派、汇总;**不直接写业务代码或执行测试**。 + +## 禁止 + +- 不为简单任务委派多个子代理 +- 不在开发阶段委派 verifier diff --git a/.claude/agents/test-engineer.md b/.claude/agents/test-engineer.md new file mode 100644 index 0000000..499a657 --- /dev/null +++ b/.claude/agents/test-engineer.md @@ -0,0 +1,76 @@ +--- +name: test-engineer +description: 测试专家。Use proactively and always use for tests, verification, code quality, API testing after feature implementation. Always use when implementation is complete, user requests 测试、验证接口、接口测试、跑测试 or mentions testing/verification/curl. +--- + +你是测试自动化专家,确保代码质量。 + +## 适用场景 + +- 为新功能编写测试 +- 运行现有测试套件 +- 修复失败的测试 +- 验证代码覆盖率 + +## 接口测试流程(必须遵守) + +做 **API/接口验证**(含新接口、改接口、提交前验收)时,必须按以下流程执行: + +### 1. 获取 Token + +```bash +curl -X POST "http://localhost:2015/api/oauth/Login" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "account=admin&password=e10adc3949ba59abbe56e057f20f883e" +``` + +返回的 `data.token` 已包含 `"Bearer "` 前缀,后续接口请求直接使用。 + +### 2. 调用目标接口 + +GET(使用 data 传参,项目规范): +```bash +curl -X GET "http://localhost:2015/api/xxx/YourAction?key=value" \ + -H "Authorization: " +``` + +POST(JSON body): +```bash +curl -X POST "http://localhost:2015/api/xxx/YourAction" \ + -H "Authorization: " \ + -H "Content-Type: application/json" \ + -d '{"key":"value"}' +``` + +### 3. 验证清单 + +- [ ] **功能**:用真实/合理数据调用,返回符合接口约定 +- [ ] **正确性**:关键字段类型、取值、分页与业务逻辑一致 +- [ ] **边界**:空列表、无数据、参数缺省等处理正确 +- [ ] **异常**:非法参数、未登录等返回合理错误码与提示 +- [ ] **性能**:响应时间可接受,无超时或明显卡顿 + +## 数据库验证(必须) + +执行**新增/编辑/删除/状态变更**操作后,**必须查库验证**数据是否真实落库: +- 通过 API 查询对应数据,或使用 MCP MySQL 执行 SELECT 核对 +- 验证要点:记录数、关键业务字段(ID、名称、金额、状态)是否正确 +- 禁止只根据接口返回值判断成功 + +## 测试范围 + +- 仅测试接口(API)和后端逻辑 +- 不进行 UI/前端测试 + +## 测试发现问题时 + +- 编译错误 / 接口返回错误 / 后端逻辑问题 → 将问题重新提交给 `backend-developer` +- 提供清晰的问题描述、复现步骤、错误信息 +- 不自行修改业务代码 + +## 交付物 + +1. 测试代码 +2. 测试运行结果(通过/失败) +3. 覆盖率报告 +4. 失败时:问题转交记录及对应 agent 的修复建议 diff --git a/.claude/agents/verifier.md b/.claude/agents/verifier.md new file mode 100644 index 0000000..538106e --- /dev/null +++ b/.claude/agents/verifier.md @@ -0,0 +1,36 @@ +--- +name: verifier +description: 最终验证者。Use only after all development and testing are complete. Validates completed work independently. Do NOT delegate during development. 仅在交付前、所有开发测试完成后使用。 +--- + +你是最终验证专家,在开发完成后进行独立确认。 + +## 何时调用 + +- 所有开发工作声称已完成 +- 测试已通过 +- 需要最终确认 +- 准备交付前的检查 + +## 不要在以下情况调用 + +- 开发阶段 +- 编写代码时 +- 运行单个测试时 + +## 验证清单 + +1. 功能完整性检查 +2. 端到端流程测试 +3. 错误处理验证 +4. 代码质量检查 +5. 安全性审查 + +## 报告格式 + +- 已验证通过的内容 +- 发现的问题 +- 需要注意的风险 +- 建议改进项 + +保持独立和怀疑态度。 diff --git a/.claude/commands/api-interface-testing.md b/.claude/commands/api-interface-testing.md new file mode 100644 index 0000000..6e42c6d --- /dev/null +++ b/.claude/commands/api-interface-testing.md @@ -0,0 +1,52 @@ +# 接口测试 + +按项目规范执行接口测试。在新增或修改后端 API、需要验证接口行为或用户提及接口测试时使用。 + +## 测试流程 + +### Step 1:获取 Token + +- 地址:`POST /api/oauth/Login` +- Content-Type:`application/x-www-form-urlencoded` +- 参数:`account=admin`,`password=e10adc3949ba59abbe56e057f20f883e` +- Base URL:本地一般为 `http://localhost:2015`,以实际运行环境为准 + +```bash +curl -X POST "http://localhost:2015/api/oauth/Login" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "account=admin&password=e10adc3949ba59abbe56e057f20f883e" +``` + +**返回说明**:`data.token` 已包含 `"Bearer "` 前缀,后续请求**直接使用**:`Authorization: {data.token}`(无需再拼 Bearer)。 + +### Step 2:调用目标接口 + +**GET(项目规范:GET 使用 data 传参,不用 params):** + +```bash +curl -X GET "http://localhost:2015/api/xxx/YourAction?key=value" \ + -H "Authorization: " +``` + +**POST(JSON body):** + +```bash +curl -X POST "http://localhost:2015/api/xxx/YourAction" \ + -H "Authorization: " \ + -H "Content-Type: application/json" \ + -d '{"key":"value"}' +``` + +### Step 3:验证清单 + +- [ ] **功能**:用真实/合理数据调用,返回符合接口约定 +- [ ] **正确性**:关键字段类型、取值、分页与业务逻辑一致 +- [ ] **边界**:空列表、无数据、参数缺省等处理正确 +- [ ] **异常**:非法参数、未登录等返回合理错误码与提示 +- [ ] **性能**:响应时间可接受,无超时或明显卡顿 + +只有测试通过后再提交相关代码。 + +## 工具 + +可使用 curl、Postman、Swagger 等;给出示例时优先提供 **curl**,便于在终端直接执行。 diff --git a/.claude/commands/api-xml-comments.md b/.claude/commands/api-xml-comments.md new file mode 100644 index 0000000..7388856 --- /dev/null +++ b/.claude/commands/api-xml-comments.md @@ -0,0 +1,41 @@ +# API 接口 XML 注释规范 + +在新增或修改后端 API、为接口方法编写或补全 XML 注释时使用。 + +## 标准格式 + +所有 API 接口方法必须按以下格式编写 XML 注释: + +```csharp +/// +/// 接口功能描述(简洁明了的一句话) +/// +/// +/// 详细功能说明和使用场景 +/// +/// 示例请求: +/// ```json +/// { +/// "参数名": "参数值", +/// "参数名2": "参数值2" +/// } +/// ``` +/// +/// 参数说明: +/// - 参数名: 参数描述 +/// - 参数名2: 参数描述 +/// +/// 参数描述 +/// 返回值描述 +/// 成功响应描述 +/// 错误响应描述 +/// 服务器错误描述 +``` + +## 注释要求 + +- ``:一句话概括功能,简洁明了 +- ``:详细说明、示例请求(JSON)、参数说明列表 +- 示例请求使用 JSON 格式,参数说明用列表 +- 必须包含所有可能返回的 HTTP 状态码(200/400/500 等)的 `` 说明 +- 复杂接口必须提供完整请求示例 diff --git a/.claude/commands/deprecated-tables.md b/.claude/commands/deprecated-tables.md new file mode 100644 index 0000000..adcfcc9 --- /dev/null +++ b/.claude/commands/deprecated-tables.md @@ -0,0 +1,27 @@ +# 已弃用表与替代方案 + +在涉及人员、门店归属、业绩关联等逻辑时使用,避免误用历史表或字段。 + +## 何时使用 + +- 开发或修改与**人员信息**相关的逻辑时 +- 开发或修改与**门店归属**(事业部/经营部/科技部/旗舰店等)相关的逻辑时 +- 涉及**业绩与人员关联**、按门店/月份统计归属时 +- 排查数据来源或历史表结构时 + +--- + +## lq_ryzl(人员资料表)已弃用 + +- **替代**:人员信息统一使用系统用户表 **`BASE_USER`** 管理 +- **使用**:所有人员相关业务使用 `BASE_USER` 及其扩展字段(`F_MDID`、`F_ZW`、`F_GWFL`、`F_GW` 等) +- **关联**:人员与业绩的关联通过 `BASE_USER.F_REALNAME` 与 `lq_yjmxb.jks` 等进行 + +--- + +## lq_mdxx_mdgs / lq_mdxx 归属字段已弃用 + +- **替代**:门店归属一律从 **`lq_md_target`** 按**月份维度**管理 +- **使用**:通过 `F_StoreId + F_Month` 获取对应月份的事业部/经营部/科技部/旗舰店等归属信息 +- **禁止**:不再从 `lq_mdxx` 读取归属;以下字段视为历史字段,**禁止作为业务统计或归属判断依据**: + - `lq_mdxx`:`syb`、`jyb`、`kjb`、`dxmb`、`gsqssj`、`gszzsj`、`status` diff --git a/.claude/commands/mcp-mysql.md b/.claude/commands/mcp-mysql.md new file mode 100644 index 0000000..4c7b57a --- /dev/null +++ b/.claude/commands/mcp-mysql.md @@ -0,0 +1,71 @@ +# MCP MySQL 与 SQL 验证 + +在使用 MCP 查库、写统计 SQL 或提交含 SQL 的代码时使用。用户直接询问业务数据时自动触发查库。 + +## 何时必须使用 + +### 1. 接口测试场景(新增 / 编辑 / 删除 / 状态变更) + +接口执行完成后,**必须使用 MCP 查询数据库**验证数据是否真实新增/修改/删除: +- 禁止只根据接口返回值判断成功 +- 禁止假设数据库已发生变化 + +### 2. 统计 / 报表 / 看板 / 聚合接口 + +编写统计 SQL 后,**必须通过 MCP 执行**,用真实数据验证结果合理性: +- 禁止"只写 SQL,不执行" +- 禁止凭经验推断结果 + +### 3. 用户直接询问业务数据(自动触发) + +包含以下特征时,**必须自动查库**: +- 包含:多少 / 数量 / 金额 / 总数 / 合计 +- 包含明确时间范围:年、月、日 +- 涉及业务实体:会员 / 订单 / 开单 / 门店 / 员工 / 消耗 + +--- + +## MCP MySQL 使用规范 + +### 允许的操作 + +- 只允许:`SELECT` +- 禁止:`INSERT / UPDATE / DELETE / TRUNCATE` + +### 表结构查询 + +```sql +SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT, EXTRA, COLUMN_COMMENT +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_SCHEMA = 'lqerp_dev' AND TABLE_NAME = '<表名>'; +``` + +注意:查询表结构时**不要加 ORDER BY**,每次查询只针对一个表。 + +### 连接配置 + +- 配置文件:`.cursor/mcp.json`(Cursor)/ `.claude/settings.json`(Claude Code) +- 服务名:`my-sql-db` +- 数据库:`lqerp_dev` +- 包:`@davewind/mysql-mcp-server` +- 执行方式:调用 MCP 的 `query` 工具,参数 `sql`(SELECT 语句,一次一条) + +### 连通性验证 SQL + +```sql +SELECT COUNT(*) AS table_count +FROM information_schema.tables +WHERE table_schema = 'lqerp_dev'; +``` + +--- + +## SQL 验证清单(统计类提交前必须) + +- [ ] SQL 语法正确,能执行通过 +- [ ] 涉及的表、字段存在且类型匹配 +- [ ] JOIN 关系正确 +- [ ] 统计逻辑与需求一致 +- [ ] 用实际数据跑一遍,结果合理 + +只有验证通过的 SQL 才能提交到代码中。 diff --git a/.claude/commands/remember.md b/.claude/commands/remember.md new file mode 100644 index 0000000..363dc99 --- /dev/null +++ b/.claude/commands/remember.md @@ -0,0 +1,86 @@ +# 持久化规则或 Skill + +当用户要求「记住」某事时,根据内容类型自动添加为项目规则或 Skill。 +触发词:记住、记一下、以后要、保存这个规则、加到规范里、写进 skill、记录下来、按这个来。 + +## 判断标准:Rule 还是 Skill? + +| 类型 | 适合内容 | 存放位置 | +|------|----------|----------| +| **Rule** | 简短约束、禁止项、风格约定、回复格式等「每次都要遵守」的规范 | `.cursor/rules/*.mdc` | +| **Skill** | 有步骤的流程、按场景触发的知识、需要 description 匹配的专项能力 | `.cursor/skills//SKILL.md` | + +### 选择 Rule 的情况 + +- 禁止或必须做的**一句话/短条款**(如:禁止用 Guid、GET 用 data 传参) +- **编码/格式约定**(缩进、命名、注释要求) +- **回复或交互约定**(如:回复前缀"大哥") +- **仅在某类文件生效**的规范 → 用 `globs`,`alwaysApply: false` + +### 选择 Skill 的情况 + +- **多步骤流程**(如:接口测试流程、查库验证流程) +- **按场景触发**的专项知识(如:弃用表、API 注释格式、MCP 查库) +- 需要**示例、模板、清单**的说明 +- 内容较长或需要**分节、可检索**的文档 + +### 与现有内容的关系 + +- 与**现有 rule/skill 主题一致** → **优先更新已有文件**,避免碎片化 +- 全新主题 → 新建 rule 或 skill + +--- + +## 执行步骤 + +### Step 1:确认要记的内容 + +从对话中提炼出用户要持久化的**具体条文或流程**。 + +### Step 2:决定类型与目标文件 + +- Rule:`.cursor/rules/` 下新建或追加到 `project_rules.mdc` +- Skill:`.cursor/skills//SKILL.md` 下新建或更新现有 skill + +**同步到 Claude Code**: +- 如果写的是 Rule,同时在 `CLAUDE.md` 对应章节补充 +- 如果写的是 Skill,同时在 `.claude/commands/.md` 创建或更新对应 slash command + +### Step 3:格式规范 + +**Rule(.cursor/rules/xxx.mdc)** + +```markdown +--- +description: 简短说明这条规则做什么 +alwaysApply: true +--- +# 规则标题 +内容... +``` + +**Skill(.cursor/skills//SKILL.md)** + +```markdown +--- +name: skill-name +description: 做什么;在什么场景下使用(含触发词) +--- +# 标题 +## 何时使用 +... +## 步骤/规范 +... +``` + +### Step 4:确认 + +写完后简短说明:写到了哪(规则还是 skill、文件名),以及以后如何生效。 + +--- + +## 本项目约定 + +- 用户**明确要求记住/保存规则或写进 skill** 时,可以且应当新增或修改 `.cursor/rules/`、`.cursor/skills/` 下的文件 +- 风格:与现有 `project_rules.mdc`、`orchestrator-first.mdc` 以及各 skill 的写法保持一致 +- Claude Code 侧同步:`.claude/commands/` 对应 skill,`CLAUDE.md` 对应全局规则 diff --git a/.claude/commands/ui-ux.md b/.claude/commands/ui-ux.md new file mode 100644 index 0000000..1cce6d9 --- /dev/null +++ b/.claude/commands/ui-ux.md @@ -0,0 +1,75 @@ +# UI/UX 设计系统生成 + +面向 Vue 2.6 + Element UI 技术栈的 UI/UX 设计指南。包含样式、色彩、字体、UX 规范与图表类型推荐。 + +## 项目 UI 规范(必须遵守) + +本项目的 UI 规范已在 `PROJECT_RULES.md` 中定义,开发时首先遵守以下约束: + +- 主色:`#409EFF`,辅助色:`#67C23A` / `#F56C6C` / `#909399` +- 卡片:高度 100px,内边距 12px,圆角 12px +- 操作按钮左对齐,统计卡片内容垂直居中 +- 列表需有图标,不同颜色区分类型(颜色不能太多) +- 空值显示"无",列表不换行 +- 表格统一使用 NCC-table + +--- + +## 如何使用 UI/UX Pro Max 工具 + +工具脚本位于:`.cursor/skills/ui-ux-pro-max/scripts/search.py` + +### Step 1:生成设计系统(推荐始终从这步开始) + +```bash +python3 .cursor/skills/ui-ux-pro-max/scripts/search.py " " --design-system [-p "Project Name"] +``` + +示例(适用于本项目的美业 ERP 风格): +```bash +python3 .cursor/skills/ui-ux-pro-max/scripts/search.py "beauty ERP dashboard professional" --design-system -p "绿纤美业ERP" +``` + +### Step 2(可选):按领域补充搜索 + +```bash +python3 .cursor/skills/ui-ux-pro-max/scripts/search.py "" --domain +``` + +| 需求 | Domain | 示例 | +|------|--------|------| +| 更多样式选项 | `style` | `--domain style "dashboard professional"` | +| 图表推荐 | `chart` | `--domain chart "trend comparison"` | +| UX 最佳实践 | `ux` | `--domain ux "table list form"` | +| 字体搭配 | `typography` | `--domain typography "professional clean"` | + +### Step 3:Vue 技术栈指南 + +```bash +python3 .cursor/skills/ui-ux-pro-max/scripts/search.py "" --stack vue +``` + +--- + +## 持久化设计系统 + +```bash +python3 .cursor/skills/ui-ux-pro-max/scripts/search.py "" --design-system --persist -p "绿纤美业ERP" +``` + +会生成: +- `design-system/MASTER.md` — 全局设计规则 +- `design-system/pages/` — 页面级覆盖 + +--- + +## 交付前 UI 检查清单 + +- [ ] 操作按钮左对齐 +- [ ] 统计卡片内容垂直居中 +- [ ] 所有列表数据有图标,颜色区分类型 +- [ ] 空值显示"无",列表不换行 +- [ ] 卡片高度 100px,内边距 12px,圆角 12px +- [ ] 色彩使用项目主色方案 +- [ ] 弹窗/二级页面/复杂表单已拆为独立 Vue 文件 +- [ ] 文件命名 kebab-case diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..8677d80 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,37 @@ +{ + "mcpServers": { + "my-sql-db": { + "command": "npx", + "args": [ + "--yes", + "@davewind/mysql-mcp-server", + "mysql://nettest:nettest@rm-2vccze142rc9a8f58bo.mysql.cn-chengdu.rds.aliyuncs.com:3306/lqerp_dev" + ] + }, + "my-api-spec": { + "command": "npx", + "args": [ + "--yes", + "@ivotoby/openapi-mcp-server", + "--openapi-spec", + "http://localhost:2015/swagger/Default/swagger.json", + "--api-base-url", + "http://localhost:2015" + ] + }, + "filesystem": { + "command": "npx", + "args": [ + "@modelcontextprotocol/server-filesystem", + "." + ] + }, + "excel-reader": { + "command": "npx", + "args": [ + "--yes", + "@negokaz/excel-mcp-server" + ] + } + } +} diff --git a/.cursor/skills/sqlsugar-type-conversion-debug/SKILL.md b/.cursor/skills/sqlsugar-type-conversion-debug/SKILL.md new file mode 100644 index 0000000..842adb8 --- /dev/null +++ b/.cursor/skills/sqlsugar-type-conversion-debug/SKILL.md @@ -0,0 +1,131 @@ +--- +name: sqlsugar-type-conversion-debug +description: SqlSugar 字段类型转换报错(如 "can't convert string to datetime")的排查与修复流程。在遇到 SqlSugar 查询返回类型转换异常、接口 500 报 convert 错误、DateTime/int/decimal 字段映射失败时使用。 +--- + +# SqlSugar 字段类型转换报错排查规范 + +## 何时使用 + +- 接口报 `500: xxx can't convert string to datetime`(或其他类型转换错误) +- SqlSugar 查询结果映射到 DTO 时抛出类型异常 +- 修改了 Select / Subqueryable / MergeTable 后出现新的转换报错 + +--- + +## 核心教训(来自真实案例) + +**错误做法**:看到报错就直接猜测并大范围修改 `SqlFunc.ToDate`、Subqueryable 等写法,反复改动导致问题更复杂,原本可用的代码被破坏。 + +**正确做法**:**先用 MCP 查库确认数据异常,再决定是否改代码**。 + +--- + +## 排查步骤 + +### Step 1:先查数据,不动代码 + +用 MCP MySQL 工具查该字段是否存在异常数据: + +```sql +-- 1. 确认字段实际类型 +SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = '表名' + AND COLUMN_NAME = '字段名'; + +-- 2. 检查是否有无法转换的异常值(针对 varchar 存日期的情况) +SELECT id, 字段名 FROM 表名 +WHERE 字段名 IS NOT NULL + AND TRIM(字段名) != '' + AND STR_TO_DATE(字段名, '%Y-%m-%d %H:%i:%s') IS NULL + AND STR_TO_DATE(字段名, '%Y-%m-%d') IS NULL +LIMIT 20; +``` + +- 若字段类型已是 `datetime`,`SqlFunc.ToDate(x.Yysj)` 在 Subqueryable 里**是可以正常工作的**,不要随意删除。 +- 若发现真有脏数据(空字符串、格式错误),先修数据,再看接口是否恢复正常。 + +### Step 2:确认 Entity 声明与 DB 类型一致 + +```csharp +// Entity 声明 DateTime? 对应 DB datetime 列 ✅ +[SugarColumn(ColumnName = "yysj")] +public DateTime? Yysj { get; set; } + +// Entity 声明 string 对应 DB datetime 列 ❌ 会触发转换错误 +public string Yysj { get; set; } +``` + +如果 Entity 类型声明与 DB 实际类型不一致,修改 Entity 类型即可,**不要改查询逻辑**。 + +### Step 3:若确认是 MergeTable 导致的类型丢失 + +`.MergeTable()` 会把查询包成中间子查询,某些版本的 SqlSugar 在此过程中会将 `DateTime` 类型推导为 `varchar`。此时才需要修改查询逻辑,正确做法是**分页后批量回填**: + +```csharp +// ❌ 错误:MergeTable 后 Subqueryable 返回 DateTime,中间表映射为 string +.Select(it => new OutputDto { + appointmentTime = SqlFunc.Subqueryable() + .Where(x => x.Id == it.AppointmentId) + .Select(x => SqlFunc.ToDate(x.Yysj)), +}) +.MergeTable() +.ToPagedListAsync(...); + +// ✅ 正确:Select 里先置 null,分页后批量回填 +.Select(it => new OutputDto { + appointmentId = it.AppointmentId, + appointmentTime = (DateTime?)null, // 先置 null +}) +.MergeTable() +.ToPagedListAsync(...); + +// 分页后批量查询回填 +var apptIds = data.list + .Where(x => !string.IsNullOrEmpty(x.appointmentId)) + .Select(x => x.appointmentId).Distinct().ToList(); +if (apptIds.Any()) +{ + var apptMap = await _db.Queryable() + .Where(x => apptIds.Contains(x.Id)) + .Select(x => new { x.Id, x.Yysj }) + .ToListAsync(); + var apptDict = apptMap.ToDictionary(x => x.Id); + foreach (var item in data.list) + { + if (!string.IsNullOrEmpty(item.appointmentId) + && apptDict.TryGetValue(item.appointmentId, out var appt)) + item.appointmentTime = appt.Yysj; + } +} +``` + +### Step 4:确认修改编译通过后再重启 + +```bash +cd netcore/src/Application/NCC.API && dotnet build --no-restore 2>&1 | tail -5 +``` + +必须 **0 Error** 后才重启 API,再测试接口。 + +--- + +## 优先级原则 + +| 顺序 | 操作 | 目的 | +|------|------|------| +| 1 | 用 MCP 查库确认数据 | 排除脏数据,80% 的情况到这里就解决了 | +| 2 | 检查 Entity 类型声明 | 确认 C# 类型与 DB 类型一致 | +| 3 | 检查是否有 MergeTable + Subqueryable DateTime | 确认是框架行为还是数据问题 | +| 4 | 改代码(改查询逻辑或 Entity) | 最后手段,改前先理解原代码为什么大多数情况能用 | + +--- + +## 禁止事项 + +- ❌ **不要看到类型转换报错就盲目删除 `SqlFunc.ToDate`**——它在大多数场景是正确的 +- ❌ **不要在没有查清原因前大范围修改 Select / Subqueryable**——会破坏原本正常的逻辑 +- ❌ **不要反复重启 API 来"试"是否生效**——每次改动前先确认 `dotnet build` 0 Error +- ❌ **原代码如果在 HEAD 中长期工作,优先怀疑是数据问题,而不是代码问题** diff --git a/.cursor/skills/workflow-form-development/SKILL.md b/.cursor/skills/workflow-form-development/SKILL.md new file mode 100644 index 0000000..a47d765 --- /dev/null +++ b/.cursor/skills/workflow-form-development/SKILL.md @@ -0,0 +1,239 @@ +--- +name: workflow-form-development +description: 工作流审批表单开发与流程配置规范。在开发新的审批表单页面、把表单配置到流程引擎、修改流程表单字段映射时使用。触发词:审批表单、流程表单、配置到流程、表单字段映射、FlowBox、formOperates。 +--- + +# 工作流审批表单开发与流程配置 + +## 一、何时使用 + +- 新增或修改审批申请表单页面(如请假、报销等) +- 用户要求"把表单配置到流程上" +- 表单在 FlowBox 中渲染报错(如 `init is not a function`、404 等) +- 配置流程设计器中的表单字段映射 + +--- + +## 二、开发审批表单页面 + +### 2.1 FlowBox 兼容要求(必须) + +框架组件 `FlowBox.vue` 通过 `ref="form"` 引用表单页面,并在生命周期中调用以下方法: + +| 方法 | 调用时机 | 说明 | +|------|----------|------| +| `init(data)` | 页面加载后 | 初始化表单,`data` 包含 `{id, flowId, enCode, readonly, formOperates, opType}` | +| `dataFormSubmit(eventType)` | 用户点击审批/驳回/提交等按钮 | 校验表单并 emit 数据 | + +FlowBox 监听的事件: + +| 事件 | 说明 | +|------|------| +| `eventReciver(formData, eventType)` | 提交表单数据,两个参数 | +| `setPageLoad` | 通知加载完成 | +| `setLoad` | 控制 loading 状态 | +| `close` | 关闭页面 | + +### 2.2 已有 mixin 方案 vs 自定义方案 + +**方案 A:使用框架 mixin(简单表单推荐)** + +```js +import comMixin from '../mixin' +export default { + mixins: [comMixin], + // mixin 自动提供 init、dataFormSubmit、judgeShow、judgeWrite +} +``` + +**方案 B:自定义实现(复杂表单,如请假申请)** + +当表单有自己的独立逻辑(额度查询、业务校验等),不能直接用 mixin 时: + +1. 在表单组件中自行实现 `init(data)` 和 `dataFormSubmit(eventType)` +2. `init` 中需完成:存 setting → 重置表单 → 加载数据/生成单据号 → emit `setPageLoad` +3. `dataFormSubmit` 中需完成:校验表单 → 校验业务规则 → emit `eventReciver(payload, eventType)` + +### 2.3 Wrapper 页面代理模式 + +如果使用「公共组件 + 场景 wrapper」的架构(如 `leave-apply-page.vue` + `rest-leave-apply/index.vue`),wrapper 必须代理方法和事件: + +```vue + + + +``` + +关键点: +- 用 `v-on="$listeners"` 自动转发所有事件给 FlowBox(`eventReciver` 有两个参数,手动转发会丢参数) +- 必须代理 `init` 和 `dataFormSubmit`(FlowBox 通过 `$refs.form` 直接调用) + +### 2.4 API Key 不等于流程 enCode(重要陷阱) + +前端 `Info(key, id)` 函数会把 key 首字母大写后拼 URL:`/api/workflow/Form/${Key}/${id}` + +**这里的 key 是后端控制器名,不是流程的 enCode!** + +| 后端控制器 | 路由 | 正确的 key | +|-----------|------|-----------| +| `LeaveApplyService` | `/api/workflow/Form/LeaveApply/` | `'leaveApply'` | + +三种请假流程(应休 `xjsq`、事假 `qjsq`、带薪 `ces`)都共用 `LeaveApplyService`,所以调用 `Info`、`Create`、`Update` 时必须固定传 `'leaveApply'`,而不是 `this.setting.enCode`。 + +```js +// ✅ 正确 +Info('leaveApply', data.id) + +// ❌ 错误 - enCode 是 xjsq,拼出 /api/workflow/Form/Xjsq/xxx → 404 +Info(this.setting.enCode, data.id) +``` + +### 2.5 FlowBox 模式下的 UI 适配 + +- 在 FlowBox 中渲染时,应隐藏页面自带的标题栏和按钮(FlowBox 有自己的操作按钮) +- 表单需支持 `setting.readonly` 只读模式(审批查看时) +- 可用 `flowBoxMode` 标记区分独立页面和 FlowBox 内嵌模式 + +### 2.6 前端语法限制 + +项目 Babel/webpack 配置不支持 ES2020+ 语法: +- ❌ `??`(空值合并) → 用 `a != null ? a : b` +- ❌ `?.`(可选链) → 用 `a && a.b` +- ✅ 箭头函数、展开运算符、模板字符串等 ES6 语法正常支持 + +--- + +## 三、把表单配置到流程上 + +当用户说"把表单配置到流程上"时,需要做以下 4 件事: + +### 3.1 配置 PC/App 页面路径 + +更新 `flow_engine` 表的 `F_FormUrl` 和 `F_AppFormUrl` 字段: + +```sql +UPDATE flow_engine +SET F_FormUrl = 'workFlow/leave-apply-pages/rest-leave-apply' +WHERE F_Id = '<流程ID>'; +``` + +- `F_FormUrl`:PC 端页面路径(不带前缀 `/`,对应 `antis-ncc-admin/src/views/` 下的路径) +- `F_AppFormUrl`:App 端页面路径(带前缀 `/`,对应 uni-app 的页面路径) + +### 3.2 配置表单字段映射(formOperates) + +更新 `flow_engine.F_FlowTemplateJson` 中每个节点的 `properties.formOperates` 数组。 + +**字段格式:** + +```json +{ + "id": "flowTitle", + "name": "流程标题", + "required": false, + "read": true, + "write": true +} +``` + +| 属性 | 说明 | +|------|------| +| `id` | 字段标识,对应 dataForm 的属性名 | +| `name` | 在流程设计器中显示的名称 | +| `required` | 是否必填 | +| `read` | 是否可见 | +| `write` | 是否可编辑 | + +**节点权限区别:** + +| 节点 | read | write | 说明 | +|------|------|-------|------| +| 发起节点(start) | true | true | 发起人可编辑 | +| 审批节点(approver) | true | false | 审批人只读查看 | + +### 3.3 配置表单字段定义(F_FormTemplateJson) + +**这一步容易遗漏!** `flow_engine` 表有两个不同的 JSON 字段,必须都配置: + +| 字段 | 用途 | 缺失后果 | +|------|------|----------| +| `F_FlowTemplateJson` → `formOperates` | 每个节点对字段的 read/write 权限控制 | 审批节点无法控制字段可见/可编辑 | +| `F_FormTemplateJson` | 流程设计器"表单字段"下拉列表定义 | **设计器里看不到字段列表,无法在界面上配置字段权限** | + +`F_FormTemplateJson` 是一个 JSON 数组,格式如下: + +```json +[ + {"filedName": "流程标题", "filedId": "flowTitle", "required": false}, + {"filedName": "单据号", "filedId": "billNo", "required": false}, + {"filedName": "休假类别", "filedId": "leaveType", "required": false} +] +``` + +| 属性 | 说明 | +|------|------| +| `filedName` | 在流程设计器中显示的字段名称(注意:原始字段名就是 `filedName`,不是 `fieldName`,这是框架的拼写) | +| `filedId` | 字段标识,必须与 `formOperates` 中的 `id` 以及 dataForm 的属性名一致 | +| `required` | 是否必填 | + +**示例 SQL:** + +```sql +UPDATE flow_engine +SET F_FormTemplateJson = '[{"filedName":"流程标题","filedId":"flowTitle","required":false},{"filedName":"单据号","filedId":"billNo","required":false},{"filedName":"紧急程度","filedId":"flowUrgent","required":false},{"filedName":"申请人员","filedId":"applyUser","required":false},{"filedName":"申请日期","filedId":"applyDate","required":false},{"filedName":"申请部门","filedId":"applyDept","required":false},{"filedName":"申请职位","filedId":"applyPost","required":false},{"filedName":"休假类别","filedId":"leaveType","required":false},{"filedName":"休假原因","filedId":"leaveReason","required":false},{"filedName":"开始时间","filedId":"leaveStartTime","required":false},{"filedName":"结束时间","filedId":"leaveEndTime","required":false},{"filedName":"请假天数","filedId":"leaveDayCount","required":false},{"filedName":"请假小时","filedId":"leaveHour","required":false},{"filedName":"相关附件","filedId":"fileJson","required":false}]' +WHERE F_Id = '<流程ID>'; +``` + +### 3.5 查询方法 + +```sql +-- 查看某流程的完整配置(含两个 JSON 字段) +SELECT F_Id, F_FullName, F_EnCode, F_FormUrl, F_AppFormUrl, + F_FormTemplateJson, F_FlowTemplateJson +FROM flow_engine +WHERE F_Id = '<流程ID>'; + +-- 参考已有流程的字段配置(如事假病假申请) +SELECT F_FormTemplateJson, F_FlowTemplateJson FROM flow_engine WHERE F_EnCode = 'qjsq'; +``` + +### 3.6 注意事项 + +- MCP 数据库是只读的,UPDATE 语句需要提供给用户手动执行 +- 修改 `F_FlowTemplateJson` 时要保留原有节点结构(nodeId、prevId、审批人配置等),只替换 `formOperates` 部分 +- 字段 ID 必须与表单页面的 dataForm model 属性名完全一致 +- 新增流程后必须确保前端路由能匹配到对应的 Vue 页面组件 + +--- + +## 四、完整检查清单 + +开发或修改审批表单后,按此清单逐项确认: + +- [ ] 表单组件有 `init(data)` 方法 +- [ ] 表单组件有 `dataFormSubmit(eventType)` 方法 +- [ ] wrapper 页面通过 `$refs` 代理了上述两个方法 +- [ ] wrapper 页面用 `v-on="$listeners"` 转发事件 +- [ ] API 调用使用正确的控制器名(如 `'leaveApply'`),不是 enCode +- [ ] 表单支持 `setting.readonly` 只读模式 +- [ ] 无 `??` 或 `?.` 语法 +- [ ] `flow_engine.F_FormUrl` 已配置 PC 页面路径 +- [ ] `flow_engine.F_AppFormUrl` 已配置 App 页面路径 +- [ ] `F_FormTemplateJson` 已配置表单字段定义(设计器字段列表) +- [ ] `F_FlowTemplateJson` 中 formOperates 字段映射完整(节点权限) +- [ ] `F_FormTemplateJson` 的 `filedId` 与 `formOperates` 的 `id` 与 dataForm 属性名三者一致 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9373bbf --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,142 @@ +# 绿纤美业 ERP · Claude Code 工作指引 + +> 本文件供 Claude Code(CLI)自动读取。原始规则与技能仍保存在 `.cursor/` 目录下,不做任何改动。 +> Claude Code 专用的 agents 在 `.claude/agents/`,slash commands 在 `.claude/commands/`,MCP 配置在 `.claude/settings.json`。 + +--- + +## 强制约定 + +- **回复前缀**:每次回复必须以"大哥"开头。 +- 未被明确要求时,不要生成新的 Markdown 文档。 +- 单次改动最小化,先看上下游再改。 + +--- + +## 项目总览 + +| 端 | 目录 | 技术 | +|---|---|---| +| 后端 | `netcore/` | ASP.NET Core + SqlSugar + MySQL + JWT + Serilog | +| 管理后台 | `antis-ncc-admin/` | Vue 2.6 + Element UI + Vuex + Axios | +| 门店 PC | `store-pc/` | Vue 2.6 + Element UI + Axios | +| 移动端 | `绿纤uni-app/` | uni-app(微信小程序) | +| 文档/SQL/脚本 | `项目文档相关/` | Markdown + Shell + Python + SQL | + +## 关键目录 + +- 后端主入口:`netcore/src/Application/NCC.API/` +- 业务核心:`netcore/src/Modularity/Extend/`(Entitys → Interfaces → Services) +- 管理后台页面:`antis-ncc-admin/src/views/`,接口:`antis-ncc-admin/src/api/` +- 门店 PC 页面:`store-pc/src/views/` +- 数据库文档:`项目文档相关/docs/数据库说明.md` + +--- + +## 前端规范 + +- Node.js 必须使用 `16.20.2` +- GET 请求统一使用 `data` 传参,不使用 `params` +- 表格优先使用 `NCC-table` +- 弹窗、二级页、复杂表单必须拆为独立 `.vue` 文件(禁止在主页面 template 内直接写) +- 文件命名使用 `kebab-case` +- 操作按钮左对齐;列表内容不换行;空值显示"无" +- 卡片高度 100px、内边距 12px、圆角 12px +- 主色 `#409EFF`,辅助色 `#67C23A` / `#F56C6C` / `#909399` + +## 后端规范 + +- 不需要在 `NCC.API` 新建 Controller;`Extend` 中的 Service 直接暴露 +- 新实体 ID 必须使用 `YitIdHelper.NextId().ToString()`,禁止 `Guid.NewGuid()` +- 固定状态/类型必须使用 `enum`,并写 XML 注释 +- 列表接口必须分页 +- 查询条件优先 `WhereIF`,避免拼接 SQL +- 统计接口与列表接口必须使用完全一致的筛选条件、时间范围、权限控制与字段命名 +- 关键 API / 方法需要 XML 注释 + +## 数据口径 + +- 人员信息优先使用 `BASE_USER`,不要依赖 `lq_ryzl` +- 门店归属按月份从 `lq_md_target` 取,禁止使用 `lq_mdxx` 上的弃用归属字段 +- 表结构/字段说明变更后同步更新 `项目文档相关/docs/数据库说明.md` +- `base_organize.DeleteMark` 为 `null` 表示未删除 + +--- + +## Agents(子代理) + +Claude Code agents 配置在 `.claude/agents/`,对应 `.cursor/agents/` 中的角色: + +| Agent | 文件 | 职责 | +|---|---|---| +| orchestrator | `.claude/agents/orchestrator.md` | 任务分析与委派 | +| 后端 | `.claude/agents/backend-developer.md` | C# API / Service / DB | +| 前端 | `.claude/agents/frontend-developer.md` | Vue 2 页面 / 组件 | +| 测试 | `.claude/agents/test-engineer.md` | 接口测试与验证 | +| verifier | `.claude/agents/verifier.md` | 最终交付验收 | + +**任务分级委派原则**: +- L1(解释/评估/判断)→ 直接回答 +- L2(仅后端 / 仅前端)→ 启动对应 agent +- L3(跨角色)→ 并行启动多个 agent + +--- + +## Slash Commands(技能) + +Claude Code 命令配置在 `.claude/commands/`,对应 `.cursor/skills/` 中的 skill: + +| 命令 | 对应 Skill | 用途 | +|---|---|---| +| `/api-interface-testing` | `api-interface-testing` | 获取 Token、curl 接口测试流程 | +| `/api-xml-comments` | `api-xml-comments` | API XML 注释格式与模板 | +| `/deprecated-tables` | `deprecated-tables-context` | 已弃用表及替代方案 | +| `/mcp-mysql` | `mcp-mysql-and-sql-validation` | MCP MySQL 查库与 SQL 验证规范 | +| `/remember` | `remember-as-rule-or-skill` | 持久化规则或 Skill | +| `/ui-ux` | `ui-ux-pro-max` | UI/UX 设计系统生成 | + +--- + +## MCP 配置 + +MCP servers 配置在 `.claude/settings.json`(`mcpServers` 字段),与 `.cursor/mcp.json` 保持一致: + +| 服务 | 用途 | +|---|---| +| `my-sql-db` | MySQL 只读查询(lqerp_dev),使用 `@davewind/mysql-mcp-server` | +| `my-api-spec` | OpenAPI Spec 浏览与接口调用,使用 `@ivotoby/openapi-mcp-server` | +| `filesystem` | 文件系统访问,使用 `@modelcontextprotocol/server-filesystem` | +| `excel-reader` | Excel 文件读取,使用 `@negokaz/excel-mcp-server` | + +> 修改 MCP 时以 `.cursor/mcp.json` 为单一事实来源,再同步到 `.claude/settings.json`。 +> 同步脚本:`python3 项目文档相关/scripts/py/sync_cursor_mcp_to_codex.py` + +--- + +## 启动命令 + +```bash +# 后端 +cd netcore/src/Application/NCC.API && dotnet restore && dotnet run + +# 管理后台 +cd antis-ncc-admin && npm install && npm run dev # http://localhost:3000 + +# 门店 PC +cd store-pc && npm install && npm run dev # http://localhost:3100 +``` + +默认账号:`admin / 123456`,后端 API:`http://localhost:5000`,Swagger:`http://localhost:5000/antis.doc` + +--- + +## 参考资料(原始,保留在 .cursor/) + +- 项目总规则:`.cursor/rules/project_rules.mdc` +- Orchestrator 优先规则:`.cursor/rules/orchestrator-first.mdc` +- 接口测试:`.cursor/skills/api-interface-testing/SKILL.md` +- API 注释:`.cursor/skills/api-xml-comments/SKILL.md` +- 查库/SQL 验证:`.cursor/skills/mcp-mysql-and-sql-validation/SKILL.md` +- 已弃用表:`.cursor/skills/deprecated-tables-context/SKILL.md` +- 规则持久化:`.cursor/skills/remember-as-rule-or-skill/SKILL.md` +- UI/UX:`.cursor/skills/ui-ux-pro-max/SKILL.md` diff --git a/antis-ncc-admin/src/views/attendance-setting/components/attendance-config-item-dialog.vue b/antis-ncc-admin/src/views/attendance-setting/components/attendance-config-item-dialog.vue index 14801d3..fbb75f9 100644 --- a/antis-ncc-admin/src/views/attendance-setting/components/attendance-config-item-dialog.vue +++ b/antis-ncc-admin/src/views/attendance-setting/components/attendance-config-item-dialog.vue @@ -1,44 +1,22 @@