diff --git a/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/CreateAdminUserRequest.cs b/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/CreateAdminUserRequest.cs
index c546a5c..9da5769 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/CreateAdminUserRequest.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/CreateAdminUserRequest.cs
@@ -24,10 +24,15 @@ public class CreateAdminUserRequest
public string Password { get; set; } = null!;
///
- /// 真实姓名
+ /// 真实姓名(为空时自动转 null)
///
[MaxLength(50, ErrorMessage = "真实姓名最多50个字符")]
- public string? RealName { get; set; }
+ public string? RealName
+ {
+ get => _realName;
+ set => _realName = string.IsNullOrWhiteSpace(value) ? null : value;
+ }
+ private string? _realName;
///
/// 头像URL
@@ -36,17 +41,27 @@ public class CreateAdminUserRequest
public string? Avatar { get; set; }
///
- /// 邮箱
+ /// 邮箱(为空时跳过格式验证)
///
[MaxLength(100, ErrorMessage = "邮箱最多100个字符")]
[EmailAddress(ErrorMessage = "邮箱格式不正确")]
- public string? Email { get; set; }
+ public string? Email
+ {
+ get => _email;
+ set => _email = string.IsNullOrWhiteSpace(value) ? null : value;
+ }
+ private string? _email;
///
- /// 手机号
+ /// 手机号(为空时自动转 null)
///
[MaxLength(20, ErrorMessage = "手机号最多20个字符")]
- public string? Phone { get; set; }
+ public string? Phone
+ {
+ get => _phone;
+ set => _phone = string.IsNullOrWhiteSpace(value) ? null : value;
+ }
+ private string? _phone;
///
/// 部门ID
diff --git a/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/UpdateAdminUserRequest.cs b/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/UpdateAdminUserRequest.cs
index 04895bc..5b56211 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/UpdateAdminUserRequest.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin/Models/AdminUser/UpdateAdminUserRequest.cs
@@ -8,10 +8,15 @@ namespace MiAssessment.Admin.Models.AdminUser;
public class UpdateAdminUserRequest
{
///
- /// 真实姓名
+ /// 真实姓名(为空时自动转 null)
///
[MaxLength(50, ErrorMessage = "真实姓名最多50个字符")]
- public string? RealName { get; set; }
+ public string? RealName
+ {
+ get => _realName;
+ set => _realName = string.IsNullOrWhiteSpace(value) ? null : value;
+ }
+ private string? _realName;
///
/// 头像URL
@@ -20,17 +25,27 @@ public class UpdateAdminUserRequest
public string? Avatar { get; set; }
///
- /// 邮箱
+ /// 邮箱(为空时跳过格式验证)
///
[MaxLength(100, ErrorMessage = "邮箱最多100个字符")]
[EmailAddress(ErrorMessage = "邮箱格式不正确")]
- public string? Email { get; set; }
+ public string? Email
+ {
+ get => _email;
+ set => _email = string.IsNullOrWhiteSpace(value) ? null : value;
+ }
+ private string? _email;
///
- /// 手机号
+ /// 手机号(为空时自动转 null)
///
[MaxLength(20, ErrorMessage = "手机号最多20个字符")]
- public string? Phone { get; set; }
+ public string? Phone
+ {
+ get => _phone;
+ set => _phone = string.IsNullOrWhiteSpace(value) ? null : value;
+ }
+ private string? _phone;
///
/// 部门ID
diff --git a/server/MiAssessment/src/MiAssessment.Admin/Services/AdminUserService.cs b/server/MiAssessment/src/MiAssessment.Admin/Services/AdminUserService.cs
index 6c88de6..0a5a54a 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/Services/AdminUserService.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin/Services/AdminUserService.cs
@@ -15,15 +15,17 @@ public class AdminUserService : IAdminUserService
private readonly AdminDbContext _dbContext;
private readonly ILogger _logger;
private readonly IAuthService _authService;
+ private readonly IPermissionService _permissionService;
// 超级管理员角色编码
private const string SuperAdminRoleCode = "super_admin";
- public AdminUserService(AdminDbContext dbContext, ILogger logger, IAuthService authService)
+ public AdminUserService(AdminDbContext dbContext, ILogger logger, IAuthService authService, IPermissionService permissionService)
{
_dbContext = dbContext;
_logger = logger;
_authService = authService;
+ _permissionService = permissionService;
}
///
@@ -310,6 +312,7 @@ public class AdminUserService : IAdminUserService
}
await _dbContext.SaveChangesAsync();
+ _permissionService.InvalidateCache(userId);
_logger.LogInformation("管理员 {UserId} 分配角色成功,角色数量: {Count}", userId, roleIds.Count);
}
@@ -353,6 +356,10 @@ public class AdminUserService : IAdminUserService
}
await _dbContext.SaveChangesAsync();
+
+ // 清除用户权限缓存,使新菜单权限立即生效
+ _permissionService.InvalidateCache(userId);
+
_logger.LogInformation("管理员 {UserId} 分配用户专属菜单成功,菜单数量: {Count}", userId, menuIds.Count);
}
diff --git a/server/MiAssessment/src/MiAssessment.Admin/Services/PermissionService.cs b/server/MiAssessment/src/MiAssessment.Admin/Services/PermissionService.cs
index 9dd2a03..e5d941e 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/Services/PermissionService.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin/Services/PermissionService.cs
@@ -212,14 +212,71 @@ public class PermissionService : IPermissionService
var roleIds = userRoles.Select(ur => ur.RoleId).ToList();
- // 获取角色关联的权限
- var permissions = await _dbContext.RolePermissions
+ // 1. 获取角色关联的权限(permissions 表)
+ var rolePermissions = await _dbContext.RolePermissions
.Where(rp => roleIds.Contains(rp.RoleId))
.Include(rp => rp.Permission)
.Select(rp => rp.Permission.Code)
.Distinct()
.ToListAsync();
- return permissions;
+ // 2. 收集角色关联的菜单 ID
+ var roleMenuIds = await _dbContext.RoleMenus
+ .Where(rm => roleIds.Contains(rm.RoleId))
+ .Select(rm => rm.MenuId)
+ .Distinct()
+ .ToListAsync();
+
+ // 3. 收集用户专属菜单 ID
+ var userMenuIds = await _dbContext.AdminUserMenus
+ .Where(um => um.AdminUserId == adminUserId)
+ .Select(um => um.MenuId)
+ .Distinct()
+ .ToListAsync();
+
+ // 4. 合并所有菜单 ID,并递归查找所有子菜单
+ var allMenuIds = roleMenuIds.Concat(userMenuIds).Distinct().ToHashSet();
+ var allChildMenuIds = await GetAllChildMenuIdsAsync(allMenuIds);
+ allMenuIds.UnionWith(allChildMenuIds);
+
+ // 5. 从所有菜单中提取权限标识
+ var menuPermissions = await _dbContext.Set()
+ .Where(m => allMenuIds.Contains(m.Id) && m.Permission != null && m.Permission != "")
+ .Select(m => m.Permission!)
+ .Distinct()
+ .ToListAsync();
+
+ // 合并所有权限
+ var allPermissions = rolePermissions
+ .Concat(menuPermissions)
+ .Distinct()
+ .ToList();
+
+ return allPermissions;
+ }
+
+ ///
+ /// 递归获取所有子菜单 ID
+ ///
+ private async Task> GetAllChildMenuIdsAsync(HashSet parentIds)
+ {
+ var result = new HashSet();
+ var currentParentIds = parentIds;
+
+ while (currentParentIds.Count > 0)
+ {
+ var childIds = await _dbContext.Set()
+ .Where(m => currentParentIds.Contains(m.ParentId))
+ .Select(m => m.Id)
+ .ToListAsync();
+
+ var newIds = childIds.Where(id => !result.Contains(id) && !parentIds.Contains(id)).ToHashSet();
+ if (newIds.Count == 0) break;
+
+ result.UnionWith(newIds);
+ currentParentIds = newIds;
+ }
+
+ return result;
}
}
diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/operationLog.ts b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/operationLog.ts
index 729b33a..c63cd05 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/operationLog.ts
+++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/operationLog.ts
@@ -2,28 +2,29 @@ import { request, type ApiResponse, type PagedResult } from '@/utils/request'
export interface OperationLog {
id: number
- userId: number
- username: string
- module: string
- action: string
- method: string
- url: string
- params: string | null
+ adminUserId: number | null
+ username: string | null
+ module: string | null
+ action: string | null
+ method: string | null
+ url: string | null
ip: string | null
- userAgent: string | null
- duration: number
+ requestData: string | null
+ responseData: string | null
status: number
- errorMessage: string | null
+ errorMsg: string | null
+ duration: number
createdAt: string
}
export interface OperationLogQuery {
- keyword?: string
- module?: string
- startDate?: string
- endDate?: string
page: number
pageSize: number
+ username?: string
+ module?: string
+ status?: number
+ startDate?: string
+ endDate?: string
}
// 获取操作日志列表
@@ -35,7 +36,7 @@ export function getOperationLogList(params: OperationLogQuery): Promise> {
return request({
url: `/admin/logs/${id}`,
diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/router/index.ts b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/router/index.ts
index 78078a7..ab7f8ec 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/router/index.ts
+++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/router/index.ts
@@ -10,7 +10,7 @@ export { businessRoutes, type RouteMeta, getBusinessPermissions, filterRoutesByP
const constantRoutes: RouteRecordRaw[] = [
{
path: '/',
- redirect: '/dashboard'
+ redirect: '/dashboard' // 默认值,登录后会被动态路由覆盖
},
{
path: '/login',
@@ -60,6 +60,23 @@ const router = createRouter({
// 白名单路由
const whiteList = ['/login', '/404']
+/**
+ * 递归获取用户有权限的第一个可访问页面路径
+ */
+function getFirstAccessiblePath(routes: RouteRecordRaw[], parentPath = ''): string | null {
+ for (const route of routes) {
+ const fullPath = parentPath ? `${parentPath}/${route.path}`.replace(/\/+/g, '/') : route.path
+ // 有 component 且不是 Layout 的就是叶子页面
+ if (route.children && route.children.length > 0) {
+ const childPath = getFirstAccessiblePath(route.children, fullPath)
+ if (childPath) return childPath
+ } else if (route.component) {
+ return fullPath
+ }
+ }
+ return null
+}
+
// 标记动态路由是否已加载
let dynamicRoutesLoaded = false
@@ -94,6 +111,11 @@ router.beforeEach(async (to, _from, next) => {
accessRoutes.forEach(route => {
router.addRoute(route)
})
+ // 动态设置首页重定向到用户有权限的第一个页面
+ const firstRoute = getFirstAccessiblePath(accessRoutes)
+ if (firstRoute) {
+ router.addRoute({ path: '/', redirect: firstRoute })
+ }
// 添加 404 兜底路由
router.addRoute({ path: '/:pathMatch(.*)*', redirect: '/404' })
// 标记动态路由已加载
diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts
index 70fba6b..82b609d 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts
+++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts
@@ -123,6 +123,11 @@ async function handle401Error(error: any): Promise {
// Don't retry if already retried or if it's a refresh request
if (originalConfig._retry || isWhiteListUrl(originalConfig.url)) {
+ // 白名单接口(如登录)的 401 错误,直接显示后端返回的错误信息
+ const msg = error.response?.data?.message
+ if (msg) {
+ ElMessage.error(msg)
+ }
return Promise.reject(error)
}
diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/system/user/index.vue b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/system/user/index.vue
index 7ecb73b..2ddc4c0 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/system/user/index.vue
+++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/system/user/index.vue
@@ -161,7 +161,6 @@
show-checkbox
node-key="id"
:default-checked-keys="checkedMenuIds"
- :check-strictly="true"
/>
取消
@@ -304,6 +303,25 @@ const passwordRules: FormRules = {
]
}
+/**
+ * 过滤出叶子节点 ID,用于树组件回显(非 check-strictly 模式)
+ */
+function filterLeafMenuIds(tree: MenuTree[], checkedIds: number[]): number[] {
+ const result: number[] = []
+ const idSet = new Set(checkedIds)
+ function walk(nodes: MenuTree[]) {
+ for (const node of nodes) {
+ if (node.children && node.children.length > 0) {
+ walk(node.children)
+ } else if (idSet.has(node.id)) {
+ result.push(node.id)
+ }
+ }
+ }
+ walk(tree)
+ return result
+}
+
const fetchData = async () => {
loading.value = true
try {
@@ -372,11 +390,18 @@ const handleSubmit = async () => {
submitLoading.value = true
try {
+ // 非必填字段:空字符串转 null,避免后端格式验证失败
+ const submitData = {
+ ...formData,
+ realName: formData.realName || null,
+ email: formData.email || null,
+ phone: formData.phone || null
+ }
if (isEdit.value) {
- await updateAdminUser(formData.id, formData)
+ await updateAdminUser(submitData.id, submitData)
ElMessage.success('更新成功')
} else {
- await createAdminUser(formData)
+ await createAdminUser(submitData)
ElMessage.success('创建成功')
}
dialogVisible.value = false
@@ -446,14 +471,20 @@ const handleSubmitDepartment = async () => {
const handleAssignMenu = async (row: AdminUser) => {
currentUserId.value = row.id
const res = await getUserMenus(row.id)
- checkedMenuIds.value = res.data
+ // 去掉 check-strictly 后,回显时只设置叶子节点 ID,避免父节点导致子节点全选
+ const allIds: number[] = res.data
+ const leafIds = filterLeafMenuIds(menuTree.value, allIds)
+ checkedMenuIds.value = leafIds
menuDialogVisible.value = true
}
const handleSubmitMenus = async () => {
menuSubmitLoading.value = true
try {
- const menuIds = menuTreeRef.value?.getCheckedKeys(false) as number[]
+ const menuIds = [
+ ...(menuTreeRef.value?.getCheckedKeys(false) as number[]),
+ ...(menuTreeRef.value?.getHalfCheckedKeys() as number[])
+ ]
await assignUserMenus({ userId: currentUserId.value, menuIds })
ElMessage.success('分配成功')
menuDialogVisible.value = false
diff --git a/temp_menu29.txt b/temp_menu29.txt
new file mode 100644
index 0000000..0de290e
--- /dev/null
+++ b/temp_menu29.txt
@@ -0,0 +1 @@
+{"code":0,"message":"success","data":{"id":29,"parentId":28,"name":"用户列表","path":"/user/list","component":"business/user/index","icon":"peoples","menuType":2,"permission":"user:view","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"createdAt":"2026-02-03T17:32:15.877","updatedAt":"2026-04-19T20:22:50.107"}}
diff --git a/temp_menus.json b/temp_menus.json
new file mode 100644
index 0000000..d186772
--- /dev/null
+++ b/temp_menus.json
@@ -0,0 +1 @@
+{"code":0,"message":"success","data":[{"id":34,"parentId":0,"name":"数据统计","path":"/dashboard","component":"dashboard/index","icon":"home-filled","menuType":2,"permission":"dashboard:view","sortOrder":0,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":28,"parentId":0,"name":"用户管理","path":"/user","component":"Layout","icon":"user","menuType":1,"permission":null,"sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[{"id":29,"parentId":28,"name":"用户列表","path":"/user/list","component":"business/user/index","icon":"peoples","menuType":2,"permission":"user:list","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[{"id":30,"parentId":29,"name":"详情","path":null,"component":null,"icon":null,"menuType":3,"permission":"user:detail","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":31,"parentId":29,"name":"编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"user:edit","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":32,"parentId":29,"name":"禁用","path":null,"component":null,"icon":null,"menuType":3,"permission":"user:disable","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]}]}]},{"id":35,"parentId":0,"name":"测评管理","path":"/assessment","component":"Layout","icon":"document","menuType":1,"permission":null,"sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[{"id":36,"parentId":35,"name":"测评类型","path":"/assessment/type","component":"business/assessment/type/index","icon":"list","menuType":2,"permission":"assessment:view","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":37,"parentId":35,"name":"题库管理","path":"/assessment/question","component":"business/assessment/question/index","icon":"edit-pen","menuType":2,"permission":"assessment:view","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":38,"parentId":35,"name":"报告分类","path":"/assessment/category","component":"business/assessment/category/index","icon":"tree","menuType":2,"permission":"assessment:view","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":39,"parentId":35,"name":"报告结论","path":"/assessment/conclusion","component":"business/assessment/conclusion/index","icon":"document","menuType":2,"permission":"assessment:view","sortOrder":4,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":10003,"parentId":35,"name":"评分标准","path":"/assessment/scoreOption","component":"business/assessment/scoreOption/index","icon":"star","menuType":2,"permission":"assessment:view","sortOrder":5,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":10005,"parentId":35,"name":"测评记录","path":"/assessment/record","component":"business/assessment/record/index","icon":"tickets","menuType":2,"permission":"assessmentRecord:view","sortOrder":6,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":10006,"parentId":35,"name":"报告页面配置","path":"/assessment/report-page-config","component":"business/assessment/report-page-config/index","icon":null,"menuType":2,"permission":"assessment:view","sortOrder":7,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":40,"parentId":0,"name":"订单管理","path":"/order","component":"Layout","icon":"shopping-cart","menuType":1,"permission":null,"sortOrder":4,"status":1,"isExternal":false,"isCache":true,"children":[{"id":41,"parentId":40,"name":"订单列表","path":"/order/list","component":"business/order/index","icon":"list","menuType":2,"permission":"order:view","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":42,"parentId":0,"name":"规划师管理","path":"/planner","component":"Layout","icon":"avatar","menuType":1,"permission":null,"sortOrder":5,"status":1,"isExternal":false,"isCache":true,"children":[{"id":43,"parentId":42,"name":"规划师列表","path":"/planner/list","component":"business/planner/index","icon":"user","menuType":2,"permission":"planner:view","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":44,"parentId":42,"name":"预约记录","path":"/planner/booking","component":"business/planner/booking/index","icon":"calendar","menuType":2,"permission":"planner:view","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":45,"parentId":0,"name":"分销管理","path":"/distribution","component":"Layout","icon":"share","menuType":1,"permission":null,"sortOrder":6,"status":1,"isExternal":false,"isCache":true,"children":[{"id":46,"parentId":45,"name":"邀请码管理","path":"/distribution/invite-code","component":"business/distribution/invite-code/index","icon":"ticket","menuType":2,"permission":"distribution:view","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":47,"parentId":45,"name":"佣金记录","path":"/distribution/commission","component":"business/distribution/commission/index","icon":"coin","menuType":2,"permission":"distribution:view","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":48,"parentId":45,"name":"提现管理","path":"/distribution/withdrawal","component":"business/distribution/withdrawal/index","icon":"wallet","menuType":2,"permission":"distribution:view","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":49,"parentId":0,"name":"内容管理","path":"/content","component":"Layout","icon":"picture","menuType":1,"permission":null,"sortOrder":7,"status":1,"isExternal":false,"isCache":true,"children":[{"id":50,"parentId":49,"name":"轮播图管理","path":"/content/banner","component":"business/content/banner/index","icon":"picture","menuType":2,"permission":"content:view","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":51,"parentId":49,"name":"宣传图管理","path":"/content/promotion","component":"business/content/promotion/index","icon":"picture-filled","menuType":2,"permission":"content:view","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":10001,"parentId":49,"name":"业务介绍页","path":"/content/business-page","component":"business/content/business-page/index","icon":null,"menuType":2,"permission":"content:view","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":10004,"parentId":49,"name":"首页导航管理","path":"/content/navigation","component":"business/content/navigation/index","icon":"guide","menuType":2,"permission":"content:view","sortOrder":4,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":1,"parentId":0,"name":"系统管理","path":"/system","component":"Layout","icon":"setting","menuType":1,"permission":null,"sortOrder":8,"status":1,"isExternal":false,"isCache":true,"children":[{"id":2,"parentId":1,"name":"管理员管理","path":"/system/admin","component":"system/user/index","icon":"user","menuType":2,"permission":"system:admin:list","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[{"id":3,"parentId":2,"name":"新增","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:admin:add","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":4,"parentId":2,"name":"编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:admin:edit","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":5,"parentId":2,"name":"删除","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:admin:delete","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":6,"parentId":1,"name":"角色管理","path":"/system/role","component":"system/role/index","icon":"peoples","menuType":2,"permission":"system:role:list","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[{"id":7,"parentId":6,"name":"新增","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:role:add","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":8,"parentId":6,"name":"编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:role:edit","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":9,"parentId":6,"name":"删除","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:role:delete","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":10,"parentId":1,"name":"菜单管理","path":"/system/menu","component":"system/menu/index","icon":"tree-table","menuType":2,"permission":"system:menu:list","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[{"id":11,"parentId":10,"name":"新增","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:menu:add","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":12,"parentId":10,"name":"编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:menu:edit","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":13,"parentId":10,"name":"删除","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:menu:delete","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":14,"parentId":1,"name":"部门管理","path":"/system/dept","component":"system/department/index","icon":"tree","menuType":2,"permission":"system:dept:list","sortOrder":4,"status":1,"isExternal":false,"isCache":true,"children":[{"id":15,"parentId":14,"name":"新增","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dept:add","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":16,"parentId":14,"name":"编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dept:edit","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":17,"parentId":14,"name":"删除","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dept:delete","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":18,"parentId":1,"name":"字典管理","path":"/system/dict","component":"system/dict/index","icon":"dict","menuType":2,"permission":"system:dict:type:list","sortOrder":5,"status":1,"isExternal":false,"isCache":true,"children":[{"id":19,"parentId":18,"name":"类型新增","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dict:type:add","sortOrder":1,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":20,"parentId":18,"name":"类型编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dict:type:edit","sortOrder":2,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":21,"parentId":18,"name":"类型删除","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dict:type:delete","sortOrder":3,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":22,"parentId":18,"name":"数据新增","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dict:item:add","sortOrder":4,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":23,"parentId":18,"name":"数据编辑","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dict:item:edit","sortOrder":5,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":24,"parentId":18,"name":"数据删除","path":null,"component":null,"icon":null,"menuType":3,"permission":"system:dict:item:delete","sortOrder":6,"status":1,"isExternal":false,"isCache":true,"children":[]}]},{"id":53,"parentId":1,"name":"系统配置","path":"/system/config","component":"business/config/index","icon":"Setting","menuType":2,"permission":null,"sortOrder":6,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":27,"parentId":1,"name":"操作日志","path":"/system/log","component":"system/log/index","icon":"log","menuType":2,"permission":"system:log:list","sortOrder":7,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":52,"parentId":1,"name":"上传配置","path":"/system/upload-config","component":"system/config/upload","icon":"Upload","menuType":2,"permission":null,"sortOrder":8,"status":1,"isExternal":false,"isCache":true,"children":[]},{"id":10002,"parentId":1,"name":"运营配置","path":"/system/ops-config","component":"system/config/index","icon":"Setting","menuType":2,"permission":"system:config:edit","sortOrder":9,"status":1,"isExternal":false,"isCache":true,"children":[]}]}]}
diff --git a/temp_test_menus.txt b/temp_test_menus.txt
new file mode 100644
index 0000000..4761ae6
--- /dev/null
+++ b/temp_test_menus.txt
@@ -0,0 +1 @@
+{"code":0,"message":"success","data":[28,29,30,31,32,34,35,36,37]}
diff --git a/uniapp/manifest.json b/uniapp/manifest.json
index 3c79348..a51ec41 100644
--- a/uniapp/manifest.json
+++ b/uniapp/manifest.json
@@ -1,6 +1,6 @@
{
"name" : "学业邑规划",
- "appid" : "__UNI__1BAACAB",
+ "appid" : "__UNI__A612028",
"description" : "",
"versionName" : "1.0.1",
"versionCode" : 101,
diff --git a/uniapp/pages/assessment/info/index.vue b/uniapp/pages/assessment/info/index.vue
index 8ddd357..b0a983e 100644
--- a/uniapp/pages/assessment/info/index.vue
+++ b/uniapp/pages/assessment/info/index.vue
@@ -653,6 +653,7 @@
+