From f22200c965b69e9158913ed93e5f7cb7a00eaa54 Mon Sep 17 00:00:00 2001 From: green <2624612302@qq.com> Date: Thu, 27 Nov 2025 10:34:00 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-druid.yml | 118 +++---- .../src/views/psychology/permission/index.vue | 288 ++++++++++++++++-- 2 files changed, 320 insertions(+), 86 deletions(-) diff --git a/ry-xinli-admin/src/main/resources/application-druid.yml b/ry-xinli-admin/src/main/resources/application-druid.yml index 2127354c..4cd2e570 100644 --- a/ry-xinli-admin/src/main/resources/application-druid.yml +++ b/ry-xinli-admin/src/main/resources/application-druid.yml @@ -1,61 +1,61 @@ # 数据源配置 spring: - datasource: - type: com.alibaba.druid.pool.DruidDataSource - driverClassName: com.mysql.cj.jdbc.Driver - druid: - # 主库数据源 - master: - url: jdbc:mysql://127.0.0.1:3306/ry_xinli?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true - username: ry_xinli - password: ZLZBcfGtsWJe5r4z - # 从库数据源 - slave: - # 从数据源开关/默认关闭 - enabled: false - url: - username: - password: - # 初始连接数 - initialSize: 10 - # 最小连接池数量 - minIdle: 20 - # 最大连接池数量 - maxActive: 100 - # 配置获取连接等待超时的时间(减少到20秒,快速失败) - maxWait: 20000 - # 配置连接超时时间 - connectTimeout: 10000 - # 配置网络超时时间 - socketTimeout: 30000 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - timeBetweenEvictionRunsMillis: 60000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - minEvictableIdleTimeMillis: 300000 - # 配置一个连接在池中最大生存的时间,单位是毫秒 - maxEvictableIdleTimeMillis: 900000 - # 配置检测连接是否有效 - validationQuery: SELECT 1 FROM DUAL - testWhileIdle: true - testOnBorrow: false - testOnReturn: false - webStatFilter: - enabled: true - statViewServlet: - enabled: true - # 设置白名单,不填则允许所有访问(生产环境必须配置!) - allow: 127.0.0.1,192.168.0.0/16 - url-pattern: /druid/* - # 控制台管理用户名和密码(重要:生产环境必须修改) - login-username: ddnai_admin - login-password: Ddnai@2025#Druid - filter: - stat: - enabled: true - # 慢SQL记录 - log-slow-sql: true - slow-sql-millis: 1000 - merge-sql: true - wall: - config: - multi-statement-allow: true + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://1.15.149.240:3306/ry_xinli?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + username: ry_xinli + password: ZLZBcfGtsWJe5r4z + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问(生产环境必须配置!) + allow: 127.0.0.1,192.168.0.0/16 + url-pattern: /druid/* + # 控制台管理用户名和密码(重要:生产环境必须修改) + login-username: ddnai_admin + login-password: Ddnai@2025#Druid + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true diff --git a/xinli-ui/src/views/psychology/permission/index.vue b/xinli-ui/src/views/psychology/permission/index.vue index 13dc458e..f214590c 100644 --- a/xinli-ui/src/views/psychology/permission/index.vue +++ b/xinli-ui/src/views/psychology/permission/index.vue @@ -102,39 +102,50 @@ /> - + - - - - +
+ + + + + + + + + + +
- - - - + @focus="showUserSelectDialog = true"> + 选择 +
- 提示:可输入姓名或账号搜索,支持多选。留空表示所有用户。 + 提示:留空表示所有用户。点击"选择"按钮可按信息编号、姓名、监区筛选用户。
@@ -170,6 +181,71 @@ 取 消
+ + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + + + + + + + + + + @@ -179,6 +255,8 @@ import { listScale } from "@/api/psychology/scale"; import { allocatedUserList } from "@/api/system/role"; import { listRole } from "@/api/system/role"; import { getUser } from "@/api/system/user"; +import { listProfile } from "@/api/psychology/profile"; +import { deptTreeSelect } from "@/api/system/user"; export default { name: "PsyScalePermission", @@ -200,6 +278,8 @@ export default { permissionList: [], // 量表列表 scaleList: [], + // 量表搜索关键词 + scaleSearchKeyword: "", // 用户列表(用于下拉框显示) userOptions: [], // 用户搜索加载状态 @@ -210,6 +290,24 @@ export default { title: "", // 是否显示弹出层 open: false, + // 是否显示用户选择对话框 + showUserSelectDialog: false, + // 用户选择相关 + userSelectList: [], + userSelectTotal: 0, + userSelectLoading: false, + selectedUserIds: [], + // 部门选项 + deptOptions: [], + // 用户查询参数 + userQueryParams: { + pageNum: 1, + pageSize: 10, + infoNumber: undefined, + userName: undefined, + deptId: undefined, + status: '0' + }, // 查询参数 queryParams: { pageNum: 1, @@ -231,10 +329,60 @@ export default { } }; }, + computed: { + // 过滤后的量表列表 + filteredScaleList() { + if (!this.scaleSearchKeyword) { + return this.scaleList; + } + const keyword = this.scaleSearchKeyword.toLowerCase(); + return this.scaleList.filter(scale => { + const scaleName = (scale.scaleName || '').toLowerCase(); + const scaleCode = (scale.scaleCode || '').toLowerCase(); + return scaleName.includes(keyword) || scaleCode.includes(keyword); + }); + }, + // 选中用户的显示文本 + selectedUserDisplay() { + const userIds = this.form.userIds || []; + if (userIds.length === 0) { + return ""; + } else if (userIds.length === 1) { + const user = this.userOptions.find(u => u.userId === userIds[0]); + return user ? (user.nickName ? `${user.nickName}(${user.userName})` : user.userName) : ""; + } else { + return `已选择 ${userIds.length} 个用户`; + } + } + }, + watch: { + // 监听用户选择对话框打开 + showUserSelectDialog(val) { + if (val) { + // 打开对话框时加载用户列表 + this.resetUserQuery(); + this.selectedUserIds = [...(this.form.userIds || [])]; + this.getUserSelectList().then(() => { + // 确保已选中的用户被选中 + this.$nextTick(() => { + if (this.form.userIds && this.form.userIds.length > 0 && this.$refs.userTable) { + this.form.userIds.forEach(userId => { + const row = this.userSelectList.find(u => u.userId === userId); + if (row) { + this.$refs.userTable.toggleRowSelection(row, true); + } + }); + } + }); + }); + } + } + }, created() { this.getList(); this.loadScales(); this.loadUsers(); + this.loadDeptTree(); }, methods: { /** 查询权限列表 */ @@ -345,6 +493,88 @@ export default { console.error("获取学员角色ID失败:", error); }); }, + /** 加载部门树 */ + loadDeptTree() { + deptTreeSelect().then(response => { + this.deptOptions = response.data || []; + }); + }, + /** 量表行点击 */ + handleScaleRowClick(row) { + this.form.scaleId = row.scaleId; + }, + /** 量表选择改变 */ + handleScaleChange(scale) { + this.form.scaleId = scale.scaleId; + }, + /** 获取用户选择列表 */ + getUserSelectList() { + this.userSelectLoading = true; + // 使用用户档案接口查询,支持信息编号、姓名、监区筛选 + const query = { + pageNum: this.userQueryParams.pageNum, + pageSize: this.userQueryParams.pageSize, + infoNumber: this.userQueryParams.infoNumber, + userName: this.userQueryParams.userName, + deptId: this.userQueryParams.deptId, + status: this.userQueryParams.status + }; + return listProfile(query).then(response => { + this.userSelectList = (response.rows || []).map(profile => ({ + userId: profile.userId, + infoNumber: profile.infoNumber, + userName: profile.userName, + userAccount: profile.infoNumber, // 使用信息编号作为账号显示 + deptName: profile.deptName, + status: profile.status || '0' + })); + this.userSelectTotal = response.total || 0; + this.userSelectLoading = false; + return response; + }).catch(() => { + this.userSelectLoading = false; + return Promise.reject(); + }); + }, + /** 用户查询 */ + handleUserQuery() { + this.userQueryParams.pageNum = 1; + this.getUserSelectList(); + }, + /** 重置用户查询 */ + resetUserQuery() { + this.resetForm("userQueryForm"); + this.userQueryParams = { + pageNum: 1, + pageSize: 10, + infoNumber: undefined, + userName: undefined, + deptId: undefined, + status: '0' + }; + this.handleUserQuery(); + }, + /** 用户选择改变 */ + handleUserSelectionChange(selection) { + this.selectedUserIds = selection.map(item => item.userId); + }, + /** 确认用户选择 */ + handleConfirmUserSelect() { + // 更新 form.userIds + this.form.userIds = [...this.selectedUserIds]; + // 确保选中的用户在 userOptions 中 + this.selectedUserIds.forEach(userId => { + const user = this.userSelectList.find(u => u.userId === userId); + if (user && !this.userOptions.find(u => u.userId === userId)) { + this.userOptions.push({ + userId: user.userId, + userName: user.userAccount || user.userName, + nickName: user.userName + }); + } + }); + this.showUserSelectDialog = false; + }, /** 搜索用户(远程搜索) */ searchUsers(keyword) { if (!this.studentRoleId) { @@ -545,6 +775,8 @@ export default { _permissionIds: undefined, // 存储所有相关的权限ID(用于编辑时删除) _groupKey: undefined // 分组key }; + this.scaleSearchKeyword = ""; + this.selectedUserIds = []; this.resetForm("form"); }, /** 搜索按钮操作 */ @@ -574,6 +806,7 @@ export default { /** 新增按钮操作 */ handleAdd() { this.reset(); + this.scaleSearchKeyword = ""; // 确保 userOptions 有初始数据 if (this.userOptions.length === 0) { this.searchUsers(""); @@ -584,6 +817,7 @@ export default { /** 修改按钮操作 */ handleUpdate(row) { this.reset(); + this.scaleSearchKeyword = ""; // 汇总后的记录包含多个权限ID,需要加载所有相关的权限记录 const permissionIds = row.permissionIds || (row.permissionId ? [row.permissionId] : []); From ef8c79f59f27a7861b4d508c41acd15c9d63ee15 Mon Sep 17 00:00:00 2001 From: green <2624612302@qq.com> Date: Thu, 27 Nov 2025 11:37:33 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../psychology/PsyUserProfileServiceImpl.java | 16 ++++++++-------- xinli-ui/src/views/psychology/profile/index.vue | 16 ++++++++++------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java index bae52304..5c9caea5 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java @@ -121,14 +121,14 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService profile.setInfoNumber(infoNumber); validateInfoNumberUnique(infoNumber, null); - // 验证姓名:如果提供,只能包含汉字 + // 验证姓名:如果提供,只能包含汉字和数字 if (StringUtils.isNotEmpty(profile.getUserName())) { String userName = profile.getUserName().trim(); - if (!userName.matches("^[\\u4e00-\\u9fa5]+$")) + if (!userName.matches("^[\\u4e00-\\u9fa5\\d]+$")) { - log.error("创建用户档案失败:姓名格式错误,只能输入汉字,userName: {}", userName); - throw new ServiceException("姓名只能输入汉字"); + log.error("创建用户档案失败:姓名格式错误,只能输入汉字和数字,userName: {}", userName); + throw new ServiceException("姓名只能输入汉字和数字"); } profile.setUserName(userName); } @@ -289,14 +289,14 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService profile.setInfoNumber(infoNumber); validateInfoNumberUnique(infoNumber, profile.getProfileId()); - // 验证姓名:如果提供,只能包含汉字 + // 验证姓名:如果提供,只能包含汉字和数字 if (StringUtils.isNotEmpty(profile.getUserName())) { String userName = profile.getUserName().trim(); - if (!userName.matches("^[\\u4e00-\\u9fa5]+$")) + if (!userName.matches("^[\\u4e00-\\u9fa5\\d]+$")) { - log.error("修改用户档案失败:姓名格式错误,只能输入汉字,userName: {}", userName); - throw new ServiceException("姓名只能输入汉字"); + log.error("修改用户档案失败:姓名格式错误,只能输入汉字和数字,userName: {}", userName); + throw new ServiceException("姓名只能输入汉字和数字"); } profile.setUserName(userName); syncUserName(profile.getUserId(), userName); diff --git a/xinli-ui/src/views/psychology/profile/index.vue b/xinli-ui/src/views/psychology/profile/index.vue index a39e87c4..f143a116 100644 --- a/xinli-ui/src/views/psychology/profile/index.vue +++ b/xinli-ui/src/views/psychology/profile/index.vue @@ -183,7 +183,10 @@ - + + + * 信息编号 + @@ -288,7 +291,7 @@ @@ -480,11 +483,12 @@ export default { { required: true, message: "档案类型不能为空", trigger: "change" } ], infoNumber: [ + { required: true, message: "信息编号不能为空", trigger: "blur" }, { pattern: /^\d+$/, message: "信息编号只能输入数字", trigger: "blur" } ], userName: [ { required: true, message: "罪犯姓名不能为空", trigger: "blur" }, - { pattern: /^[\u4e00-\u9fa5]+$/, message: "姓名只能输入汉字", trigger: "blur" } + { pattern: /^[\u4e00-\u9fa5\d]+$/, message: "姓名只能输入汉字和数字", trigger: "blur" } ], prison: [ { required: true, message: "监狱不能为空", trigger: "blur" } @@ -753,8 +757,8 @@ export default { }, // 处理姓名输入,只允许汉字 handleUserNameInput(value) { - // 移除所有非汉字字符 - this.form.userName = value.replace(/[^\u4e00-\u9fa5]/g, '') + // 移除所有非汉字和非数字字符 + this.form.userName = value.replace(/[^\u4e00-\u9fa5\d]/g, '') }, /** 搜索按钮操作 */ handleQuery() { From ef2f7da6361c9693590ce5d0ab42023e02c61706 Mon Sep 17 00:00:00 2001 From: green <2624612302@qq.com> Date: Thu, 27 Nov 2025 18:12:23 +0800 Subject: [PATCH 3/6] 1127bug --- .../psychology/PsyAssessmentController.java | 31 +- .../psychology/PsyScaleController.java | 40 ++- .../psychology/PsyUserProfileController.java | 12 + .../system/domain/dto/ImportProgress.java | 150 ++++++++++ .../domain/psychology/PsyScalePermission.java | 15 + .../psychology/PsyScalePermissionMapper.java | 7 + .../PsyScalePermissionServiceImpl.java | 63 ++-- .../psychology/PsyUserProfileServiceImpl.java | 53 +++- .../IPsyScalePermissionService.java | 7 + .../psychology/IPsyUserProfileService.java | 9 + .../support/ImportProgressManager.java | 130 +++++++++ .../system/psychology/PsyAssessmentMapper.xml | 8 +- .../psychology/PsyScalePermissionMapper.xml | 11 +- .../psychology/PsyUserProfileMapper.xml | 7 +- xinli-ui/src/api/psychology/assessment.js | 5 +- xinli-ui/src/api/psychology/profile.js | 8 + .../src/views/psychology/assessment/index.vue | 10 +- .../src/views/psychology/assessment/start.vue | 40 ++- .../views/psychology/assessment/taking.vue | 44 ++- .../src/views/psychology/permission/index.vue | 249 +++++++++++++--- .../src/views/psychology/profile/index.vue | 255 ++++++++++++++-- .../views/psychology/questionnaire/index.vue | 2 +- .../views/psychology/report/comprehensive.vue | 271 ++++++++++++++---- xinli-ui/src/views/psychology/scale/index.vue | 13 +- xinli-ui/src/views/student/tests.vue | 76 ++++- xinli-ui/src/views/system/user/index.vue | 147 +++++----- xinli-ui/vue.config.js | 2 +- 27 files changed, 1392 insertions(+), 273 deletions(-) create mode 100644 ry-xinli-system/src/main/java/com/ddnai/system/domain/dto/ImportProgress.java create mode 100644 ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/support/ImportProgressManager.java diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java index 17d426b0..edaf179c 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyAssessmentController.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.ddnai.common.annotation.Log; import com.ddnai.common.core.controller.BaseController; @@ -36,7 +37,6 @@ import com.ddnai.system.service.psychology.IPsyAssessmentService; import com.ddnai.system.service.psychology.IPsyAssessmentAnswerService; import com.ddnai.system.service.psychology.IPsyScaleItemService; import java.util.ArrayList; -import java.math.BigDecimal; /** * 测评记录 信息操作处理 @@ -87,10 +87,33 @@ public class PsyAssessmentController extends BaseController * 获取暂停的测评列表 */ @GetMapping("/pausedList") - public AjaxResult pausedList() + public AjaxResult pausedList(@RequestParam(value = "userId", required = false) Long userId) { - Long userId = SecurityUtils.getUserId(); - List list = assessmentService.selectPausedAssessmentList(userId); + Long currentUserId = SecurityUtils.getUserId(); + boolean hasManagePerm = false; + try + { + hasManagePerm = SecurityUtils.hasPermi("psychology:assessment:list"); + } + catch (Exception ignored) + { + } + + Long targetUserId = null; + if (userId != null) + { + if (!userId.equals(currentUserId) && !hasManagePerm) + { + return error("无权查看其他用户的暂停测评记录"); + } + targetUserId = userId; + } + else if (!hasManagePerm) + { + targetUserId = currentUserId; + } + + List list = assessmentService.selectPausedAssessmentList(targetUserId); return success(list); } diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyScaleController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyScaleController.java index 28d678dc..1c21c75d 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyScaleController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyScaleController.java @@ -1,7 +1,6 @@ package com.ddnai.web.controller.psychology; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -74,6 +73,7 @@ public class PsyScaleController extends BaseController public TableDataInfo list(PsyScale scale, @RequestParam(required = false, defaultValue = "true") Boolean includeQuestionnaire) { Set allowedScaleIds = resolveAllowedScaleIdsForCurrentUser(); + Set restrictedScaleIds = resolveRestrictedScaleIds(); boolean needPermissionFilter = allowedScaleIds != null; // 如果需要包含问卷,需要先查询所有数据,合并后再分页 @@ -91,7 +91,7 @@ public class PsyScaleController extends BaseController } } - scaleList = filterScaleListByPermission(scaleList, allowedScaleIds); + scaleList = filterScaleListByPermission(scaleList, allowedScaleIds, restrictedScaleIds); // 查询问卷列表(不分页,因为需要合并后再分页) PsyQuestionnaire questionnaireQuery = new PsyQuestionnaire(); @@ -119,7 +119,7 @@ public class PsyScaleController extends BaseController scaleList.add(scaleItem); } - scaleList = filterScaleListByPermission(scaleList, allowedScaleIds); + scaleList = filterScaleListByPermission(scaleList, allowedScaleIds, restrictedScaleIds); // 按排序顺序和创建时间排序 scaleList.sort((a, b) -> { @@ -157,7 +157,7 @@ public class PsyScaleController extends BaseController } } - scaleList = filterScaleListByPermission(scaleList, allowedScaleIds); + scaleList = filterScaleListByPermission(scaleList, allowedScaleIds, restrictedScaleIds); if (needPermissionFilter) { @@ -193,7 +193,6 @@ public class PsyScaleController extends BaseController scale.setRemark(questionnaire.getRemark()); return scale; } - /** * 构建手动分页结果,适用于自定义过滤后的列表 */ @@ -224,7 +223,7 @@ public class PsyScaleController extends BaseController * @param scaleList 原始列表 * @param allowedScaleIds null表示无需过滤;非null表示仅可访问允许集合中的量表 */ - private List filterScaleListByPermission(List scaleList, Set allowedScaleIds) + private List filterScaleListByPermission(List scaleList, Set allowedScaleIds, Set restrictedScaleIds) { if (allowedScaleIds == null || scaleList == null) { @@ -238,13 +237,16 @@ public class PsyScaleController extends BaseController continue; } String sourceType = scale.getSourceType(); + Long scaleId = scale.getScaleId(); if ("questionnaire".equalsIgnoreCase(sourceType)) { - // 问卷类型默认对所有学员开放 - filtered.add(scale); - continue; + boolean restricted = restrictedScaleIds != null && restrictedScaleIds.contains(scaleId); + if (!restricted) + { + filtered.add(scale); + continue; + } } - Long scaleId = scale.getScaleId(); if (scaleId != null && allowedScaleIds.contains(scaleId)) { filtered.add(scale); @@ -585,6 +587,24 @@ public class PsyScaleController extends BaseController } } } + + private Set resolveRestrictedScaleIds() + { + try + { + List ids = scalePermissionService.selectAllScaleIdsWithPermission(); + if (ids == null || ids.isEmpty()) + { + return java.util.Collections.emptySet(); + } + return new java.util.HashSet<>(ids); + } + catch (Exception e) + { + logger.warn("解析量表权限限制列表失败: {}", e.getMessage()); + return java.util.Collections.emptySet(); + } + } @SuppressWarnings("unchecked") private Map normalizeScaleImportMap(Map root) diff --git a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyUserProfileController.java b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyUserProfileController.java index 9d536f74..dfa532d6 100644 --- a/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyUserProfileController.java +++ b/ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyUserProfileController.java @@ -24,6 +24,7 @@ import com.ddnai.common.enums.BusinessType; import com.ddnai.common.utils.SecurityUtils; import com.ddnai.common.utils.StringUtils; import com.ddnai.common.utils.poi.ExcelUtil; +import com.ddnai.system.domain.dto.ImportProgress; import com.ddnai.system.domain.psychology.PsyUserProfile; import com.ddnai.system.service.ISysDeptService; import com.ddnai.system.service.ISysPostService; @@ -280,4 +281,15 @@ public class PsyUserProfileController extends BaseController String message = profileService.importProfile(profileList, updateSupport, operName); return success(message); } + + /** + * 查询导入进度 + */ + @PreAuthorize("@ss.hasPermi('psychology:profile:import')") + @GetMapping("/importProgress") + public AjaxResult getImportProgress() + { + ImportProgress progress = profileService.getImportProgress(getUsername()); + return success(progress); + } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/domain/dto/ImportProgress.java b/ry-xinli-system/src/main/java/com/ddnai/system/domain/dto/ImportProgress.java new file mode 100644 index 00000000..51933b55 --- /dev/null +++ b/ry-xinli-system/src/main/java/com/ddnai/system/domain/dto/ImportProgress.java @@ -0,0 +1,150 @@ +package com.ddnai.system.domain.dto; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 通用导入进度信息 + */ +public class ImportProgress implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总数量 */ + private int total; + + /** 已处理数量 */ + private int processed; + + /** 成功数量 */ + private int success; + + /** 失败数量 */ + private int failure; + + /** 状态:processing、success、failed */ + private String status; + + /** 状态描述/提示 */ + private String message; + + /** 开始时间 */ + private LocalDateTime startTime; + + /** 最近更新时间 */ + private LocalDateTime lastUpdateTime; + + /** 过期时间戳(毫秒) */ + private long expireAt; + + public int getTotal() + { + return total; + } + + public void setTotal(int total) + { + this.total = total; + } + + public int getProcessed() + { + return processed; + } + + public void setProcessed(int processed) + { + this.processed = processed; + } + + public int getSuccess() + { + return success; + } + + public void setSuccess(int success) + { + this.success = success; + } + + public int getFailure() + { + return failure; + } + + public void setFailure(int failure) + { + this.failure = failure; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getMessage() + { + return message; + } + + public void setMessage(String message) + { + this.message = message; + } + + public LocalDateTime getStartTime() + { + return startTime; + } + + public void setStartTime(LocalDateTime startTime) + { + this.startTime = startTime; + } + + public LocalDateTime getLastUpdateTime() + { + return lastUpdateTime; + } + + public void setLastUpdateTime(LocalDateTime lastUpdateTime) + { + this.lastUpdateTime = lastUpdateTime; + } + + public long getExpireAt() + { + return expireAt; + } + + public void setExpireAt(long expireAt) + { + this.expireAt = expireAt; + } + + public boolean isExpired(long now) + { + return expireAt > 0 && now > expireAt; + } + + public ImportProgress copy() + { + ImportProgress copy = new ImportProgress(); + copy.setTotal(this.total); + copy.setProcessed(this.processed); + copy.setSuccess(this.success); + copy.setFailure(this.failure); + copy.setStatus(this.status); + copy.setMessage(this.message); + copy.setStartTime(this.startTime); + copy.setLastUpdateTime(this.lastUpdateTime); + copy.setExpireAt(this.expireAt); + return copy; + } +} + diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyScalePermission.java b/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyScalePermission.java index 6745e914..afafd85d 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyScalePermission.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/domain/psychology/PsyScalePermission.java @@ -46,6 +46,9 @@ public class PsyScalePermission extends BaseEntity /** 量表名称(关联查询字段,不存储在表中) */ private String scaleName; + /** 来源类型(scale/questionnaire) */ + private String sourceType; + /** 部门名称(关联查询字段,不存储在表中) */ private String deptName; @@ -155,6 +158,16 @@ public class PsyScalePermission extends BaseEntity this.scaleName = scaleName; } + public String getSourceType() + { + return sourceType; + } + + public void setSourceType(String sourceType) + { + this.sourceType = sourceType; + } + public String getDeptName() { return deptName; @@ -202,6 +215,8 @@ public class PsyScalePermission extends BaseEntity .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) + .append("scaleName", getScaleName()) + .append("sourceType", getSourceType()) .toString(); } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/mapper/psychology/PsyScalePermissionMapper.java b/ry-xinli-system/src/main/java/com/ddnai/system/mapper/psychology/PsyScalePermissionMapper.java index 3dba4814..41058155 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/mapper/psychology/PsyScalePermissionMapper.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/mapper/psychology/PsyScalePermissionMapper.java @@ -91,5 +91,12 @@ public interface PsyScalePermissionMapper * @return 结果 */ public int deletePermissionByScaleId(Long scaleId); + + /** + * 查询所有已配置权限的量表ID + * + * @return 量表ID集合 + */ + public List selectAllScaleIdsWithPermission(); } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyScalePermissionServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyScalePermissionServiceImpl.java index e82a1629..6664dcd3 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyScalePermissionServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyScalePermissionServiceImpl.java @@ -9,8 +9,10 @@ import org.springframework.transaction.annotation.Transactional; import com.ddnai.common.utils.SecurityUtils; import com.ddnai.system.domain.psychology.PsyScalePermission; import com.ddnai.system.mapper.psychology.PsyScalePermissionMapper; +import com.ddnai.system.domain.psychology.PsyQuestionnaire; import com.ddnai.system.service.psychology.IPsyScalePermissionService; import com.ddnai.system.service.psychology.IPsyScaleService; +import com.ddnai.system.service.psychology.IPsyQuestionnaireService; /** * 量表权限 服务层实现 @@ -27,6 +29,9 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService @Autowired private IPsyScaleService scaleService; + + @Autowired + private IPsyQuestionnaireService questionnaireService; /** * 查询量表权限信息 @@ -92,15 +97,7 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService @Override public int insertPermission(PsyScalePermission permission) { - // 验证 scale_id 是否存在 - if (permission.getScaleId() != null) - { - com.ddnai.system.domain.psychology.PsyScale scale = scaleService.selectScaleById(permission.getScaleId()); - if (scale == null) - { - throw new RuntimeException("量表不存在,scaleId: " + permission.getScaleId()); - } - } + validateScaleExists(permission.getScaleId()); if (permission.getStatus() == null) { @@ -150,15 +147,7 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService @Override public int updatePermission(PsyScalePermission permission) { - // 验证 scale_id 是否存在 - if (permission.getScaleId() != null) - { - com.ddnai.system.domain.psychology.PsyScale scale = scaleService.selectScaleById(permission.getScaleId()); - if (scale == null) - { - throw new RuntimeException("量表不存在,scaleId: " + permission.getScaleId()); - } - } + validateScaleExists(permission.getScaleId()); return permissionMapper.updatePermission(permission); } @@ -239,12 +228,10 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService } try { - // 验证 scale_id 是否存在 - com.ddnai.system.domain.psychology.PsyScale scale = scaleService.selectScaleById(scaleId); - if (scale == null) + if (!validateScaleExistsSilent(scaleId)) { - log.warn("量表不存在,跳过该权限分配,scaleId: {}", scaleId); - continue; // 跳过不存在的量表 + log.warn("量表/问卷不存在,跳过该权限分配,scaleId: {}", scaleId); + continue; } PsyScalePermission permission = new PsyScalePermission(); @@ -267,5 +254,35 @@ public class PsyScalePermissionServiceImpl implements IPsyScalePermissionService } return count; } + + @Override + public List selectAllScaleIdsWithPermission() + { + return permissionMapper.selectAllScaleIdsWithPermission(); + } + + private void validateScaleExists(Long scaleId) + { + if (!validateScaleExistsSilent(scaleId)) + { + throw new RuntimeException("量表或问卷不存在,scaleId: " + scaleId); + } + } + + private boolean validateScaleExistsSilent(Long scaleId) + { + if (scaleId == null) + { + return true; + } + if (scaleId < 0) + { + Long questionnaireId = Math.abs(scaleId); + PsyQuestionnaire questionnaire = questionnaireService.selectQuestionnaireById(questionnaireId); + return questionnaire != null; + } + com.ddnai.system.domain.psychology.PsyScale scale = scaleService.selectScaleById(scaleId); + return scale != null; + } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java index 5c9caea5..84916dd7 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java @@ -14,10 +14,12 @@ import com.ddnai.common.utils.SecurityUtils; import com.ddnai.common.utils.StringUtils; import com.ddnai.system.domain.psychology.PsyUserProfile; import com.ddnai.system.mapper.psychology.PsyUserProfileMapper; +import com.ddnai.system.domain.dto.ImportProgress; import com.ddnai.system.service.ISysConfigService; import com.ddnai.system.service.ISysRoleService; import com.ddnai.system.service.ISysUserService; import com.ddnai.system.service.psychology.IPsyUserProfileService; +import com.ddnai.system.service.psychology.support.ImportProgressManager; /** * 用户档案扩展表 服务层实现 @@ -41,6 +43,9 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService @Autowired private ISysRoleService roleService; + @Autowired + private ImportProgressManager importProgressManager; + /** * 查询档案信息 * @@ -475,13 +480,16 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService { throw new ServiceException("导入用户档案数据不能为空!"); } + final String progressKey = importProgressManager.buildProfileKey(operName); + importProgressManager.start(progressKey, profileList.size()); int successNum = 0; int failureNum = 0; StringBuilder successMsg = new StringBuilder(); StringBuilder failureMsg = new StringBuilder(); - - for (PsyUserProfile profile : profileList) + try { + for (PsyUserProfile profile : profileList) + { try { // 设置创建者 @@ -492,6 +500,7 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService { failureNum++; failureMsg.append("
").append(failureNum).append("、档案信息编号为空"); + importProgressManager.recordFailure(progressKey); continue; } @@ -503,6 +512,7 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService this.insertProfile(profile); successNum++; successMsg.append("
").append(successNum).append("、信息编号 ").append(profile.getInfoNumber()).append(" 导入成功"); + importProgressManager.recordSuccess(progressKey); } else if (isUpdateSupport) { @@ -513,11 +523,13 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService this.updateProfile(profile); successNum++; successMsg.append("
").append(successNum).append("、信息编号 ").append(profile.getInfoNumber()).append(" 更新成功"); + importProgressManager.recordSuccess(progressKey); } else { failureNum++; failureMsg.append("
").append(failureNum).append("、信息编号 ").append(profile.getInfoNumber()).append(" 已存在"); + importProgressManager.recordFailure(progressKey); } } catch (Exception e) @@ -525,20 +537,51 @@ public class PsyUserProfileServiceImpl implements IPsyUserProfileService failureNum++; String msg = "
" + failureNum + "、信息编号 " + profile.getInfoNumber() + " 导入失败:"; failureMsg.append(msg).append(e.getMessage()); + importProgressManager.recordFailure(progressKey); log.error(msg, e); } } + + if (successNum > 0) + { + successMsg.insert(0, "以下数据处理成功(共 " + successNum + " 条):"); + } if (failureNum > 0) { failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + if (successNum > 0) + { + failureMsg.append("

").append(successMsg); + } + importProgressManager.finishFailure(progressKey, failureMsg.toString()); throw new ServiceException(failureMsg.toString()); } - else + + if (successNum > 0) { - successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + String successMessage = "恭喜您,数据已全部导入成功!
" + successMsg.toString(); + importProgressManager.finishSuccess(progressKey, successMessage); + return successMessage; + } + importProgressManager.finishSuccess(progressKey, "导入完成,但未检测到需要处理的数据。"); + return "导入完成,但未检测到需要处理的数据。"; } - return successMsg.toString(); + catch (RuntimeException ex) + { + if (!(ex instanceof ServiceException)) + { + importProgressManager.finishFailure(progressKey, ex.getMessage()); + } + throw ex; + } + } + + @Override + public ImportProgress getImportProgress(String operName) + { + String progressKey = importProgressManager.buildProfileKey(operName); + return importProgressManager.snapshot(progressKey); } } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyScalePermissionService.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyScalePermissionService.java index 9e7d368f..380a1c1e 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyScalePermissionService.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyScalePermissionService.java @@ -83,6 +83,13 @@ public interface IPsyScalePermissionService */ public int deletePermissionByScaleId(Long scaleId); + /** + * 查询所有已配置权限的量表ID + * + * @return 量表ID集合 + */ + public List selectAllScaleIdsWithPermission(); + /** * 批量分配用户量表权限 * diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyUserProfileService.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyUserProfileService.java index b670a5c6..97a94af2 100644 --- a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyUserProfileService.java +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyUserProfileService.java @@ -1,6 +1,7 @@ package com.ddnai.system.service.psychology; import java.util.List; +import com.ddnai.system.domain.dto.ImportProgress; import com.ddnai.system.domain.psychology.PsyUserProfile; /** @@ -75,5 +76,13 @@ public interface IPsyUserProfileService * @return 结果 */ public String importProfile(List profileList, Boolean isUpdateSupport, String operName); + + /** + * 查询导入进度 + * + * @param operName 操作人 + * @return 进度信息 + */ + public ImportProgress getImportProgress(String operName); } diff --git a/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/support/ImportProgressManager.java b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/support/ImportProgressManager.java new file mode 100644 index 00000000..08ad2cae --- /dev/null +++ b/ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/support/ImportProgressManager.java @@ -0,0 +1,130 @@ +package com.ddnai.system.service.psychology.support; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.springframework.stereotype.Component; + +import com.ddnai.system.domain.dto.ImportProgress; + +/** + * 导入进度管理 + */ +@Component +public class ImportProgressManager +{ + private static final long EXPIRE_MILLIS = TimeUnit.MINUTES.toMillis(30); + + private final Map cache = new ConcurrentHashMap<>(); + + public String buildProfileKey(String username) + { + return "psychology_profile:" + username; + } + + public void start(String key, int total) + { + if (Objects.isNull(key)) + { + return; + } + ImportProgress progress = new ImportProgress(); + progress.setTotal(total); + progress.setProcessed(0); + progress.setSuccess(0); + progress.setFailure(0); + progress.setStatus("processing"); + progress.setStartTime(LocalDateTime.now()); + progress.setLastUpdateTime(LocalDateTime.now()); + progress.setExpireAt(System.currentTimeMillis() + EXPIRE_MILLIS); + cache.put(key, progress); + } + + public void recordSuccess(String key) + { + adjustProgress(key, true); + } + + public void recordFailure(String key) + { + adjustProgress(key, false); + } + + private void adjustProgress(String key, boolean success) + { + ImportProgress progress = cache.get(key); + if (progress == null) + { + return; + } + progress.setProcessed(progress.getProcessed() + 1); + if (success) + { + progress.setSuccess(progress.getSuccess() + 1); + } + else + { + progress.setFailure(progress.getFailure() + 1); + } + refreshMeta(progress); + } + + public void finishSuccess(String key, String message) + { + ImportProgress progress = cache.get(key); + if (progress == null) + { + return; + } + progress.setStatus("success"); + progress.setMessage(message); + progress.setProcessed(progress.getTotal()); + refreshMeta(progress); + } + + public void finishFailure(String key, String message) + { + ImportProgress progress = cache.get(key); + if (progress == null) + { + return; + } + progress.setStatus("failed"); + progress.setMessage(message); + refreshMeta(progress); + } + + private void refreshMeta(ImportProgress progress) + { + progress.setLastUpdateTime(LocalDateTime.now()); + progress.setExpireAt(System.currentTimeMillis() + EXPIRE_MILLIS); + } + + public ImportProgress snapshot(String key) + { + ImportProgress progress = cache.get(key); + if (progress == null) + { + return null; + } + long now = System.currentTimeMillis(); + if (progress.isExpired(now)) + { + cache.remove(key); + return null; + } + return progress.copy(); + } + + public void clear(String key) + { + if (key != null) + { + cache.remove(key); + } + } +} + diff --git a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml index c685a5c0..95be61eb 100644 --- a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml +++ b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyAssessmentMapper.xml @@ -77,7 +77,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -349,4 +354,3 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - diff --git a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyScalePermissionMapper.xml b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyScalePermissionMapper.xml index 8da382f5..e81148a7 100644 --- a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyScalePermissionMapper.xml +++ b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyScalePermissionMapper.xml @@ -28,9 +28,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select p.permission_id, p.scale_id, p.dept_id, p.role_id, p.user_id, p.class_name, p.start_time, p.end_time, p.status, p.create_by, p.create_time, p.update_by, p.update_time, p.remark, - s.scale_name, d.dept_name, r.role_name, u.user_name + case when p.scale_id < 0 then q.questionnaire_name else s.scale_name end as scale_name, + case when p.scale_id < 0 then 'questionnaire' else 'scale' end as source_type, + d.dept_name, r.role_name, u.user_name from psy_scale_permission p left join psy_scale s on p.scale_id = s.scale_id + left join psy_questionnaire q on q.questionnaire_id = -p.scale_id left join sys_dept d on p.dept_id = d.dept_id left join sys_role r on p.role_id = r.role_id left join sys_user u on p.user_id = u.user_id @@ -175,4 +178,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" delete from psy_scale_permission where scale_id = #{scaleId} + + diff --git a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyUserProfileMapper.xml b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyUserProfileMapper.xml index 94c0c941..6242bb0a 100644 --- a/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyUserProfileMapper.xml +++ b/ry-xinli-system/src/main/resources/mapper/system/psychology/PsyUserProfileMapper.xml @@ -94,6 +94,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND u.phonenumber like concat('%', #{phone}, '%') + + AND p.prison = #{prison} + + + AND p.prison_area = #{prisonArea} + AND u.status = #{status} @@ -196,4 +202,3 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - diff --git a/xinli-ui/src/api/psychology/assessment.js b/xinli-ui/src/api/psychology/assessment.js index fe406a5c..5f885338 100644 --- a/xinli-ui/src/api/psychology/assessment.js +++ b/xinli-ui/src/api/psychology/assessment.js @@ -19,10 +19,11 @@ export function myAssessmentList(query) { } // 查询暂停的测评列表 -export function pausedAssessmentList() { +export function pausedAssessmentList(params) { return request({ url: '/psychology/assessment/pausedList', - method: 'get' + method: 'get', + params: params }) } diff --git a/xinli-ui/src/api/psychology/profile.js b/xinli-ui/src/api/psychology/profile.js index 47894322..a0e89c17 100644 --- a/xinli-ui/src/api/psychology/profile.js +++ b/xinli-ui/src/api/psychology/profile.js @@ -93,3 +93,11 @@ export function delUserInProfile(userIds) { }) } +// 查询档案导入进度 +export function getProfileImportProgress() { + return request({ + url: '/psychology/profile/importProgress', + method: 'get' + }) +} + diff --git a/xinli-ui/src/views/psychology/assessment/index.vue b/xinli-ui/src/views/psychology/assessment/index.vue index 3b0d222c..0993faea 100644 --- a/xinli-ui/src/views/psychology/assessment/index.vue +++ b/xinli-ui/src/views/psychology/assessment/index.vue @@ -61,7 +61,11 @@ - + + +