From 4009b88ff0e1182bfe1ee4065a3fcad65b60dda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=87=E7=89=A9=E8=A1=97?= <7729700+wanwujie@user.noreply.gitee.com> Date: Fri, 29 Aug 2025 00:10:44 +0800 Subject: [PATCH] chore: sync changes for v0.1.1 --- .cursor/rules/aifont.mdc | 224 ++++++++ .../web-antd/src/addon/cms/api/article.ts | 102 ++++ .../cms/lang/zh-cn/article.category.json | 17 + .../addon/cms/lang/zh-cn/article.edit.json | 36 ++ .../addon/cms/lang/zh-cn/article.list.json | 21 + .../src/addon/cms/lang/zh-cn/common.json | 12 + .../src/addon/cms/views/article/category.vue | 144 +++++ .../article/components/edit-category.vue | 133 +++++ .../src/addon/cms/views/article/edit.vue | 175 ++++++ .../src/addon/cms/views/article/list.vue | 182 ++++++ .../cms/views/diy/components/edit-article.vue | 173 ++++++ .../src/addon/example/router/index.ts | 28 + .../src/addon/example/views/dashboard.vue | 9 + .../src/addon/example/views/public.vue | 9 + admin/apps/web-antd/src/constants/layout.ts | 8 + admin/apps/web-antd/src/layouts/app/admin.vue | 17 + admin/apps/web-antd/src/layouts/app/home.vue | 17 + admin/apps/web-antd/src/layouts/app/site.vue | 17 + .../src/locales/langs/en-US/page.json | 5 + .../src/locales/langs/zh-CN/page.json | 5 + .../src/locales/langs/zh-CN/system.json | 8 +- admin/apps/web-antd/src/preferences.ts | 12 +- admin/apps/web-antd/src/router/guard.ts | 27 +- admin/apps/web-antd/src/router/index.ts | 34 ++ .../apps/web-antd/src/router/routes/index.ts | 21 +- .../router/routes/modules/admin-setting.ts | 20 + .../src/router/routes/modules/app-entries.ts | 48 ++ .../src/router/routes/modules/system.ts | 9 + .../src/views/admin/setting/layout/index.vue | 50 ++ .../web-antd/src/views/app/admin/index.vue | 12 + .../web-antd/src/views/app/home/index.vue | 12 + .../web-antd/src/views/app/site/index.vue | 12 + .../web-antd/src/views/system/user/list.vue | 26 + admin/apps/web-antd/tsconfig.json | 3 +- admin/docs/scripts/generate-api-docs.js | 76 +-- admin/docs/src/wwjcloud/ai/coordination.md | 368 +++++------- .../docs/src/wwjcloud/ai/frontend-workflow.md | 544 ++++++++++++------ admin/docs/src/wwjcloud/ai/index.md | 15 +- admin/docs/src/wwjcloud/ai/workflow.md | 79 ++- scripts/deploy/kong/docker-compose.yml | 26 + scripts/deploy/kong/kong.yaml | 43 ++ sql/wwjcloud.sql | 33 ++ wwjcloud/docs/queue-system.md | 384 ------------- wwjcloud/docs/queue-usage.example.ts | 245 -------- wwjcloud/package.json | 2 +- wwjcloud/src/app.controller.ts | 23 - wwjcloud/src/app.module.ts | 80 +-- .../controllers/docsNavigationController.ts | 66 ++- wwjcloud/src/config/core/appConfig.ts | 27 +- wwjcloud/src/config/core/configModule.ts | 5 +- wwjcloud/src/config/index.ts | 3 - wwjcloud/src/config/integrations/index.ts | 2 - .../src/config/integrations/swaggerConfig.ts | 212 ------- .../modules/swagger/swaggerController.ts | 53 ++ .../config/modules/swagger/swaggerService.ts | 70 +++ .../core/event/outboxKafkaForwarder.module.ts | 12 + .../event/outboxKafkaForwarder.service.ts | 65 +++ wwjcloud/src/core/health/healthModule.ts | 2 - .../health/indicators/db.indicator.ts | 10 +- .../health/indicators/eventbus.indicator.ts | 10 +- .../health/indicators/queue.indicator.ts | 12 +- .../health/indicators/redis.indicator.ts | 19 +- .../health/indicators/storage.indicator.ts | 27 +- .../src/core/queue/databaseQueueProvider.ts | 7 +- .../src/core/queue/entities/event.entity.ts | 7 + .../src/core/queue/queueFactoryService.ts | 146 ++--- .../src/core/queue/redisTaskQueueProvider.ts | 216 +------ wwjcloud/src/main.ts | 56 +- .../1757000000001-AlterEventsAddSiteTrace.ts | 59 ++ wwjcloud/src/vendor/event/kafka.provider.ts | 43 +- wwjcloud/src/vendor/http/http.module.ts | 20 +- wwjcloud/src/vendor/queue/bullmq.provider.ts | 167 ++++-- wwjcloud/src/vendor/vendor.module.ts | 6 +- 73 files changed, 3128 insertions(+), 1740 deletions(-) create mode 100644 .cursor/rules/aifont.mdc create mode 100644 admin/apps/web-antd/src/addon/cms/api/article.ts create mode 100644 admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.category.json create mode 100644 admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.edit.json create mode 100644 admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.list.json create mode 100644 admin/apps/web-antd/src/addon/cms/lang/zh-cn/common.json create mode 100644 admin/apps/web-antd/src/addon/cms/views/article/category.vue create mode 100644 admin/apps/web-antd/src/addon/cms/views/article/components/edit-category.vue create mode 100644 admin/apps/web-antd/src/addon/cms/views/article/edit.vue create mode 100644 admin/apps/web-antd/src/addon/cms/views/article/list.vue create mode 100644 admin/apps/web-antd/src/addon/cms/views/diy/components/edit-article.vue create mode 100644 admin/apps/web-antd/src/addon/example/router/index.ts create mode 100644 admin/apps/web-antd/src/addon/example/views/dashboard.vue create mode 100644 admin/apps/web-antd/src/addon/example/views/public.vue create mode 100644 admin/apps/web-antd/src/constants/layout.ts create mode 100644 admin/apps/web-antd/src/layouts/app/admin.vue create mode 100644 admin/apps/web-antd/src/layouts/app/home.vue create mode 100644 admin/apps/web-antd/src/layouts/app/site.vue create mode 100644 admin/apps/web-antd/src/router/routes/modules/admin-setting.ts create mode 100644 admin/apps/web-antd/src/router/routes/modules/app-entries.ts create mode 100644 admin/apps/web-antd/src/views/admin/setting/layout/index.vue create mode 100644 admin/apps/web-antd/src/views/app/admin/index.vue create mode 100644 admin/apps/web-antd/src/views/app/home/index.vue create mode 100644 admin/apps/web-antd/src/views/app/site/index.vue create mode 100644 admin/apps/web-antd/src/views/system/user/list.vue create mode 100644 scripts/deploy/kong/docker-compose.yml create mode 100644 scripts/deploy/kong/kong.yaml delete mode 100644 wwjcloud/docs/queue-system.md delete mode 100644 wwjcloud/docs/queue-usage.example.ts delete mode 100644 wwjcloud/src/config/integrations/index.ts delete mode 100644 wwjcloud/src/config/integrations/swaggerConfig.ts create mode 100644 wwjcloud/src/config/modules/swagger/swaggerController.ts create mode 100644 wwjcloud/src/config/modules/swagger/swaggerService.ts create mode 100644 wwjcloud/src/core/event/outboxKafkaForwarder.module.ts create mode 100644 wwjcloud/src/core/event/outboxKafkaForwarder.service.ts create mode 100644 wwjcloud/src/migrations/1757000000001-AlterEventsAddSiteTrace.ts diff --git a/.cursor/rules/aifont.mdc b/.cursor/rules/aifont.mdc new file mode 100644 index 0000000..68aa7f8 --- /dev/null +++ b/.cursor/rules/aifont.mdc @@ -0,0 +1,224 @@ +--- +description: +globs: +alwaysApply: true +--- +# 前后端多智能体协调机制 + +## 协调原则 + +### 1. 同步开发原则 +- **并行开发**: 前后端智能体并行工作,通过契约接口协调 +- **契约优先**: 优先定义 API 契约,确保前后端接口一致 +- **质量对等**: 前后端质量要求保持一致,测试覆盖率对等 + +### 2. 规范对齐原则 +- **命名对齐**: 前后端命名规范保持一致,优先使用业务术语 +- **结构对齐**: 前后端数据结构保持一致,DTO 与前端类型对应 +- **错误对齐**: 前后端错误处理机制保持一致,错误码统一 + +### 3. 工具协调原则 +- **版本控制**: 使用 Git 进行版本控制,前后端代码分离管理 +- **CI/CD 协调**: 前后端构建流程协调,确保部署一致性 +- **文档同步**: API 文档与前端类型定义同步更新 + +## 智能体映射关系 + +| 前端智能体 | 后端智能体 | 协调阶段 | 主要职责 | +|-----------|-----------|----------|----------| +| F1 FrontendAnalyzer | S1 Analyzer | 需求分析 | 页面设计与接口设计协调 | +| F2 FrontendArchitect | S2 Architect | 架构设计 | 整体架构与目录结构协调 | +| F3 FrontendInfraOperator | S3 InfraOperator | 基建接入 | 开发环境与工具链协调 | +| F4 FrontendDeveloper | S4 Developer | 功能开发 | 接口实现与页面开发协调 | +| F5 FrontendSecurityGuard | S5 SecurityGuard | 安全检查 | 前后端安全策略协调 | +| F6 FrontendQualityGate | S6 QualityGate | 质量门禁 | 代码质量与测试协调 | +| F7 FrontendAuditor | S7 Auditor | 规范审计 | 代码规范与标准协调 | +| F8 FrontendRelease | S8 Release | 发布部署 | 构建部署与版本协调 | +| F9 FrontendPerfTuner | S9 PerfTuner | 性能优化 | 性能指标与优化协调 | + +## 协调检查点 + +### 1. 项目启动阶段 +**参与智能体**: F1 + S1 +**协调内容**: +- 业务需求分析与技术方案设计 +- 页面功能划分与 API 接口设计 +- 开发计划制定与里程碑设定 + +**输出产物**: +- 需求分析文档 +- API 接口设计文档 +- 开发计划与时间安排 + +### 2. 架构设计阶段 +**参与智能体**: F2 + S2 +**协调内容**: +- 整体架构设计与技术选型 +- 目录结构设计与模块划分 +- 数据流设计与状态管理方案 + +**输出产物**: +- 架构设计文档 +- 目录结构规范 +- 数据流设计文档 + +### 3. 基建接入阶段 +**参与智能体**: F3 + S3 +**协调内容**: +- 开发环境配置与工具链搭建 +- 依赖管理策略与版本控制 +- 构建流程设计与自动化配置 + +**输出产物**: +- 开发环境配置文档 +- 工具链使用指南 +- 构建流程文档 + +### 4. 功能开发阶段 +**参与智能体**: F4 + S4 +**协调内容**: +- API 接口实现与前端页面开发 +- 数据交互逻辑与状态管理 +- 业务逻辑实现与用户体验 + +**输出产物**: +- 功能模块代码 +- API 接口文档 +- 测试用例与测试报告 + +### 5. 质量保证阶段 +**参与智能体**: F5 + S5, F6 + S6 +**协调内容**: +- 安全策略实施与漏洞修复 +- 代码质量检查与测试覆盖 +- 性能指标监控与优化 + +**输出产物**: +- 安全评估报告 +- 质量检查报告 +- 性能测试报告 + +### 6. 规范审计阶段 +**参与智能体**: F7 + S7 +**协调内容**: +- 代码规范检查与标准对齐 +- 最佳实践实施与文档完善 +- 技术债务识别与重构计划 + +**输出产物**: +- 规范检查报告 +- 最佳实践文档 +- 重构计划与建议 + +### 7. 发布部署阶段 +**参与智能体**: F8 + S8 +**协调内容**: +- 构建流程协调与版本管理 +- 部署策略制定与环境配置 +- 发布计划执行与回滚预案 + +**输出产物**: +- 构建产物与部署包 +- 部署配置文档 +- 发布计划与回滚预案 + +## 协调工具 + +### 1. API 契约管理 +- **OpenAPI/Swagger**: API 接口文档与类型定义 +- **TypeScript 类型生成**: 前端类型定义自动生成 +- **API 测试工具**: 接口测试与验证 + +### 2. 版本控制 +- **Git**: 代码版本控制与分支管理 +- **GitHub/GitLab**: 代码托管与协作平台 +- **Git Flow**: 分支策略与发布流程 + +### 3. CI/CD 协调 +- **GitHub Actions/GitLab CI**: 自动化构建与测试 +- **Docker**: 容器化部署与环境一致性 +- **Kubernetes**: 容器编排与服务管理 + +### 4. 项目管理 +- **Jira/ZenTao**: 需求管理与任务跟踪 +- **Confluence/Notion**: 文档管理与知识共享 +- **Slack/钉钉**: 即时沟通与通知 + +### 5. 监控与反馈 +- **Sentry**: 错误监控与性能追踪 +- **Prometheus**: 指标监控与告警 +- **Grafana**: 数据可视化与报表 + +## 协调流程 + +### 1. 日常开发协调 +``` +每日站会 → 任务分配 → 并行开发 → 代码审查 → 集成测试 → 部署验证 +``` + +### 2. 版本发布协调 +``` +需求冻结 → 功能开发 → 集成测试 → 预发布验证 → 正式发布 → 监控反馈 +``` + +### 3. 问题处理协调 +``` +问题发现 → 影响评估 → 方案制定 → 并行修复 → 验证测试 → 部署上线 +``` + +## 协调规范 + +### 1. 沟通规范 +- **定期同步**: 每日站会、周例会、里程碑评审 +- **异步沟通**: 使用文档、评论、邮件进行异步沟通 +- **紧急沟通**: 使用即时通讯工具进行紧急问题处理 + +### 2. 文档规范 +- **API 文档**: 使用 OpenAPI 规范,及时更新 +- **技术文档**: 使用 Markdown 格式,结构清晰 +- **变更日志**: 记录所有重要变更,便于追溯 + +### 3. 代码规范 +- **命名规范**: 前后端命名保持一致,使用业务术语 +- **注释规范**: 关键逻辑必须有注释,便于理解 +- **提交规范**: 使用规范的提交信息,便于版本管理 + +### 4. 测试规范 +- **单元测试**: 前后端都要有充分的单元测试 +- **集成测试**: 前后端集成测试,确保接口正确 +- **端到端测试**: 完整的用户流程测试 + +## 效果评估 + +### 1. 开发效率指标 +- **开发周期**: 从需求到上线的完整周期 +- **代码质量**: 缺陷密度、技术债务比例 +- **团队协作**: 沟通效率、冲突解决时间 + +### 2. 产品质量指标 +- **功能完整性**: 需求实现程度、功能覆盖率 +- **性能指标**: 响应时间、吞吐量、资源使用 +- **用户体验**: 用户满意度、易用性评分 + +### 3. 运维指标 +- **部署频率**: 发布频率、部署成功率 +- **系统稳定性**: 可用性、故障恢复时间 +- **监控覆盖**: 监控覆盖率、告警准确性 + +## 持续改进 + +### 1. 定期回顾 +- **周回顾**: 每周进行开发回顾,识别改进点 +- **月回顾**: 每月进行项目回顾,评估整体效果 +- **季度回顾**: 每季度进行战略回顾,调整方向 + +### 2. 改进措施 +- **流程优化**: 根据回顾结果优化协调流程 +- **工具升级**: 引入新的工具提升协作效率 +- **技能提升**: 团队技能培训与知识分享 + +### 3. 最佳实践 +- **经验总结**: 总结成功经验,形成最佳实践 +- **案例分享**: 分享典型案例,促进团队学习 + +- **标准制定**: 制定团队标准,确保一致性 \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/cms/api/article.ts b/admin/apps/web-antd/src/addon/cms/api/article.ts new file mode 100644 index 0000000..7619ab1 --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/api/article.ts @@ -0,0 +1,102 @@ +import request from '@/utils/request' + +/***************************************************** 文章表 ****************************************************/ + +/** + * 获取文章表列表 + * @param params + * @returns + */ +export function getArticleList(params: Record) { + return request.get(`cms/article`, {params}) +} + +/** + * 获取文章表详情 + * @param id 文章表id + * @returns + */ +export function getArticleInfo(id: number) { + return request.get(`cms/article/${id}`); +} + +/** + * 添加文章表 + * @param params + * @returns + */ +export function addArticle(params: Record) { + return request.post('cms/article', params, {showSuccessMessage: true}) +} + +/** + * 编辑文章表 + * @param params + */ +export function editArticle(params: Record) { + return request.put(`cms/article/${params.id}`, params, {showSuccessMessage: true}) +} + +/** + * 删除文章表 + * @param id + * @returns + */ +export function deleteArticle(id: number) { + return request.delete(`cms/article/${id}`, {showSuccessMessage: true}) +} + +/***************************************************** 文章分类管理 ****************************************************/ + +/** + * 获取文章分类列表 + * @param params + * @returns + */ +export function getArticleCategoryList(params: Record) { + return request.get(`cms/category`, {params}) +} + + +/** + * 获取文章全部分类 + * @param params + * @returns + */ +export function getArticleCategoryAll(params: Record) { + return request.get(`cms/category/all`, params) +} + +/** + * 获取文章分类详情 + * @param category_id + */ +export function getArticleCategoryInfo(category_id: number) { + return request.get(`cms/category/${category_id}`); +} + +/** + * 添加文章分类 + * @param params + * @returns + */ +export function addArticleCategory(params: Record) { + return request.post('cms/category', params, {showSuccessMessage: true}) +} + +/** + * 编辑文章分类 + * @param params + * @returns + */ +export function editArticleCategory(params: Record) { + return request.put(`cms/category/${params.category_id}`, params, {showSuccessMessage: true}) +} + +/** + * 文章分类删除 + * @param category_id + */ +export function deleteArticleCategory(category_id: number) { + return request.delete(`cms/category/${category_id}`, {showSuccessMessage: true}); +} \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.category.json b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.category.json new file mode 100644 index 0000000..886b34a --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.category.json @@ -0,0 +1,17 @@ +{ + "name": "栏目名称", + "sort": "排序", + "isShow": "是否显示", + "namePlaceholder": "请输入栏目名称", + "sortPlaceholder": "请输入排序", + "isShowPlaceholder": "是否显示", + "addArticleCategory": "添加栏目", + "updateArticleCategory": "编辑栏目", + "articleCategoryDeleteTips": "确定要删除该栏目吗?", + "nameMax": "名称不能超过20个字符", + "sortNumber": "排序号必须是数字", + "sortBetween": "排序号不能超过10000", + "show": "显示", + "hide": "不显示", + "articleNumber": "文章数量" +} \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.edit.json b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.edit.json new file mode 100644 index 0000000..437e8c0 --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.edit.json @@ -0,0 +1,36 @@ +{ + "categoryName": "文章栏目", + "title": "文章标题", + "intro": "简介", + "summary": "文章摘要", + "image": "文章图片", + "author": "作者", + "content": "文章内容", + "visit": "实际浏览量", + "visitVirtual": "初始浏览量", + "isShow": "是否显示", + "sort": "排序", + "categoryIdPlaceholder": "请选择文章栏目", + "titlePlaceholder": "请输入文章标题", + "introPlaceholder": "请输入简介", + "summaryPlaceholder": "请输入文章摘要", + "imagePlaceholder": "请上传文章图片", + "authorPlaceholder": "请输入作者", + "contentPlaceholder": "请输入文章内容", + "visitPlaceholder": "请输入实际浏览量", + "visitVirtualPlaceholder": "请输入初始浏览量", + "isShowPlaceholder": "是否显示", + "sortPlaceholder": "请输入排序", + "addArticle": "添加文章", + "updateArticle": "编辑文章", + "titleMax": "文章标题不能超过20个字符", + "introMax": "文章简介不能超过50个字符", + "summaryMax": "文章摘要不能超过50个字符", + "imageMax": "图片路径太长", + "authorMax": "文章作者不能超过20个字符", + "isShowNumber": "是否显示必须是数字", + "isShowBetween": "是否显示只能是0或者1", + "sortNumber": "排序号必须是数字", + "sortBetween": "排序号需要在0-10000之间", + "articleNull": "未读取到文章信息!" +} \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.list.json b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.list.json new file mode 100644 index 0000000..2f4b076 --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/article.list.json @@ -0,0 +1,21 @@ +{ + "categoryName": "栏目", + "ID": "ID", + "title": "标题", + "intro": "简介", + "summary": "摘要", + "image": "封面", + "author": "作者", + "content": "文章内容", + "visit": "浏览量", + "visitVirtual": "初始浏览量", + "isShow": "是否显示", + "sort": "排序", + "createTime": "创建时间", + "updateTime": "更新时间", + "addArticle": "添加文章", + "updateArticle": "编辑文章", + "titlePlaceholder": "请输入文章标题", + "categoryIdPlaceholder": "请选择文章栏目", + "articleDeleteTips": "确定要删除该文章吗?" +} \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/cms/lang/zh-cn/common.json b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/common.json new file mode 100644 index 0000000..335f240 --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/lang/zh-cn/common.json @@ -0,0 +1,12 @@ +{ + "articleData": "文章数据", + "articleStyle": "文章样式", + "articleBgColor": "文章背景", + "articleNum": "文章数量", + "selectArticleTips": "文章选择", + "articleTitle": "标题", + "articleImage": "封面", + "articleCategoryName": "栏目", + "articleSummary": "摘要", + "selectArticleTip": "请选择文章" +} \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/cms/views/article/category.vue b/admin/apps/web-antd/src/addon/cms/views/article/category.vue new file mode 100644 index 0000000..becd50a --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/views/article/category.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/admin/apps/web-antd/src/addon/cms/views/article/components/edit-category.vue b/admin/apps/web-antd/src/addon/cms/views/article/components/edit-category.vue new file mode 100644 index 0000000..bd16aec --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/views/article/components/edit-category.vue @@ -0,0 +1,133 @@ + + + + + diff --git a/admin/apps/web-antd/src/addon/cms/views/article/edit.vue b/admin/apps/web-antd/src/addon/cms/views/article/edit.vue new file mode 100644 index 0000000..267450b --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/views/article/edit.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/admin/apps/web-antd/src/addon/cms/views/article/list.vue b/admin/apps/web-antd/src/addon/cms/views/article/list.vue new file mode 100644 index 0000000..b233e55 --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/views/article/list.vue @@ -0,0 +1,182 @@ + + + + + diff --git a/admin/apps/web-antd/src/addon/cms/views/diy/components/edit-article.vue b/admin/apps/web-antd/src/addon/cms/views/diy/components/edit-article.vue new file mode 100644 index 0000000..c1a04b3 --- /dev/null +++ b/admin/apps/web-antd/src/addon/cms/views/diy/components/edit-article.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/admin/apps/web-antd/src/addon/example/router/index.ts b/admin/apps/web-antd/src/addon/example/router/index.ts new file mode 100644 index 0000000..42fb632 --- /dev/null +++ b/admin/apps/web-antd/src/addon/example/router/index.ts @@ -0,0 +1,28 @@ +import type { RouteRecordRaw } from 'vue-router'; + +export const NO_LOGIN_ROUTES: string[] = ['/home/example/public']; + +export const ROUTE: RouteRecordRaw[] = [ + { + name: 'ExampleAddonRoot', + path: '/home/example', + meta: { title: '示例插件', app: 'home' }, + component: () => import('#/layouts/app/home.vue'), + children: [ + { + name: 'ExampleAddonPublic', + path: 'public', + meta: { title: '公开页面' }, + component: () => import('../views/public.vue'), + }, + { + name: 'ExampleAddonDashboard', + path: 'dashboard', + meta: { title: '插件仪表盘' }, + component: () => import('../views/dashboard.vue'), + }, + ], + }, +]; + +export default ROUTE; \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/example/views/dashboard.vue b/admin/apps/web-antd/src/addon/example/views/dashboard.vue new file mode 100644 index 0000000..8508b4a --- /dev/null +++ b/admin/apps/web-antd/src/addon/example/views/dashboard.vue @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/addon/example/views/public.vue b/admin/apps/web-antd/src/addon/example/views/public.vue new file mode 100644 index 0000000..8a07a91 --- /dev/null +++ b/admin/apps/web-antd/src/addon/example/views/public.vue @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/constants/layout.ts b/admin/apps/web-antd/src/constants/layout.ts new file mode 100644 index 0000000..b76ac64 --- /dev/null +++ b/admin/apps/web-antd/src/constants/layout.ts @@ -0,0 +1,8 @@ +export const LAYOUT_OPTIONS = [ + { key: 'sidebar-nav', i18nKey: 'layout.vertical' }, + { key: 'sidebar-mixed-nav', i18nKey: 'layout.verticalMix' }, + { key: 'header-nav', i18nKey: 'layout.horizontal' }, + { key: 'header-sidebar-nav', i18nKey: 'layout.headerSidebar' }, +] as const; + +export type LayoutKey = (typeof LAYOUT_OPTIONS)[number]['key']; \ No newline at end of file diff --git a/admin/apps/web-antd/src/layouts/app/admin.vue b/admin/apps/web-antd/src/layouts/app/admin.vue new file mode 100644 index 0000000..2bde0c7 --- /dev/null +++ b/admin/apps/web-antd/src/layouts/app/admin.vue @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/layouts/app/home.vue b/admin/apps/web-antd/src/layouts/app/home.vue new file mode 100644 index 0000000..b183068 --- /dev/null +++ b/admin/apps/web-antd/src/layouts/app/home.vue @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/layouts/app/site.vue b/admin/apps/web-antd/src/layouts/app/site.vue new file mode 100644 index 0000000..7edd3b5 --- /dev/null +++ b/admin/apps/web-antd/src/layouts/app/site.vue @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/locales/langs/en-US/page.json b/admin/apps/web-antd/src/locales/langs/en-US/page.json index 50f19dc..18ed493 100644 --- a/admin/apps/web-antd/src/locales/langs/en-US/page.json +++ b/admin/apps/web-antd/src/locales/langs/en-US/page.json @@ -12,5 +12,10 @@ "title": "Dashboard", "analytics": "Analytics", "workspace": "Workspace" + }, + "adminSetting": { + "layoutTitle": "Layout Settings", + "appList": "Application List", + "chooseLayout": "Choose Layout" } } diff --git a/admin/apps/web-antd/src/locales/langs/zh-CN/page.json b/admin/apps/web-antd/src/locales/langs/zh-CN/page.json index 666db5b..ce3f973 100644 --- a/admin/apps/web-antd/src/locales/langs/zh-CN/page.json +++ b/admin/apps/web-antd/src/locales/langs/zh-CN/page.json @@ -12,5 +12,10 @@ "title": "概览", "analytics": "分析页", "workspace": "工作台" + }, + "adminSetting": { + "layoutTitle": "布局设置", + "appList": "应用列表", + "chooseLayout": "选择布局" } } diff --git a/admin/apps/web-antd/src/locales/langs/zh-CN/system.json b/admin/apps/web-antd/src/locales/langs/zh-CN/system.json index b0f5e7f..165d751 100644 --- a/admin/apps/web-antd/src/locales/langs/zh-CN/system.json +++ b/admin/apps/web-antd/src/locales/langs/zh-CN/system.json @@ -63,5 +63,11 @@ "permissions": "权限", "setPermissions": "授权" }, - "title": "系统管理" + "title": "系统管理", + "layout": { + "header": "头部", + "sider": "侧边栏", + "footer": "底部", + "content": "内容" + } } diff --git a/admin/apps/web-antd/src/preferences.ts b/admin/apps/web-antd/src/preferences.ts index b2e9ace..0d19f3b 100644 --- a/admin/apps/web-antd/src/preferences.ts +++ b/admin/apps/web-antd/src/preferences.ts @@ -6,8 +6,18 @@ import { defineOverridesPreferences } from '@vben/preferences'; * !!! 更改配置后请清空缓存,否则可能不生效 */ export const overridesPreferences = defineOverridesPreferences({ - // overrides + // 可按需覆盖默认偏好 app: { name: import.meta.env.VITE_APP_TITLE, }, }); + +/** + * 根据路由前缀选择默认布局(可替换为后端/站点配置) + * 规范值参考:'sidebar-nav' | 'sidebar-mixed-nav' | 'header-nav' | 'header-mixed-nav' | 'header-sidebar-nav' + */ +export const APP_LAYOUT_BY_PREFIX: Record = { + admin: 'sidebar-mixed-nav', + home: 'header-nav', + site: 'sidebar-nav', +}; diff --git a/admin/apps/web-antd/src/router/guard.ts b/admin/apps/web-antd/src/router/guard.ts index 514bd2e..2b3e51b 100644 --- a/admin/apps/web-antd/src/router/guard.ts +++ b/admin/apps/web-antd/src/router/guard.ts @@ -1,12 +1,14 @@ import type { Router } from 'vue-router'; import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; +import { preferences, updatePreferences } from '@vben/preferences'; import { useAccessStore, useUserStore } from '@vben/stores'; import { startProgress, stopProgress } from '@vben/utils'; import { accessRoutes, coreRouteNames } from '#/router/routes'; import { useAuthStore } from '#/store'; +import { NO_LOGIN_ROUTES } from '#/router/routes'; +import { APP_LAYOUT_BY_PREFIX } from '#/preferences'; import { generateAccess } from './access'; @@ -21,6 +23,13 @@ function setupCommonGuard(router: Router) { router.beforeEach((to) => { to.meta.loaded = loadedPaths.has(to.path); + // 根据前缀切换布局(由配置驱动,可接后端/站点设置) + const first = to.path.replace(/^\/+/, '').split('/')[0] as string; + const desiredLayout = APP_LAYOUT_BY_PREFIX[first]; + if (desiredLayout && preferences.app.layout !== desiredLayout) { + updatePreferences({ app: { layout: desiredLayout as any } }); + } + // 页面加载进度条 if (!to.meta.loaded && preferences.transition.progress) { startProgress(); @@ -36,6 +45,14 @@ function setupCommonGuard(router: Router) { if (preferences.transition.progress) { stopProgress(); } + + // 设置标题:路由标题 + 站点/网站名(如有) + const titleParts: string[] = []; + if (typeof to.meta?.title === 'string') titleParts.push(to.meta.title); + // 这里可扩展注入 store 的网站/站点名 + const websiteName = ''; + if (websiteName) titleParts.push(websiteName); + if (titleParts.length) document.title = titleParts.join(' - '); }); } @@ -67,6 +84,11 @@ function setupAccessGuard(router: Router) { return true; } + // addon 定义的免登录白名单 + if (NO_LOGIN_ROUTES?.includes(to.path)) { + return true; + } + // 没有访问权限,跳转登录页面 if (to.fullPath !== LOGIN_PATH) { return { @@ -105,6 +127,8 @@ function setupAccessGuard(router: Router) { accessStore.setAccessMenus(accessibleMenus); accessStore.setAccessRoutes(accessibleRoutes); accessStore.setIsAccessChecked(true); + + // 计算首次进入首页路径 let redirectPath: string; if (from.query.redirect) { redirectPath = from.query.redirect as string; @@ -115,6 +139,7 @@ function setupAccessGuard(router: Router) { } else { redirectPath = to.fullPath; } + return { ...router.resolve(decodeURIComponent(redirectPath)), replace: true, diff --git a/admin/apps/web-antd/src/router/index.ts b/admin/apps/web-antd/src/router/index.ts index 4840230..405db94 100644 --- a/admin/apps/web-antd/src/router/index.ts +++ b/admin/apps/web-antd/src/router/index.ts @@ -31,6 +31,40 @@ const router = createRouter({ const resetRoutes = () => resetStaticRoutes(router, routes); +// 获取当前 app 类型(admin/site/home),默认 admin +function getAppType(): 'admin' | 'site' | 'home' { + const path = location.pathname.replace(/^\/+/, ''); + const first = path.split('/')[0]; + if (first === 'site' || first === 'home' || first === 'admin') return first as any; + return 'admin'; +} + +// 重写 push,自动补齐 app 前缀 +const originPush = router.push.bind(router); +router.push = (to: any) => { + const route = typeof to === 'string' ? { path: to } : { ...to }; + if (route.path) { + const parts = route.path.split('/').filter(Boolean); + if (!['admin', 'site', 'home'].includes(parts[0])) { + route.path = `/${getAppType()}${route.path.startsWith('/') ? '' : '/'}${route.path}`; + } + } + return originPush(route); +}; + +// 重写 resolve,保证解析时也有 app 前缀 +const originResolve = router.resolve.bind(router); +router.resolve = (to: any, currentLocation?: any) => { + const route = typeof to === 'string' ? { path: to } : { ...to }; + if (route.path) { + const parts = route.path.split('/').filter(Boolean); + if (!['admin', 'site', 'home'].includes(parts[0])) { + route.path = `/${getAppType()}${route.path.startsWith('/') ? '' : '/'}${route.path}`; + } + } + return originResolve(route, currentLocation); +}; + // 创建路由守卫 createRouterGuard(router); diff --git a/admin/apps/web-antd/src/router/routes/index.ts b/admin/apps/web-antd/src/router/routes/index.ts index 275eb83..a868661 100644 --- a/admin/apps/web-antd/src/router/routes/index.ts +++ b/admin/apps/web-antd/src/router/routes/index.ts @@ -15,6 +15,22 @@ const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', { /** 动态路由 */ const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); +/** 从 addon 中加载路由与免登录白名单(对齐 PHP admin 的插件机制) */ +const addonRouteFiles = import.meta.glob('../../addon/**/router/index.ts', { eager: true }); +const addonRoutes: RouteRecordRaw[] = []; +const addonNoLoginPaths: string[] = []; +Object.values(addonRouteFiles).forEach((mod: any) => { + if (Array.isArray(mod?.default)) { + addonRoutes.push(...mod.default); + } + if (Array.isArray(mod?.ROUTE)) { + addonRoutes.push(...mod.ROUTE); + } + if (Array.isArray(mod?.NO_LOGIN_ROUTES)) { + addonNoLoginPaths.push(...mod.NO_LOGIN_ROUTES); + } +}); + /** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */ // const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles); // const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles); @@ -32,8 +48,8 @@ const routes: RouteRecordRaw[] = [ /** 基本路由列表,这些路由不需要进入权限拦截 */ const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name); -/** 有权限校验的路由列表,包含动态路由和静态路由 */ -const accessRoutes = [...dynamicRoutes, ...staticRoutes]; +/** 有权限校验的路由列表,包含动态路由、静态路由与 addon 路由 */ +const accessRoutes = [...dynamicRoutes, ...staticRoutes, ...addonRoutes]; const componentKeys: string[] = Object.keys( import.meta.glob('../../views/**/*.vue'), @@ -45,3 +61,4 @@ const componentKeys: string[] = Object.keys( }); export { accessRoutes, componentKeys, coreRouteNames, routes }; +export const NO_LOGIN_ROUTES: string[] = addonNoLoginPaths; diff --git a/admin/apps/web-antd/src/router/routes/modules/admin-setting.ts b/admin/apps/web-antd/src/router/routes/modules/admin-setting.ts new file mode 100644 index 0000000..ae27ed5 --- /dev/null +++ b/admin/apps/web-antd/src/router/routes/modules/admin-setting.ts @@ -0,0 +1,20 @@ +import type { RouteRecordRaw } from 'vue-router'; + +const routes: RouteRecordRaw[] = [ + { + name: 'AdminSettingRoot', + path: '/admin/setting', + meta: { title: '系统设置' }, + component: () => import('#/layouts/app/admin.vue'), + children: [ + { + name: 'AdminSettingLayout', + path: 'layout', + meta: { title: '布局设置' }, + component: () => import('#/views/admin/setting/layout/index.vue'), + }, + ], + }, +]; + +export default routes; \ No newline at end of file diff --git a/admin/apps/web-antd/src/router/routes/modules/app-entries.ts b/admin/apps/web-antd/src/router/routes/modules/app-entries.ts new file mode 100644 index 0000000..69c7570 --- /dev/null +++ b/admin/apps/web-antd/src/router/routes/modules/app-entries.ts @@ -0,0 +1,48 @@ +import type { RouteRecordRaw } from 'vue-router'; + +const routes: RouteRecordRaw[] = [ + { + name: 'AdminRoot', + path: '/admin', + meta: { title: 'Admin' }, + component: () => import('#/layouts/app/admin.vue'), + children: [ + { + name: 'AdminIndex', + path: '', + component: () => import('#/views/app/admin/index.vue'), + meta: { title: 'Admin 控制台' }, + }, + ], + }, + { + name: 'HomeRoot', + path: '/home', + meta: { title: 'Home' }, + component: () => import('#/layouts/app/home.vue'), + children: [ + { + name: 'HomeIndex', + path: '', + component: () => import('#/views/app/home/index.vue'), + meta: { title: 'Home 门户' }, + }, + ], + }, + { + name: 'SiteRoot', + path: '/site', + meta: { title: 'Site' }, + component: () => import('#/layouts/app/site.vue'), + children: [ + { + name: 'SiteIndex', + path: '', + component: () => import('#/views/app/site/index.vue'), + meta: { title: 'Site 应用' }, + }, + ], + }, +]; + +export default routes; \ No newline at end of file diff --git a/admin/apps/web-antd/src/router/routes/modules/system.ts b/admin/apps/web-antd/src/router/routes/modules/system.ts index e1bf712..f610ddf 100644 --- a/admin/apps/web-antd/src/router/routes/modules/system.ts +++ b/admin/apps/web-antd/src/router/routes/modules/system.ts @@ -12,6 +12,15 @@ const routes: RouteRecordRaw[] = [ name: 'System', path: '/system', children: [ + { + path: '/system/user', + name: 'SystemUser', + meta: { + icon: 'mdi:account-circle-outline', + title: $t('system.user.title'), + }, + component: () => import('#/views/system/user/list.vue'), + }, { path: '/system/role', name: 'SystemRole', diff --git a/admin/apps/web-antd/src/views/admin/setting/layout/index.vue b/admin/apps/web-antd/src/views/admin/setting/layout/index.vue new file mode 100644 index 0000000..85dba60 --- /dev/null +++ b/admin/apps/web-antd/src/views/admin/setting/layout/index.vue @@ -0,0 +1,50 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/views/app/admin/index.vue b/admin/apps/web-antd/src/views/app/admin/index.vue new file mode 100644 index 0000000..fc0f1b3 --- /dev/null +++ b/admin/apps/web-antd/src/views/app/admin/index.vue @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/views/app/home/index.vue b/admin/apps/web-antd/src/views/app/home/index.vue new file mode 100644 index 0000000..49ff595 --- /dev/null +++ b/admin/apps/web-antd/src/views/app/home/index.vue @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/views/app/site/index.vue b/admin/apps/web-antd/src/views/app/site/index.vue new file mode 100644 index 0000000..3f60815 --- /dev/null +++ b/admin/apps/web-antd/src/views/app/site/index.vue @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/admin/apps/web-antd/src/views/system/user/list.vue b/admin/apps/web-antd/src/views/system/user/list.vue new file mode 100644 index 0000000..8eae031 --- /dev/null +++ b/admin/apps/web-antd/src/views/system/user/list.vue @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/admin/apps/web-antd/tsconfig.json b/admin/apps/web-antd/tsconfig.json index 02c287f..7538f1e 100644 --- a/admin/apps/web-antd/tsconfig.json +++ b/admin/apps/web-antd/tsconfig.json @@ -8,5 +8,6 @@ } }, "references": [{ "path": "./tsconfig.node.json" }], - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "exclude": ["src/addon/**"] } diff --git a/admin/docs/scripts/generate-api-docs.js b/admin/docs/scripts/generate-api-docs.js index cc1cd96..b9405bb 100644 --- a/admin/docs/scripts/generate-api-docs.js +++ b/admin/docs/scripts/generate-api-docs.js @@ -14,13 +14,27 @@ const config = { backendUrl: process.env.BACKEND_URL || 'http://localhost:3000', docsDir: path.join(__dirname, '../src/wwjcloud/openapi/api'), apiGroups: { - unified: { - name: '统一 API', - swaggerPath: '/docs-json', - outputDir: 'unified', - prefix: '' - } - } + full: { + name: '全量 API', + swaggerPath: process.env.OPENAPI_FULL_PATH || '/api-json', + outputDir: 'full', + prefix: '', + }, + admin: { + name: '管理端 API', + swaggerPath: process.env.OPENAPI_ADMIN_PATH || '/api/admin-json', + outputDir: 'admin', + prefix: '/adminapi', + }, + frontend: { + name: '前端 API', + swaggerPath: process.env.OPENAPI_FRONTEND_PATH || '/api/frontend-json', + outputDir: 'frontend', + prefix: '/api', + }, + }, + // 固定 Token(与后端 swagger.token 保持一致) + token: '9f2a7c1e4b5d8a90c3f6e2b17a4c58d0f1b2c3d4e5f67890ab12cd34ef56a789', }; /** @@ -30,7 +44,9 @@ async function getSwaggerJson(group) { try { const url = `${config.backendUrl}${group.swaggerPath}`; console.log(`获取 ${group.name} API: ${url}`); - const response = await axios.get(url); + const headers = {}; + if (config.token) headers.Authorization = `Bearer ${config.token}`; + const response = await axios.get(url, { headers }); return response.data; } catch (error) { console.error(`获取失败: ${error.message}`); @@ -44,28 +60,28 @@ async function getSwaggerJson(group) { function generateModuleDoc(group, tag, paths) { const moduleName = tag.name; let markdown = `--- -title: ${moduleName} API -description: ${tag.description || `${moduleName} 相关接口`} +:title: ${moduleName} API +:description: ${tag.description || `${moduleName} 相关接口`} --- # ${moduleName} API -::: info ${moduleName} +:::: info ${moduleName} ${tag.description || `${moduleName} 相关接口`} -::: +:::: ## API 列表 `; // 查找该标签下的接口 - Object.keys(paths).forEach(path => { - Object.keys(paths[path]).forEach(method => { - const operation = paths[path][method]; + Object.keys(paths).forEach((p) => { + Object.keys(paths[p]).forEach((method) => { + const operation = paths[p][method]; if (operation.tags && operation.tags.includes(tag.name)) { - markdown += generateApiDoc(path, method, operation); + markdown += generateApiDoc(p, method, operation); } }); }); @@ -76,11 +92,11 @@ ${tag.description || `${moduleName} 相关接口`} /** * 生成单个 API 文档 */ -function generateApiDoc(path, method, operation) { +function generateApiDoc(pathname, method, operation) { const summary = operation.summary || operation.operationId || '未命名接口'; let doc = `### ${summary}\n\n`; - doc += `**接口**: \`${method.toUpperCase()} ${path}\`\n\n`; + doc += `**接口**: \`${method.toUpperCase()} ${pathname}\`\n\n`; if (operation.description) { doc += `**描述**: ${operation.description}\n\n`; @@ -92,7 +108,7 @@ function generateApiDoc(path, method, operation) { doc += `| 参数 | 类型 | 必填 | 说明 |\n`; doc += `|------|------|------|------|\n`; - operation.parameters.forEach(param => { + operation.parameters.forEach((param) => { const required = param.required ? '是' : '否'; const type = param.type || param.schema?.type || 'string'; doc += `| ${param.name} | ${type} | ${required} | ${param.description || ''} |\n`; @@ -104,22 +120,14 @@ function generateApiDoc(path, method, operation) { if (operation.requestBody) { doc += `**请求体**:\n\n`; doc += `\`\`\`json\n`; - doc += `{\n`; - doc += ` // 请求数据\n`; - doc += `}\n`; + doc += `{}\n`; doc += `\`\`\`\n\n`; } // 响应 doc += `**响应**:\n\n`; doc += `\`\`\`json\n`; - doc += `{\n`; - doc += ` "code": 200,\n`; - doc += ` "message": "success",\n`; - doc += ` "data": {\n`; - doc += ` // 响应数据\n`; - doc += ` }\n`; - doc += `}\n`; + doc += `{"code":200,"message":"success","data":{}}\n`; doc += `\`\`\`\n\n`; doc += `---\n\n`; @@ -148,7 +156,7 @@ function saveDocument(outputPath, content) { async function main() { console.log('开始自动生成 API 文档...\n'); - for (const [key, group] of Object.entries(config.apiGroups)) { + for (const [_key, group] of Object.entries(config.apiGroups)) { console.log(`处理 ${group.name}...`); const swaggerData = await getSwaggerJson(group); @@ -164,7 +172,11 @@ async function main() { for (const tag of tags) { const moduleName = tag.name.toLowerCase().replace(/\s+/g, '-'); const content = generateModuleDoc(group, tag, paths); - const outputPath = path.join(config.docsDir, group.outputDir, `${moduleName}.md`); + const outputPath = path.join( + config.docsDir, + group.outputDir, + `${moduleName}.md`, + ); saveDocument(outputPath, content); } @@ -177,7 +189,7 @@ async function main() { // 运行 if (require.main === module) { - main().catch(error => { + main().catch((error) => { console.error('执行失败:', error); process.exit(1); }); diff --git a/admin/docs/src/wwjcloud/ai/coordination.md b/admin/docs/src/wwjcloud/ai/coordination.md index 7e10d27..69070e3 100644 --- a/admin/docs/src/wwjcloud/ai/coordination.md +++ b/admin/docs/src/wwjcloud/ai/coordination.md @@ -1,276 +1,218 @@ -# 前后端智能体协调配置 +# 前后端多智能体协调机制 ## 协调原则 ### 1. 同步开发原则 -- 前后端智能体同时启动,并行开发 -- 通过 API 契约进行协调 -- 定期同步开发进度 +- **并行开发**: 前后端智能体并行工作,通过契约接口协调 +- **契约优先**: 优先定义 API 契约,确保前后端接口一致 +- **质量对等**: 前后端质量要求保持一致,测试覆盖率对等 -### 2. 契约优先原则 -- 先定义 API 接口契约 -- 前后端基于契约独立开发 -- 契约变更需要双方确认 +### 2. 规范对齐原则 +- **命名对齐**: 前后端命名规范保持一致,优先使用业务术语 +- **结构对齐**: 前后端数据结构保持一致,DTO 与前端类型对应 +- **错误对齐**: 前后端错误处理机制保持一致,错误码统一 -### 3. 质量对等原则 -- 前后端质量要求一致 -- 测试覆盖率要求相同 -- 代码规范标准统一 +### 3. 工具协调原则 +- **版本控制**: 使用 Git 进行版本控制,前后端代码分离管理 +- **CI/CD 协调**: 前后端构建流程协调,确保部署一致性 +- **文档同步**: API 文档与前端类型定义同步更新 ## 智能体映射关系 -| 前端智能体 | 后端智能体 | 协调内容 | 协调时机 | +| 前端智能体 | 后端智能体 | 协调阶段 | 主要职责 | |-----------|-----------|----------|----------| -| F1 FrontendAnalyzer | S1 Analyzer | 需求分析、API 设计 | 项目启动 | -| F2 FrontendArchitect | S2 Architect | 架构设计、接口定义 | 架构设计阶段 | -| F3 FrontendInfraOperator | S3 InfraOperator | 基建接入、环境配置 | 基建搭建阶段 | -| F4 FrontendDeveloper | S4 Developer | 功能开发、接口联调 | 开发阶段 | -| F5 FrontendSecurityGuard | S5 SecurityGuard | 安全检查、权限控制 | 开发中/提测前 | -| F6 FrontendQualityGate | S6 QualityGate | 质量检查、测试覆盖 | CI/CD 阶段 | -| F7 FrontendAuditor | S7 Auditor | 规范审计、代码质量 | 提测前 | -| F8 FrontendRelease | S8 Release | 构建部署、版本管理 | 发布阶段 | -| F9 FrontendPerfTuner | S9 PerfTuner | 性能优化、监控指标 | 持续优化 | +| F1 FrontendAnalyzer | S1 Analyzer | 需求分析 | 页面设计与接口设计协调 | +| F2 FrontendArchitect | S2 Architect | 架构设计 | 整体架构与目录结构协调 | +| F3 FrontendInfraOperator | S3 InfraOperator | 基建接入 | 开发环境与工具链协调 | +| F4 FrontendDeveloper | S4 Developer | 功能开发 | 接口实现与页面开发协调 | +| F5 FrontendSecurityGuard | S5 SecurityGuard | 安全检查 | 前后端安全策略协调 | +| F6 FrontendQualityGate | S6 QualityGate | 质量门禁 | 代码质量与测试协调 | +| F7 FrontendAuditor | S7 Auditor | 规范审计 | 代码规范与标准协调 | +| F8 FrontendRelease | S8 Release | 发布部署 | 构建部署与版本协调 | +| F9 FrontendPerfTuner | S9 PerfTuner | 性能优化 | 性能指标与优化协调 | ## 协调检查点 -### 检查点 1:项目启动(F1 + S1) -```yaml -协调内容: - - 业务需求理解 - - 技术栈确认 - - 开发计划制定 - - API 接口规划 +### 1. 项目启动阶段 +**参与智能体**: F1 + S1 +**协调内容**: +- 业务需求分析与技术方案设计 +- 页面功能划分与 API 接口设计 +- 开发计划制定与里程碑设定 -输出产物: - - 需求文档 - - 技术方案 - - API 接口文档 - - 开发计划 -``` +**输出产物**: +- 需求分析文档 +- API 接口设计文档 +- 开发计划与时间安排 -### 检查点 2:架构设计(F2 + S2) -```yaml -协调内容: - - 系统架构设计 - - 数据模型设计 - - 组件结构设计 - - 接口定义 +### 2. 架构设计阶段 +**参与智能体**: F2 + S2 +**协调内容**: +- 整体架构设计与技术选型 +- 目录结构设计与模块划分 +- 数据流设计与状态管理方案 -输出产物: - - 架构设计文档 - - 数据模型文档 - - 组件设计文档 - - API 接口定义 -``` +**输出产物**: +- 架构设计文档 +- 目录结构规范 +- 数据流设计文档 -### 检查点 3:基建搭建(F3 + S3) -```yaml -协调内容: - - 开发环境配置 - - 工具链搭建 - - 基础组件开发 - - 数据库设计 +### 3. 基建接入阶段 +**参与智能体**: F3 + S3 +**协调内容**: +- 开发环境配置与工具链搭建 +- 依赖管理策略与版本控制 +- 构建流程设计与自动化配置 -输出产物: - - 开发环境配置 - - 工具链配置 - - 基础组件库 - - 数据库结构 -``` +**输出产物**: +- 开发环境配置文档 +- 工具链使用指南 +- 构建流程文档 -### 检查点 4:功能开发(F4 + S4) -```yaml -协调内容: - - API 接口开发 - - 前端页面开发 - - 接口联调 - - 功能测试 +### 4. 功能开发阶段 +**参与智能体**: F4 + S4 +**协调内容**: +- API 接口实现与前端页面开发 +- 数据交互逻辑与状态管理 +- 业务逻辑实现与用户体验 -输出产物: - - API 接口实现 - - 前端页面实现 - - 联调测试报告 - - 功能测试报告 -``` +**输出产物**: +- 功能模块代码 +- API 接口文档 +- 测试用例与测试报告 -### 检查点 5:质量保障(F5-F7 + S5-S7) -```yaml -协调内容: - - 安全检查 - - 代码质量检查 - - 测试覆盖率 - - 规范审计 +### 5. 质量保证阶段 +**参与智能体**: F5 + S5, F6 + S6 +**协调内容**: +- 安全策略实施与漏洞修复 +- 代码质量检查与测试覆盖 +- 性能指标监控与优化 -输出产物: - - 安全测试报告 - - 代码质量报告 - - 测试覆盖率报告 - - 规范审计报告 -``` +**输出产物**: +- 安全评估报告 +- 质量检查报告 +- 性能测试报告 -### 检查点 6:部署上线(F8 + S8) -```yaml -协调内容: - - 构建部署 - - 版本管理 - - 环境配置 - - 监控配置 +### 6. 规范审计阶段 +**参与智能体**: F7 + S7 +**协调内容**: +- 代码规范检查与标准对齐 +- 最佳实践实施与文档完善 +- 技术债务识别与重构计划 -输出产物: - - 构建产物 - - 部署配置 - - 版本说明 - - 监控配置 -``` +**输出产物**: +- 规范检查报告 +- 最佳实践文档 +- 重构计划与建议 -### 检查点 7:性能优化(F9 + S9) -```yaml -协调内容: - - 性能分析 - - 优化方案 - - 监控指标 - - 持续优化 +### 7. 发布部署阶段 +**参与智能体**: F8 + S8 +**协调内容**: +- 构建流程协调与版本管理 +- 部署策略制定与环境配置 +- 发布计划执行与回滚预案 -输出产物: - - 性能分析报告 - - 优化方案 - - 监控指标 - - 优化效果报告 -``` +**输出产物**: +- 构建产物与部署包 +- 部署配置文档 +- 发布计划与回滚预案 ## 协调工具 ### 1. API 契约管理 -```yaml -工具: OpenAPI/Swagger -用途: API 接口定义和文档 -协调: 前后端基于契约开发 -``` +- **OpenAPI/Swagger**: API 接口文档与类型定义 +- **TypeScript 类型生成**: 前端类型定义自动生成 +- **API 测试工具**: 接口测试与验证 -### 2. 代码仓库管理 -```yaml -工具: Git + GitLab/GitHub -用途: 代码版本管理 -协调: 分支策略、合并策略 -``` +### 2. 版本控制 +- **Git**: 代码版本控制与分支管理 +- **GitHub/GitLab**: 代码托管与协作平台 +- **Git Flow**: 分支策略与发布流程 -### 3. 持续集成/部署 -```yaml -工具: CI/CD Pipeline -用途: 自动化构建、测试、部署 -协调: 构建流程、测试流程 -``` +### 3. CI/CD 协调 +- **GitHub Actions/GitLab CI**: 自动化构建与测试 +- **Docker**: 容器化部署与环境一致性 +- **Kubernetes**: 容器编排与服务管理 ### 4. 项目管理 -```yaml -工具: Jira/禅道 -用途: 任务管理、进度跟踪 -协调: 任务分配、进度同步 -``` +- **Jira/ZenTao**: 需求管理与任务跟踪 +- **Confluence/Notion**: 文档管理与知识共享 +- **Slack/钉钉**: 即时沟通与通知 -### 5. 沟通协作 -```yaml -工具: 企业微信/钉钉 -用途: 实时沟通、问题讨论 -协调: 日常沟通、问题解决 -``` +### 5. 监控与反馈 +- **Sentry**: 错误监控与性能追踪 +- **Prometheus**: 指标监控与告警 +- **Grafana**: 数据可视化与报表 ## 协调流程 -### 1. 项目启动阶段 +### 1. 日常开发协调 ``` -1. 需求分析会议(F1 + S1) -2. 技术方案评审(F2 + S2) -3. 开发计划制定 -4. API 接口设计 +每日站会 → 任务分配 → 并行开发 → 代码审查 → 集成测试 → 部署验证 ``` -### 2. 开发阶段 +### 2. 版本发布协调 ``` -1. 基建搭建(F3 + S3) -2. 功能开发(F4 + S4) -3. 接口联调 -4. 功能测试 +需求冻结 → 功能开发 → 集成测试 → 预发布验证 → 正式发布 → 监控反馈 ``` -### 3. 质量保障阶段 +### 3. 问题处理协调 ``` -1. 安全检查(F5 + S5) -2. 质量检查(F6 + S6) -3. 规范审计(F7 + S7) -4. 问题修复 -``` - -### 4. 部署上线阶段 -``` -1. 构建部署(F8 + S8) -2. 环境验证 -3. 性能优化(F9 + S9) -4. 监控配置 +问题发现 → 影响评估 → 方案制定 → 并行修复 → 验证测试 → 部署上线 ``` ## 协调规范 ### 1. 沟通规范 -- **定期会议**:每周一次协调会议 -- **即时沟通**:重要问题即时沟通 -- **文档记录**:重要决策文档记录 -- **问题跟踪**:问题跟踪和解决 +- **定期同步**: 每日站会、周例会、里程碑评审 +- **异步沟通**: 使用文档、评论、邮件进行异步沟通 +- **紧急沟通**: 使用即时通讯工具进行紧急问题处理 -### 2. 代码规范 -- **代码风格**:统一的代码风格 -- **命名规范**:统一的命名规范 -- **注释规范**:统一的注释规范 -- **提交规范**:统一的提交规范 +### 2. 文档规范 +- **API 文档**: 使用 OpenAPI 规范,及时更新 +- **技术文档**: 使用 Markdown 格式,结构清晰 +- **变更日志**: 记录所有重要变更,便于追溯 -### 3. 测试规范 -- **测试覆盖**:统一的测试覆盖率要求 -- **测试类型**:单元测试、集成测试、e2e 测试 -- **测试环境**:统一的测试环境 -- **测试报告**:统一的测试报告格式 +### 3. 代码规范 +- **命名规范**: 前后端命名保持一致,使用业务术语 +- **注释规范**: 关键逻辑必须有注释,便于理解 +- **提交规范**: 使用规范的提交信息,便于版本管理 -### 4. 部署规范 -- **环境管理**:开发、测试、生产环境 -- **版本管理**:统一的版本管理策略 -- **回滚策略**:统一的回滚策略 -- **监控告警**:统一的监控告警策略 +### 4. 测试规范 +- **单元测试**: 前后端都要有充分的单元测试 +- **集成测试**: 前后端集成测试,确保接口正确 +- **端到端测试**: 完整的用户流程测试 -## 协调效果评估 +## 效果评估 -### 1. 开发效率 -- **开发周期**:项目开发周期 -- **代码质量**:代码质量指标 -- **测试覆盖**:测试覆盖率 -- **问题数量**:问题数量和解决时间 +### 1. 开发效率指标 +- **开发周期**: 从需求到上线的完整周期 +- **代码质量**: 缺陷密度、技术债务比例 +- **团队协作**: 沟通效率、冲突解决时间 -### 2. 协作效果 -- **沟通效率**:沟通效率和效果 -- **协调成本**:协调所需的时间和成本 -- **冲突解决**:冲突解决的速度和质量 -- **团队满意度**:团队满意度调查 +### 2. 产品质量指标 +- **功能完整性**: 需求实现程度、功能覆盖率 +- **性能指标**: 响应时间、吞吐量、资源使用 +- **用户体验**: 用户满意度、易用性评分 -### 3. 项目质量 -- **功能完整性**:功能实现完整性 -- **性能指标**:系统性能指标 -- **用户体验**:用户体验评价 -- **稳定性**:系统稳定性指标 +### 3. 运维指标 +- **部署频率**: 发布频率、部署成功率 +- **系统稳定性**: 可用性、故障恢复时间 +- **监控覆盖**: 监控覆盖率、告警准确性 ## 持续改进 ### 1. 定期回顾 -- **项目回顾**:项目结束后进行回顾 -- **流程优化**:根据回顾结果优化流程 -- **工具改进**:根据使用情况改进工具 -- **规范更新**:根据实践情况更新规范 +- **周回顾**: 每周进行开发回顾,识别改进点 +- **月回顾**: 每月进行项目回顾,评估整体效果 +- **季度回顾**: 每季度进行战略回顾,调整方向 -### 2. 经验总结 -- **最佳实践**:总结最佳实践 -- **问题案例**:总结问题案例和解决方案 -- **工具推荐**:推荐新的工具和方法 -- **培训计划**:制定培训计划 +### 2. 改进措施 +- **流程优化**: 根据回顾结果优化协调流程 +- **工具升级**: 引入新的工具提升协作效率 +- **技能提升**: 团队技能培训与知识分享 -### 3. 技术演进 -- **技术更新**:跟进技术更新 -- **架构演进**:架构演进规划 -- **工具升级**:工具升级计划 -- **标准更新**:标准更新计划 \ No newline at end of file +### 3. 最佳实践 +- **经验总结**: 总结成功经验,形成最佳实践 +- **案例分享**: 分享典型案例,促进团队学习 +- **标准制定**: 制定团队标准,确保一致性 \ No newline at end of file diff --git a/admin/docs/src/wwjcloud/ai/frontend-workflow.md b/admin/docs/src/wwjcloud/ai/frontend-workflow.md index 4317a0c..1c1575f 100644 --- a/admin/docs/src/wwjcloud/ai/frontend-workflow.md +++ b/admin/docs/src/wwjcloud/ai/frontend-workflow.md @@ -1,201 +1,425 @@ -# 前端多智能体工作流(Ant Design Vue) +# 前端多智能体工作流 (F1-F9) ## 智能体角色定义(按执行顺序标注) -### F1 前端需求分析体(FrontendAnalyzer) -- **职责**:解析前端需求、对应 Ant Design Vue 规范、输出组件设计与页面结构 -- **输入**:业务需求、UI/UX 设计稿、后端 API 接口 -- **输出**:页面结构图、组件树、路由配置、状态管理方案 +### F1 前端分析体(FrontendAnalyzer) +- **职责**: 解析前端需求、对应 Vben Admin 规范、输出页面结构与组件设计 +- **输入**: 业务需求、UI设计稿、后端API接口 +- **输出**: 页面划分、组件设计、路由配置、状态管理方案 +- **必做检查(M1 前置)**: + - 先阅读 `src/views/demos/` 中的示例,遵循演示的交互与代码风格 + - 严禁修改 `src/views/demos/` 下任何代码(仅可参考) + - 开发与改动范围仅限 `admin/apps/web-antd/src` 目录 +- **与 PHP 对齐(admin/site 双端)**: + - 明确模块是否在「管理端(admin)」还是「站点端(site)」呈现与操作 + - 功能“真值”以 PHP 页面为准:字段/交互/校验/约束先梳理清单,再对照 Vben 风格实现 -### F2 前端架构治理体(FrontendArchitect) -- **职责**:校验前端分层/目录规范,给出组件设计建议与边界清单 -- **校验**:目录结构、组件分层、状态管理、路由设计 -- **输出**:前端架构设计说明、组件接口定义、重构建议 +### F2 前端架构体(FrontendArchitect) +- **职责**: 校验目录结构、组件分层、依赖关系,给出架构建议 +- **输入**: 页面划分、组件设计 +- **输出**: 目录结构、组件分层、依赖方向、删除/迁移建议 +- **约束补充**: + - 页面骨架需与 demos 的交互与布局风格一致(Page + Grid/Toolbar + Drawer/Modal) + - 模块化目录与命名严格遵循 `src/views/{module}/` 规范 + - 区分 admin/site 的路由前缀与菜单归属;前端路由命名与 PHP 端保持语义一致 -### F3 前端基建接入体(FrontendInfraOperator) -- **职责**:接入/校验 Vben Admin 生态、状态管理、路由、国际化 -- **接入**:Pinia、Vue Router、i18n、Vben Hooks、组件库适配 -- **产物**:接入差异与示例代码,配置项校验清单 +### F3 前端基建体(FrontendInfraOperator) +- **职责**: 接入/校验 Vben Admin 生态、状态管理、路由配置 +- **输入**: 架构设计、依赖需求 +- **输出**: 基建配置、接入差异与示例代码 +- **规范工具(必须启动)**: + - 启动开发(基础校验随 Vite Dev 一起运行) + - pnpm -F @vben/web-antd run dev + - 持续类型检查(推荐独立终端常驻) + - pnpm -F @vben/web-antd run typecheck --watch + - 首轮规范修复(确保本地无明显规范问题再进入开发) + - pnpm -F @vben/web-antd run lint --fix + - pnpm -F @vben/web-antd run stylelint --fix + - pnpm -F @vben/web-antd run format +- **API 契约与映射策略**: + - 与后端 OpenAPI/Swagger 契约对齐;区分 admin `/adminapi` 与 site `/api` + - 若后端字段为 `snake_case`,前端统一 camelCase,映射集中在 API 层(不要在页面里散落转换) -### F4 前端开发执行体(FrontendDeveloper) -- **职责**:按规范编码、编写组件、修复构建 -- **实现**:页面组件、业务逻辑、API 调用、状态管理 -- **测试**:组件测试、页面测试、集成测试 +### F4 前端开发体(FrontendDeveloper) +- **职责**: 按规范编码、编写测试、修复构建 +- **输入**: 页面设计、组件设计、API接口 +- **输出**: 页面组件、业务逻辑、单元测试、构建通过 +- **UI 交互约定**: + - 简单单页/单步表单:可使用 Modal(或在 Drawer 内的单面板) + - 多 Tab/多步骤/复杂设置表单:统一使用 Drawer(抽屉)承载 + - 操作列统一使用 `CellOperation`;状态开关统一使用 `CellSwitch/CellTag` + - 页面框架统一 `Page + Grid`,工具栏使用 `#toolbar-tools` 槽位 +- **用户管理改造(admin/site 双端)**: + - 列表/筛选:id、用户名、状态、备注、创建时间(对齐 PHP 字段;前端统一 camelCase) + - 基础操作:新建/编辑/删除、启用/禁用(支持批量) + - 账号能力:重置密码、锁定/解锁(若 PHP 存在则对齐) + - 权限归属:分配角色(role)、部门选择(dept-tree) + - 资料与上传:头像上传、基础资料字段(email/mobile/avatar 等) + - 详情与表单:多 Tab 表单使用 Drawer;成功后刷新 `gridApi.query()` + - 路由与菜单:指向 admin 端;若 site 端也有用户自管页面,建立对应 site 路由并复用组件 -### F5 前端安全基线体(FrontendSecurityGuard) -- **职责**:检查权限控制、数据验证、XSS 防护 -- **检查**:路由守卫、按钮权限、表单验证、敏感信息处理 +### F5 前端安全体(FrontendSecurityGuard) +- **职责**: 检查权限控制、敏感信息暴露、XSS防护 +- **输入**: 页面组件、权限配置 +- **输出**: 安全检查报告、修复建议 +- **对齐要求**: + - 所有管理端页面需具备权限码与菜单守卫;敏感操作需二次确认 -### F6 前端质量门禁体(FrontendQualityGate) -- **职责**:聚合 ESLint/TS/覆盖率/e2e 结果,低于阈值阻断合并 -- **指标**:ESLint/TS 无报错、覆盖率≥阈值、e2e 关键路径通过 +### F6 前端质量体(FrontendQualityGate) +- **职责**: 聚合 ESLint/TS/覆盖率/e2e 结果,低于阈值阻断合并 +- **输入**: 代码质量指标 +- **输出**: 质量报告、阻断/通过决策 +- **规范工具校验(必过项)**: + - pnpm -F @vben/web-antd run typecheck + - pnpm -F @vben/web-antd run lint + - pnpm -F @vben/web-antd run stylelint + - pnpm -F @vben/web-antd run test (含 unit/component) + - pnpm -F @vben/web-antd run e2e(关键路径) +- **一致性核查**: + - 与 `src/views/demos` 风格逐项对齐;与 PHP 页面功能逐项对齐(以核对清单为准) -### F7 前端规范审计体(FrontendAuditor) -- **职责**:按清单逐项核查,出具差异报告与修复项 -- **检查**:组件规范、命名规范、代码风格、性能优化 +### F7 前端审计体(FrontendAuditor) +- **职责**: 按清单逐项核查,出具差异报告与修复项 +- **输入**: 代码规范、Vben Admin 标准 +- **输出**: 规范检查报告、修复任务清单 -### F8 前端构建部署体(FrontendRelease) -- **职责**:构建、变更说明、部署计划 -- **产出**:构建产物、变更日志、部署步骤 +### F8 前端发布体(FrontendRelease) +- **职责**: 构建、变更说明、部署计划 +- **输入**: 构建产物、变更日志 +- **输出**: 部署包、变更说明、部署步骤 -### F9 前端性能优化体(FrontendPerfTuner) -- **职责**:建议缓存/懒加载/代码分割,识别性能瓶颈 -- **优化**:组件懒加载、图片优化、包体积优化、渲染性能 +### F9 前端优化体(FrontendPerfTuner) +- **职责**: 建议缓存、懒加载、代码分割,识别性能瓶颈 +- **输入**: 性能指标、用户体验 +- **输出**: 优化建议、性能报告 -## 前后端智能体协调机制 +## 串联流程(带顺序) -### 协调流程(F1-F9 + S1-S9) +### 1) F1 FrontendAnalyzer +- **输入**: 业务需求/UI设计稿/后端API接口 +- **输出**: 页面划分、组件设计、路由配置、状态管理方案 +- **注意**: 先阅读 `src/views/demos/`,严禁修改 demos 代码,所有开发仅在 `src` 范围内完成 +- **PHP 对齐**: 先列出 admin/site 双端的用户管理差异清单(字段/交互/入口) -#### 阶段一:需求分析与架构设计(F1+F2 + S1+S2) -``` -F1 FrontendAnalyzer ←→ S1 Analyzer -├── 前端需求分析 ←→ 后端 API 设计 -├── 组件结构设计 ←→ 数据模型设计 -└── 状态管理方案 ←→ 业务逻辑设计 +### 2) F2 FrontendArchitect +- **校验**: 目录结构、组件分层、依赖方向 +- **输出**: 目录结构设计、组件分层方案、删除/迁移建议 +- **PHP 对齐**: 确认 admin 与 site 两端的路由/菜单归属与复用边界 -F2 FrontendArchitect ←→ S2 Architect -├── 前端架构设计 ←→ 后端架构设计 -├── 组件接口定义 ←→ API 接口定义 -└── 数据流设计 ←→ 数据流设计 -``` +### 3) F3 FrontendInfraOperator +- **接入**: Vben Admin 生态、状态管理、路由配置 +- **产物**: 基建配置、接入差异与示例代码 +- **并行启动规范工具**: + - dev + typecheck --watch(两个终端常驻) + - lint/stylelint/format 首轮修复 +- **API 契约**: 对齐 admin `/adminapi` 与 site `/api`,前端统一 camelCase,映射在 API 层 -#### 阶段二:基建接入与开发(F3+F4 + S3+S4) -``` -F3 FrontendInfraOperator ←→ S3 InfraOperator -├── 前端基建接入 ←→ 后端基建接入 -├── 组件库适配 ←→ 数据库/缓存接入 -└── 开发环境配置 ←→ 开发环境配置 +### 4) F4 FrontendDeveloper +- **实现**: 页面组件、业务逻辑、状态管理、路由配置 +- **测试**: 单元测试、组件测试、e2e测试 +- **构建**: 确保构建通过 +- **UI 交互约定**: 多 Tab 表单用 Drawer;简单表单可用 Modal -F4 FrontendDeveloper ←→ S4 Developer -├── 前端组件开发 ←→ 后端接口开发 -├── API 调用实现 ←→ API 接口实现 -└── 页面功能开发 ←→ 业务逻辑实现 -``` +### 5) F5 FrontendSecurityGuard(第一次,开发阶段) +- **检查**: 权限控制、敏感信息暴露、XSS防护 -#### 阶段三:质量保障与部署(F5-F9 + S5-S9) -``` -F5 FrontendSecurityGuard ←→ S5 SecurityGuard -├── 前端安全检查 ←→ 后端安全检查 -├── 权限控制实现 ←→ 权限控制实现 -└── 数据验证 ←→ 数据验证 +### 6) F6 FrontendQualityGate(CI 阶段) +- **指标**: ESLint/TS 无报错;覆盖率≥80%;e2e 关键路径通过 +- **动作**: 不达标阻断合并 +- **执行**: typecheck/lint/stylelint/test/e2e 均需通过;对照 PHP 页面核对功能完整性 -F6 FrontendQualityGate ←→ S6 QualityGate -├── 前端质量检查 ←→ 后端质量检查 -├── 代码规范检查 ←→ 代码规范检查 -└── 测试覆盖率 ←→ 测试覆盖率 +### 7) F7 FrontendAuditor(提测前) +- **检查**: 规范清单、Vben Admin 标准对齐 +- **产物**: 差异报告与修复任务 -F7 FrontendAuditor ←→ S7 Auditor -├── 前端规范审计 ←→ 后端规范审计 -├── 代码质量检查 ←→ 代码质量检查 -└── 架构合规性 ←→ 架构合规性 +### 8) F5 FrontendSecurityGuard(第二次,提测前) +- **复检**: 重要页面的权限控制、安全防护 -F8 FrontendRelease ←→ S8 Release -├── 前端构建部署 ←→ 后端构建部署 -├── 版本管理 ←→ 版本管理 -└── 部署协调 ←→ 部署协调 +### 9) F9 FrontendPerfTuner(并行/持续) +- **建议**: 缓存、懒加载、代码分割、性能优化 -F9 FrontendPerfTuner ←→ S9 PerfTuner -├── 前端性能优化 ←→ 后端性能优化 -├── 用户体验优化 ←→ 系统性能优化 -└── 监控指标 ←→ 监控指标 -``` +### 10) F8 FrontendRelease +- **产出**: 构建产物、变更日志、部署步骤 ## 前端开发规范 ### 目录结构规范 + ``` src/ -├── views/ # 页面组件 -│ ├── system/ # 系统管理模块 -│ ├── business/ # 业务模块 -│ └── _core/ # 核心页面 -├── components/ # 公共组件 -├── api/ # API 接口 -├── store/ # 状态管理 -├── router/ # 路由配置 -├── locales/ # 国际化 -├── utils/ # 工具函数 -└── adapter/ # 适配器层 +├── views/ # 页面目录 +│ ├── {module}/ # 功能模块目录(语义化命名) +│ │ ├── index.vue # 主页面(必须使用 Page 组件) +│ │ ├── data.ts # 数据配置 +│ │ └── modules/ # 子组件目录 +│ │ ├── form.vue # 表单组件 +│ │ ├── table.vue # 表格组件 +│ │ └── ... +│ └── demos/ # 示例页面目录 +│ ├── {feature}/ # 功能特性目录 +│ │ ├── index.vue # 主页面 +│ │ └── {sub}.vue # 子页面 +│ └── ... +├── api/ # API 接口目录 +│ ├── {module}/ # 按模块组织 +│ │ ├── index.ts # 模块 API 入口 +│ │ └── {feature}.ts # 具体功能 API +│ └── index.ts # API 总入口 +├── router/ # 路由配置 +│ ├── routes/ # 路由定义 +│ │ └── modules/ # 按模块组织 +│ └── index.ts # 路由入口 +├── locales/ # 多语言 +│ └── langs/ # 语言包 +├── adapter/ # 适配器 +│ ├── form.ts # 表单适配器 +│ └── vxe-table.ts # 表格适配器 +└── __tests__/ # 测试目录 + ├── e2e/ # 端到端测试 + ├── unit/ # 单元测试 + │ ├── components/ # 组件测试 + │ ├── views/ # 页面测试 + │ └── api/ # API 测试 + └── integration/ # 集成测试 ``` -### 组件开发规范 -- **命名规范**:PascalCase,语义化命名 -- **文件结构**:index.vue + data.ts + modules/ -- **组件设计**:单一职责、可复用、可测试 -- **状态管理**:使用 Pinia,按模块划分 +### 页面组件规范 -### API 调用规范 -- **接口定义**:使用 TypeScript 类型定义 -- **错误处理**:统一错误处理机制 -- **请求封装**:使用 Vben 的 request 工具 -- **数据转换**:前后端数据格式转换 +#### 主页面结构(必须使用 Page 组件) +```vue + -### 路由配置规范 -- **路由结构**:按模块组织,支持懒加载 -- **权限控制**:路由级权限控制 -- **面包屑**:自动生成面包屑导航 -- **缓存策略**:页面缓存配置 + +``` -## 前后端协调检查点 +#### 子页面结构 +```vue + -### 开发前协调 -- [ ] API 接口设计确认 -- [ ] 数据模型对齐 -- [ ] 权限控制方案 -- [ ] 错误处理机制 + +``` -### 开发中协调 -- [ ] API 接口联调 -- [ ] 数据格式验证 -- [ ] 权限控制测试 -- [ ] 错误处理测试 +#### 表单组件结构 +```vue + -### 开发后协调 -- [ ] 功能完整性测试 -- [ ] 性能测试 -- [ ] 安全测试 -- [ ] 部署协调 + +``` -## 工具与配置 +### 命名规范 + +#### 文件命名 +- **主页面**: 必须命名为 `index.vue` +- **子页面**: 使用 kebab-case,如 `button-control.vue` +- **组件文件**: 使用 kebab-case,如 `form.vue`、`table.vue` +- **API 文件**: 使用 kebab-case,如 `role.ts`、`menu.ts` + +#### 目录命名 +- **功能模块**: 使用语义化命名,如 `system`、`user`、`order` +- **子目录**: 使用语义化命名,如 `modules`、`components` + +#### 组件命名 +- **页面组件**: 使用 PascalCase,如 `RoleList`、`MenuForm` +- **业务组件**: 使用 PascalCase,如 `UserTable`、`OrderForm` + +### 测试规范 + +#### 测试目录结构 +``` +__tests__/ +├── e2e/ # 端到端测试 +│ └── {feature}.spec.ts # 功能测试 +├── unit/ # 单元测试 +│ ├── components/ # 组件测试 +│ │ └── {component}.spec.ts +│ ├── views/ # 页面测试 +│ │ └── {page}.spec.ts +│ └── api/ # API 测试 +│ └── {api}.spec.ts +└── integration/ # 集成测试 + └── {feature}.spec.ts +``` + +#### 测试覆盖率要求 +- **单元测试覆盖率**: ≥ 80% +- **组件测试覆盖率**: ≥ 90% +- **e2e 测试覆盖率**: 关键路径 100% + +### 代码质量规范 + +#### ESLint 规范 +- 必须通过 ESLint 检查 +- 禁止使用 `any` 类型 +- 必须使用 TypeScript 严格模式 + +#### TypeScript 规范 +- 必须通过类型检查 +- 必须定义接口和类型 +- 禁止使用 `@ts-ignore` + +#### 组件规范 +- 必须使用 `