diff --git a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql index 14edb2f..38f5ba4 100644 --- a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql +++ b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql @@ -318,8 +318,8 @@ INSERT INTO `tb_sys_menu` VALUES ('3000', 'menu_admin_resource_manage', '资源管理', NULL, '', '', 'admin/resource.svg', 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:40', NULL, 0), ('3001', 'menu_admin_resource', '数据采集', 'menu_admin_resource_manage', '/admin/manage/resource/resource', 'admin/manage/resource/ResourceManagementView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('3002', 'menu_admin_article', '文章管理', 'menu_admin_resource_manage', '/admin/manage/resource/article', 'admin/manage/resource/ArticleManagementView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('3010', 'menu_article_add', '文章添加', 'menu_admin_article', '/article/add', 'public/article/ArticleAddView', NULL, 1, 3, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('3011', 'menu_article_show', '文章展示', 'menu_admin_article', '/article/show', 'public/article/ArticleShowView', NULL, 2, 3, 'NavigationLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), +('3010', 'menu_article_add', '文章添加', NULL, '/article/add', 'public/article/ArticleAddView', NULL, 1, 3, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), +('3011', 'menu_article_show', '文章展示', NULL, '/article/show', 'public/article/ArticleShowView', NULL, 2, 3, 'NavigationLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('4000', 'menu_admin_content_manage', '运营管理', NULL, '', '', 'admin/maintain.svg', 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:42', NULL, 0), ('4001', 'menu_admin_banner', 'Banner管理', 'menu_admin_content_manage', '/admin/manage/content/banner', 'admin/manage/content/BannerManagementView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:49:56', NULL, 0), ('4002', 'menu_admin_tag', '标签管理', 'menu_admin_content_manage', '/admin/manage/content/tag', 'admin/manage/content/TagManagementView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:49:56', NULL, 0), diff --git a/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/task/LearningTaskService.java b/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/task/LearningTaskService.java index fac7967..feae608 100644 --- a/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/task/LearningTaskService.java +++ b/schoolNewsServ/api/api-study/src/main/java/org/xyzh/api/study/task/LearningTaskService.java @@ -116,6 +116,8 @@ public interface LearningTaskService { */ ResultDomain addTaskUser(String taskID, List userIDs); + ResultDomain updateTaskUser(String taskID, List userIDs); + /** * @description 批量添加任务用户 * @param taskID 任务ID diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningTaskController.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningTaskController.java index c093fbc..4079f0d 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningTaskController.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/controller/LearningTaskController.java @@ -117,30 +117,21 @@ public class LearningTaskController { return learningTaskService.addTaskUser(taskID, userIDs); } + /** + * 批量更新任务用户 + */ + @PutMapping("/{taskID}/users") + public ResultDomain updateTaskUser(@PathVariable("taskID") String taskID, @RequestBody Map> map) { + List userIDs = map.get("userIDs"); + return learningTaskService.updateTaskUser(taskID, userIDs); + } + @DeleteMapping("/{taskID}/users") public ResultDomain removeTaskUser(@PathVariable("taskID") String taskID, @RequestBody Map> map) { List userIDs = map.get("userIDs"); return learningTaskService.removeTaskUser(taskID, userIDs); } - /** - * 分配任务给用户 - */ - @PostMapping("/{taskID}/assign") - public ResultDomain assignTaskToUser(@PathVariable("taskID") String taskID, @RequestParam String userID) { - return null; - // return learningTaskService.assignTaskToUser(taskID, userID); - } - - /** - * 从用户移除任务 - */ - @DeleteMapping("/{taskID}/user/{userID}") - public ResultDomain removeTaskFromUser(@PathVariable("taskID") String taskID, @PathVariable("userID") String userID) { - return null; - // return learningTaskService.removeTaskFromUser(taskID, userID); - } - /** * 用户获取个人任务列表(用户视角) */ diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningTaskServiceImpl.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningTaskServiceImpl.java index d0f7ffb..7c73918 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningTaskServiceImpl.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCLearningTaskServiceImpl.java @@ -111,6 +111,65 @@ public class SCLearningTaskServiceImpl implements LearningTaskService { } } + @Override + public ResultDomain updateTaskUser(String taskID, List userIDs){ + ResultDomain resultDomain = new ResultDomain<>(); + TbSysUser user = LoginUtil.getCurrentUser(); + if (user == null) { + resultDomain.fail("请先登录"); + return resultDomain; + } + + // 先查询已有人员 + List taskUsers = taskUserMapper.selectByTaskId(taskID).stream().map(TbTaskUser::getUserID).toList(); + + // newList: userIDs中有但taskUsers中没有的(需要新增的用户) + List newList = userIDs.stream() + .filter(userId -> !taskUsers.contains(userId)) + .toList(); + + // oldList: userIDs和taskUsers都有的(保留的用户) + List oldList = userIDs.stream() + .filter(taskUsers::contains) + .toList(); + + // deleteList: taskUsers中有但userIDs中没有的(需要删除的用户) + List deleteList = taskUsers.stream() + .filter(userId -> !userIDs.contains(userId)) + .toList(); + + // 批量插入新用户 + List insertUsers = new ArrayList<>(); + for (String userID : newList) { + TbTaskUser taskUser = new TbTaskUser(); + taskUser.setId(IDUtils.generateID()); + taskUser.setTaskID(taskID); + taskUser.setUserID(userID); + taskUser.setCreator(user.getId()); + taskUser.setCreateTime(new Date()); + insertUsers.add(taskUser); + } + + // 执行批量操作 + if (!insertUsers.isEmpty()) { + int insertResult = taskUserMapper.batchInsertTaskUsers(insertUsers); + logger.debug("批量插入任务用户: {}条", insertResult); + } + + if (!deleteList.isEmpty()) { + int deleteResult = taskUserMapper.batchDeleteTaskUsers(taskID, deleteList); + logger.debug("批量删除任务用户: {}条", deleteResult); + } + + // 更新学习人数:新人数 = 保留的 + 新增的 + int newUserCount = oldList.size() + newList.size(); + courseMapper.incrementLearnCount(taskID, newUserCount - taskUsers.size()); + + resultDomain.success("更新任务用户成功", insertUsers); + logger.info("任务{}更新用户成功: 新增{}人, 删除{}人, 保留{}人", taskID, newList.size(), deleteList.size(), oldList.size()); + return resultDomain; + } + @Override public ResultDomain batchAddTaskUsers(String taskID, List userIDs, String deptID) { // TODO Auto-generated method stub diff --git a/schoolNewsWeb/src/apis/study/learning-task.ts b/schoolNewsWeb/src/apis/study/learning-task.ts index 0815408..7c648ef 100644 --- a/schoolNewsWeb/src/apis/study/learning-task.ts +++ b/schoolNewsWeb/src/apis/study/learning-task.ts @@ -110,6 +110,17 @@ export const learningTaskApi = { return response.data; }, + /** + * 更新任务用户(统一的添加/删除人员接口) + * @param taskID 任务ID + * @param userIDs 用户ID列表 + * @returns Promise> + */ + async updateTaskUser(taskID: string, userIDs: string[]): Promise> { + const response = await api.put(`${this.learningTaskPrefix}/${taskID}/users`, { userIDs }); + return response.data; + }, + /** * 获取用户任务进度 * @param userID 用户ID @@ -123,29 +134,7 @@ export const learningTaskApi = { return response.data; }, - /** - * 分配任务给用户 - * @param taskID 任务ID - * @param userID 用户ID - * @returns Promise> - */ - async assignTaskToUser(taskID: string, userID: string): Promise> { - const response = await api.post(`${this.learningTaskPrefix}/${taskID}/assign`, null, { - params: { userID } - }); - return response.data; - }, - /** - * 从用户移除任务 - * @param taskID 任务ID - * @param userID 用户ID - * @returns Promise> - */ - async removeTaskFromUser(taskID: string, userID: string): Promise> { - const response = await api.delete(`${this.learningTaskPrefix}/${taskID}/user/${userID}`); - return response.data; - }, /** * 用户获取个人任务列表(用户视角) diff --git a/schoolNewsWeb/src/views/admin/manage/study/TaskManageView.vue b/schoolNewsWeb/src/views/admin/manage/study/TaskManageView.vue index 652a11c..e6e4519 100644 --- a/schoolNewsWeb/src/views/admin/manage/study/TaskManageView.vue +++ b/schoolNewsWeb/src/views/admin/manage/study/TaskManageView.vue @@ -699,30 +699,35 @@ async function handleUserSelectConfirm(selectedUsers: any[]) { saving.value = true; try { - const userIds = selectedUsers.map(u => u.id!); + const selectedUserIds = selectedUsers.map(u => u.id!); + + // 计算更新后的用户ID列表 + let updatedUserIds: string[]; if (selectorMode.value === 'add') { - // 执行添加操作 - for (const userID of userIds) { - await learningTaskApi.assignTaskToUser(managingTask.value.learningTask.taskID!, userID); - } - ElMessage.success(`成功添加 ${userIds.length} 位人员`); + // 添加模式:合并现有用户和新选择的用户 + const currentUserIds = currentUsers.value.map(u => u.id!); + updatedUserIds = [...new Set([...currentUserIds, ...selectedUserIds])]; // 更新当前用户列表 currentUsers.value.push(...(selectedUsers as UserVO[])); + ElMessage.success(`成功添加 ${selectedUserIds.length} 位人员`); } else { - // 执行删除操作 - for (const userID of userIds) { - await learningTaskApi.removeTaskFromUser(managingTask.value.learningTask.taskID!, userID); - } - ElMessage.success(`成功删除 ${userIds.length} 位人员`); + // 删除模式:从现有用户中移除选择的用户 + updatedUserIds = currentUsers.value + .map(u => u.id!) + .filter(id => !selectedUserIds.includes(id)); // 更新当前用户列表 currentUsers.value = currentUsers.value.filter(user => - !userIds.includes(user.id!) + !selectedUserIds.includes(user.id!) ); + ElMessage.success(`成功删除 ${selectedUserIds.length} 位人员`); } + // 调用统一的更新接口 + await learningTaskApi.updateTaskUser(managingTask.value.learningTask.taskID!, updatedUserIds); + closeSelectorModal(); loadTaskList(); } catch (error) {