From 1dec1972934d41b553293d4e35cd12bb50703934 Mon Sep 17 00:00:00 2001 From: zhangzhe Date: Wed, 4 Feb 2026 10:37:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .kiro/steering/development-standards.md | 202 +++++++++-- .../scripts/seed_business_menus.sql | 321 ++++++++++++++++++ 2 files changed, 503 insertions(+), 20 deletions(-) create mode 100644 server/MiAssessment/scripts/seed_business_menus.sql diff --git a/.kiro/steering/development-standards.md b/.kiro/steering/development-standards.md index b6aa188..517d9cd 100644 --- a/.kiro/steering/development-standards.md +++ b/.kiro/steering/development-standards.md @@ -2,27 +2,60 @@ 本文档定义了 MiAssessment 项目的开发规范和编码标准,所有开发工作必须遵循这些规范。 +## 项目概述 + +学业邑规划是一个基于多元智能理论的学业规划测评系统,包含微信小程序和后台管理系统。 + +### 相关文档 + +- 需求文档: `docs/需求文档.md` +- 数据库设计: `docs/数据库设计文档.md` +- 开发文档: `docs/开发文档.md` +- 题库资料: `docs/题库和结论/` +- UI 设计图: `docs/设计图/` +- UI 切图: `docs/切图/` + ## 一、技术栈 | 层级 | 技术 | -|---|---| +|------|------| | 后端框架 | .NET 10 Web API (C#) | | 数据库 | SQL Server 2022 | | ORM | Entity Framework Core | | 缓存 | Redis | | 接口风格 | RPC 风格(仅 GET / POST 请求) | -| 前端 | UniApp + Vue 3 + TypeScript | +| 小程序前端 | UniApp + Vue 3 + TypeScript | +| 后台管理前端 | Vue 3 + TypeScript + Vite | ## 二、项目结构 +### 整体结构 + +``` +mi-assessment/ +├── docs/ # 文档资料 +│ ├── 需求文档.md +│ ├── 数据库设计文档.md +│ ├── 开发文档.md +│ ├── 开发规范/ # 详细编码规范 +│ ├── 设计图/ # UI 设计图 +│ ├── 切图/ # UI 切图资源 +│ └── 题库和结论/ # 测评题库与报告模板 +├── server/MiAssessment/ # 后端服务 +└── uniapp/ # 小程序前端 +``` + +### 后端项目结构 + ``` server/MiAssessment/src/ -├── MiAssessment.Api/ # 小程序 API 接口 -├── MiAssessment.Admin/ # 后台管理系统基础模块 -├── MiAssessment.Admin.Business/ # 后台业务模块(主要开发区域) -├── MiAssessment.Core/ # 核心业务逻辑 -├── MiAssessment.Infrastructure/ # 基础设施 -└── MiAssessment.Model/ # 数据模型 +├── MiAssessment.Api/ # 小程序 API 接口 +├── MiAssessment.Admin/ # 后台管理系统基础模块 +│ └── admin-web/ # 后台管理前端 (Vue 3) +├── MiAssessment.Admin.Business/ # 后台业务模块(主要开发区域) +├── MiAssessment.Core/ # 核心业务逻辑 +├── MiAssessment.Infrastructure/ # 基础设施 +└── MiAssessment.Model/ # 数据模型 ``` ### Admin.Business 项目结构 @@ -45,7 +78,7 @@ MiAssessment.Admin.Business/ ### 3.1 数据库命名 | 类型 | 规范 | 示例 | -|---|---|---| +|------|------|------| | 表名 | snake_case(小写下划线) | `users`, `assessment_records` | | 字段名 | PascalCase | `UserId`, `CreateTime` | | 主键 | `Id` (bigint 自增) | `Id` | @@ -57,7 +90,7 @@ MiAssessment.Admin.Business/ ### 3.2 C# 代码命名 | 类型 | 规范 | 示例 | -|---|---|---| +|------|------|------| | 命名空间 | PascalCase | `MiAssessment.Admin.Business.Services` | | 类名 | PascalCase | `UserService`, `OrderController` | | 接口 | I + PascalCase | `IUserService`, `IOrderService` | @@ -70,13 +103,25 @@ MiAssessment.Admin.Business/ ### 3.3 文件命名 | 类型 | 规范 | 示例 | -|---|---|---| +|------|------|------| | 实体类 | 单数形式 | `User.cs`, `Order.cs` | | 服务接口 | I + 服务名 | `IUserService.cs` | | 服务实现 | 服务名 | `UserService.cs` | | 控制器 | 模块名 + Controller | `UserController.cs` | | DTO 模型 | 功能 + Request/Dto | `CreateUserRequest.cs`, `UserDto.cs` | +### 3.4 前端命名 (Vue/TypeScript) + +| 类型 | 规范 | 示例 | +|------|------|------| +| 组件文件 | PascalCase | `UserList.vue`, `OrderDetail.vue` | +| 组合式函数 | use + camelCase | `useUserList.ts`, `useAuth.ts` | +| 工具函数 | camelCase | `formatDate.ts`, `request.ts` | +| 类型定义 | PascalCase | `UserInfo`, `OrderStatus` | +| 变量/函数 | camelCase | `userList`, `handleSubmit` | +| 常量 | UPPER_SNAKE_CASE | `API_BASE_URL`, `MAX_PAGE_SIZE` | +| CSS 类名 | kebab-case | `user-list`, `order-card` | + ## 四、代码规范 ### 4.1 实体类规范 @@ -263,11 +308,12 @@ public class UserController : BusinessControllerBase ### 5.2 路由规范 ``` -/api/admin/{module}/{action} +小程序 API: /api/{module}/{action} +后台管理 API: /api/admin/{module}/{action} ``` | 操作 | 方法 | 路由示例 | -|---|---|---| +|------|------|----------| | 获取列表 | GET | `/api/admin/user/getList` | | 获取详情 | GET | `/api/admin/user/getDetail?id=1` | | 创建 | POST | `/api/admin/user/create` | @@ -309,7 +355,7 @@ public class UserController : BusinessControllerBase ## 六、错误码规范 | 范围 | 说明 | -|---|---| +|------|------| | 0 | 成功 | | 1000-1999 | 通用错误 | | 2000-2999 | 业务错误 | @@ -324,7 +370,7 @@ public class UserController : BusinessControllerBase ## 七、注释规范 -### 7.1 XML 注释 +### 7.1 XML 注释 (C#) 所有公开的类、方法、属性必须有 XML 注释: @@ -337,7 +383,20 @@ public class UserController : BusinessControllerBase public async Task> GetUserListAsync(UserQueryRequest request) ``` -### 7.2 代码注释 +### 7.2 JSDoc 注释 (TypeScript) + +```typescript +/** + * 获取用户列表 + * @param params 查询参数 + * @returns 分页用户列表 + */ +export async function getUserList(params: UserQueryParams): Promise> { + // ... +} +``` + +### 7.3 代码注释 - 使用中文注释 - 复杂逻辑需要添加说明注释 @@ -387,14 +446,14 @@ await _dbContext.SaveChangesAsync(); ### 9.1 通用状态 | 值 | 说明 | -|---|---| +|----|------| | 0 | 禁用/下线 | | 1 | 启用/正常 | ### 9.2 订单状态 | 值 | 说明 | -|---|---| +|----|------| | 1 | 待支付 | | 2 | 已支付 | | 3 | 已完成 | @@ -405,7 +464,7 @@ await _dbContext.SaveChangesAsync(); ### 9.3 用户等级 | 值 | 说明 | -|---|---| +|----|------| | 1 | 普通用户 | | 2 | 合伙人 | | 3 | 渠道合伙人 | @@ -456,7 +515,7 @@ public Property PaginationReturnsCorrectCount() ### 11.2 Type 类型 | Type | 说明 | -|---|---| +|------|------| | feat | 新功能 | | fix | 修复 bug | | docs | 文档更新 | @@ -474,3 +533,106 @@ feat(user): 添加用户列表分页查询功能 - 支持按手机号、昵称筛选 - 添加分页参数验证 ``` + +## 十二、前端开发规范 + +### 12.1 Vue 组件规范 + +```vue + + + + + +``` + +### 12.2 API 请求规范 + +```typescript +// api/user.ts +import request from '@/utils/request' +import type { UserDto, UserQueryParams, PagedResult } from '@/types' + +/** + * 获取用户列表 + */ +export function getUserList(params: UserQueryParams) { + return request.get>('/api/admin/user/getList', { params }) +} + +/** + * 更新用户状态 + */ +export function updateUserStatus(id: number, status: number) { + return request.post('/api/admin/user/updateStatus', { id, status }) +} +``` + +### 12.3 类型定义规范 + +```typescript +// types/user.ts + +/** 用户信息 */ +export interface UserDto { + id: number + uid: string + nickname: string + phone: string + status: number + createTime: string +} + +/** 用户查询参数 */ +export interface UserQueryParams { + page?: number + pageSize?: number + phone?: string + status?: number +} +``` diff --git a/server/MiAssessment/scripts/seed_business_menus.sql b/server/MiAssessment/scripts/seed_business_menus.sql new file mode 100644 index 0000000..af31f2f --- /dev/null +++ b/server/MiAssessment/scripts/seed_business_menus.sql @@ -0,0 +1,321 @@ +-- ============================================= +-- Business Module Menus Seed Script +-- 学业邑规划 - MiAssessment +-- +-- This script inserts business module menus +-- into the Admin database menus table +-- +-- Database: SQL Server 2022 +-- Run after: init_admin_db.sql, seed_business_permissions.sql +-- ============================================= + +USE [MiAssessment_Admin]; +GO + +PRINT N'Seeding business module menus...'; + +-- ============================================= +-- Get max menu ID to avoid conflicts +-- ============================================= +DECLARE @maxMenuId INT; +SELECT @maxMenuId = ISNULL(MAX([Id]), 0) FROM [dbo].[menus]; +PRINT N'Current max menu ID: ' + CAST(@maxMenuId AS NVARCHAR(10)); + +-- ============================================= +-- 1. 数据统计 (Dashboard) +-- ============================================= +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/dashboard') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'数据统计', '/dashboard', 'dashboard/index', 'dashboard', 2, 'dashboard:view', 0, 1, GETDATE()); + PRINT N'Inserted menu: 数据统计'; +END + +-- ============================================= +-- 2. 测评管理 (Assessment) +-- ============================================= +DECLARE @assessmentMenuId BIGINT; + +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/assessment') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'测评管理', '/assessment', 'Layout', 'education', 1, NULL, 3, 1, GETDATE()); + SET @assessmentMenuId = SCOPE_IDENTITY(); + PRINT N'Inserted menu: 测评管理'; +END +ELSE +BEGIN + SELECT @assessmentMenuId = [Id] FROM [dbo].[menus] WHERE [Path] = '/assessment'; +END + +-- 测评类型 +IF @assessmentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/assessment/type') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@assessmentMenuId, N'测评类型', '/assessment/type', 'assessment/type/index', 'list', 2, 'assessment:view', 1, 1, GETDATE()); + PRINT N'Inserted menu: 测评类型'; +END + +-- 题库管理 +IF @assessmentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/assessment/question') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@assessmentMenuId, N'题库管理', '/assessment/question', 'assessment/question/index', 'edit-pen', 2, 'assessment:view', 2, 1, GETDATE()); + PRINT N'Inserted menu: 题库管理'; +END + +-- 报告分类 +IF @assessmentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/assessment/category') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@assessmentMenuId, N'报告分类', '/assessment/category', 'assessment/category/index', 'tree', 2, 'assessment:view', 3, 1, GETDATE()); + PRINT N'Inserted menu: 报告分类'; +END + +-- 报告结论 +IF @assessmentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/assessment/conclusion') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@assessmentMenuId, N'报告结论', '/assessment/conclusion', 'assessment/conclusion/index', 'document', 2, 'assessment:view', 4, 1, GETDATE()); + PRINT N'Inserted menu: 报告结论'; +END + +-- 测评记录 +IF @assessmentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/assessment/record') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@assessmentMenuId, N'测评记录', '/assessment/record', 'assessment/record/index', 'tickets', 2, 'assessment:view', 5, 1, GETDATE()); + PRINT N'Inserted menu: 测评记录'; +END + +-- ============================================= +-- 3. 订单管理 (Order) +-- ============================================= +DECLARE @orderMenuId BIGINT; + +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/order') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'订单管理', '/order', 'Layout', 'shopping-cart', 1, NULL, 4, 1, GETDATE()); + SET @orderMenuId = SCOPE_IDENTITY(); + PRINT N'Inserted menu: 订单管理'; +END +ELSE +BEGIN + SELECT @orderMenuId = [Id] FROM [dbo].[menus] WHERE [Path] = '/order'; +END + +-- 订单列表 +IF @orderMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/order/list') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@orderMenuId, N'订单列表', '/order/list', 'order/list/index', 'list', 2, 'order:view', 1, 1, GETDATE()); + PRINT N'Inserted menu: 订单列表'; +END + +-- 退款管理 +IF @orderMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/order/refund') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@orderMenuId, N'退款管理', '/order/refund', 'order/refund/index', 'money', 2, 'order:view', 2, 1, GETDATE()); + PRINT N'Inserted menu: 退款管理'; +END + +-- ============================================= +-- 4. 规划师管理 (Planner) +-- ============================================= +DECLARE @plannerMenuId BIGINT; + +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/planner') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'规划师管理', '/planner', 'Layout', 'avatar', 1, NULL, 5, 1, GETDATE()); + SET @plannerMenuId = SCOPE_IDENTITY(); + PRINT N'Inserted menu: 规划师管理'; +END +ELSE +BEGIN + SELECT @plannerMenuId = [Id] FROM [dbo].[menus] WHERE [Path] = '/planner'; +END + +-- 规划师列表 +IF @plannerMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/planner/list') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@plannerMenuId, N'规划师列表', '/planner/list', 'planner/list/index', 'user', 2, 'planner:view', 1, 1, GETDATE()); + PRINT N'Inserted menu: 规划师列表'; +END + +-- 预约记录 +IF @plannerMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/planner/booking') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@plannerMenuId, N'预约记录', '/planner/booking', 'planner/booking/index', 'calendar', 2, 'planner:view', 2, 1, GETDATE()); + PRINT N'Inserted menu: 预约记录'; +END + +-- ============================================= +-- 5. 分销管理 (Distribution) +-- ============================================= +DECLARE @distributionMenuId BIGINT; + +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/distribution') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'分销管理', '/distribution', 'Layout', 'share', 1, NULL, 6, 1, GETDATE()); + SET @distributionMenuId = SCOPE_IDENTITY(); + PRINT N'Inserted menu: 分销管理'; +END +ELSE +BEGIN + SELECT @distributionMenuId = [Id] FROM [dbo].[menus] WHERE [Path] = '/distribution'; +END + +-- 邀请码管理 +IF @distributionMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/distribution/invite-code') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@distributionMenuId, N'邀请码管理', '/distribution/invite-code', 'distribution/invite-code/index', 'ticket', 2, 'distribution:view', 1, 1, GETDATE()); + PRINT N'Inserted menu: 邀请码管理'; +END + +-- 佣金记录 +IF @distributionMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/distribution/commission') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@distributionMenuId, N'佣金记录', '/distribution/commission', 'distribution/commission/index', 'coin', 2, 'distribution:view', 2, 1, GETDATE()); + PRINT N'Inserted menu: 佣金记录'; +END + +-- 提现管理 +IF @distributionMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/distribution/withdrawal') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@distributionMenuId, N'提现管理', '/distribution/withdrawal', 'distribution/withdrawal/index', 'wallet', 2, 'distribution:view', 3, 1, GETDATE()); + PRINT N'Inserted menu: 提现管理'; +END + +-- ============================================= +-- 6. 内容管理 (Content) +-- ============================================= +DECLARE @contentMenuId BIGINT; + +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/content') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'内容管理', '/content', 'Layout', 'picture', 1, NULL, 7, 1, GETDATE()); + SET @contentMenuId = SCOPE_IDENTITY(); + PRINT N'Inserted menu: 内容管理'; +END +ELSE +BEGIN + SELECT @contentMenuId = [Id] FROM [dbo].[menus] WHERE [Path] = '/content'; +END + +-- 轮播图管理 +IF @contentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/content/banner') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@contentMenuId, N'轮播图管理', '/content/banner', 'content/banner/index', 'picture', 2, 'content:view', 1, 1, GETDATE()); + PRINT N'Inserted menu: 轮播图管理'; +END + +-- 宣传图管理 +IF @contentMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/content/promotion') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@contentMenuId, N'宣传图管理', '/content/promotion', 'content/promotion/index', 'picture-filled', 2, 'content:view', 2, 1, GETDATE()); + PRINT N'Inserted menu: 宣传图管理'; +END + +-- ============================================= +-- 7. 系统配置 (Config) - 业务配置 +-- ============================================= +DECLARE @configMenuId BIGINT; + +IF NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/config') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (0, N'业务配置', '/config', 'Layout', 'setting', 1, NULL, 8, 1, GETDATE()); + SET @configMenuId = SCOPE_IDENTITY(); + PRINT N'Inserted menu: 业务配置'; +END +ELSE +BEGIN + SELECT @configMenuId = [Id] FROM [dbo].[menus] WHERE [Path] = '/config'; +END + +-- 基础配置 +IF @configMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/config/basic') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@configMenuId, N'基础配置', '/config/basic', 'config/basic/index', 'tools', 2, 'config:view', 1, 1, GETDATE()); + PRINT N'Inserted menu: 基础配置'; +END + +-- 支付配置 +IF @configMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/config/payment') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@configMenuId, N'支付配置', '/config/payment', 'config/payment/index', 'credit-card', 2, 'config:view', 2, 1, GETDATE()); + PRINT N'Inserted menu: 支付配置'; +END + +-- 分销配置 +IF @configMenuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[menus] WHERE [Path] = '/config/distribution') +BEGIN + INSERT INTO [dbo].[menus] ([ParentId], [Name], [Path], [Component], [Icon], [MenuType], [Permission], [SortOrder], [Status], [CreatedAt]) + VALUES (@configMenuId, N'分销配置', '/config/distribution', 'config/distribution/index', 'share', 2, 'config:view', 3, 1, GETDATE()); + PRINT N'Inserted menu: 分销配置'; +END + +-- ============================================= +-- 8. Assign new menus to Super Admin Role (RoleId = 1) +-- ============================================= +PRINT N'Assigning new menus to super_admin role...'; + +INSERT INTO [dbo].[role_menus] ([RoleId], [MenuId]) +SELECT 1, m.[Id] +FROM [dbo].[menus] m +WHERE NOT EXISTS ( + SELECT 1 FROM [dbo].[role_menus] rm + WHERE rm.[RoleId] = 1 AND rm.[MenuId] = m.[Id] +); + +PRINT N'New menus assigned to super_admin role'; +GO + +-- ============================================= +-- Verify inserted menus +-- ============================================= +PRINT N''; +PRINT N'Business module menus seeded successfully!'; +PRINT N''; + +SELECT + m.[Id], + m.[ParentId], + m.[Name], + m.[Path], + m.[Component], + m.[Icon], + CASE m.[MenuType] + WHEN 1 THEN N'目录' + WHEN 2 THEN N'菜单' + WHEN 3 THEN N'按钮' + END AS [MenuType], + m.[Permission], + m.[SortOrder], + m.[Status] +FROM [dbo].[menus] m +WHERE m.[Path] IN ( + '/dashboard', + '/assessment', '/assessment/type', '/assessment/question', '/assessment/category', '/assessment/conclusion', '/assessment/record', + '/order', '/order/list', '/order/refund', + '/planner', '/planner/list', '/planner/booking', + '/distribution', '/distribution/invite-code', '/distribution/commission', '/distribution/withdrawal', + '/content', '/content/banner', '/content/promotion', + '/config', '/config/basic', '/config/payment', '/config/distribution' +) +ORDER BY m.[SortOrder], m.[ParentId], m.[Id]; +GO