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 @@