From e0aa84416224cc064af62dadfa3f7e1e44b54d05 Mon Sep 17 00:00:00 2001 From: GoCo Date: Fri, 19 Sep 2025 10:06:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E8=AE=A8=E8=AE=BA?= =?UTF-8?q?=E8=A1=A8=E4=BB=A3=E7=A0=81+=E6=8E=A5=E5=8F=A3=E3=80=81?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=8E=A5=E5=8F=A3=E3=80=81=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E3=80=81=E8=AF=BE=E7=A8=8B=E7=AB=A0=E8=8A=82?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiol/constant/EntityLinkConst.java | 2 + .../controller/AiolCommentController.java | 98 +++++++- .../controller/AiolDiscussionController.java | 205 ++++++++++++++++ .../controller/AiolHomeworkController.java | 131 +++++++++++ .../controller/AiolMessageController.java | 102 ++++++++ .../controller/AiolResourceController.java | 118 ++++++++++ .../modules/aiol/dto/AiolHomeworkSaveDTO.java | 23 ++ .../modules/aiol/dto/CommentWithUserInfo.java | 5 + .../modules/aiol/entity/AiolDiscussion.java | 64 +++++ .../modules/aiol/entity/AiolHomework.java | 16 +- .../aiol/mapper/AiolDiscussionMapper.java | 17 ++ .../aiol/mapper/xml/AiolDiscussionMapper.xml | 5 + .../aiol/service/IAiolDiscussionService.java | 14 ++ .../service/IAiolHomeworkSubmitService.java | 5 + .../impl/AiolDiscussionServiceImpl.java | 19 ++ .../impl/AiolHomeworkSubmitServiceImpl.java | 10 + .../aiol/uniapp/AiolDiscussionForm.vue | 89 +++++++ .../aiol/uniapp/AiolDiscussionList.vue | 44 ++++ .../aiol/uniapp3/AiolDiscussionData.ts | 14 ++ .../aiol/uniapp3/AiolDiscussionForm.vue | 222 ++++++++++++++++++ .../aiol/uniapp3/AiolDiscussionList.vue | 148 ++++++++++++ .../modules/aiol/vue3/AiolDiscussion.api.ts | 64 +++++ .../modules/aiol/vue3/AiolDiscussion.data.ts | 56 +++++ .../modules/aiol/vue3/AiolDiscussionList.vue | 206 ++++++++++++++++ ...20250919_1__menu_insert_AiolDiscussion.sql | 26 ++ .../vue3/components/AiolDiscussionForm.vue | 70 ++++++ .../vue3/components/AiolDiscussionModal.vue | 99 ++++++++ .../src/views/aiol/AiolHomework.data.ts | 37 +++ 28 files changed, 1899 insertions(+), 10 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolDiscussionController.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolHomeworkSaveDTO.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolDiscussion.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/AiolDiscussionMapper.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/xml/AiolDiscussionMapper.xml create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolDiscussionService.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolDiscussionServiceImpl.java create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionForm.vue create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionList.vue create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionData.ts create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionForm.vue create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionList.vue create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.api.ts create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.data.ts create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussionList.vue create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/V20250919_1__menu_insert_AiolDiscussion.sql create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionForm.vue create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionModal.vue diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/constant/EntityLinkConst.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/constant/EntityLinkConst.java index 4eddd70e..41dee935 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/constant/EntityLinkConst.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/constant/EntityLinkConst.java @@ -39,6 +39,8 @@ public final class EntityLinkConst { public static final String REPO = "repo"; // 班级 public static final String CLASS = "class"; + // 讨论 + public static final String DISCUSSION = "discussion"; } /** 资源类型 0:视频,1:图片,2:文档 */ diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCommentController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCommentController.java index bc89df17..b7324b4e 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCommentController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCommentController.java @@ -1,5 +1,6 @@ package org.jeecg.modules.aiol.controller; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -93,7 +94,19 @@ public class AiolCommentController extends JeecgController add(@RequestBody AiolComment aiolComment) { + public Result add(@RequestBody AiolComment aiolComment, HttpServletRequest request) { + // 1. 获取当前登录用户信息 + String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); + String username = JwtUtil.getUsername(token); + LoginUser sysUser = sysBaseApi.getUserByName(username); + + if (sysUser == null) { + return Result.error("用户未登录或登录已过期"); + } + + aiolComment.setUserId(sysUser.getId()); // 用户ID + aiolComment.setLikeCount(0); + aiolCommentService.save(aiolComment); return Result.OK("添加成功!"); @@ -153,6 +166,7 @@ public class AiolCommentController extends JeecgController queryById(@RequestParam(name = "id", required = true) String id) { AiolComment aiolComment = aiolCommentService.getById(id); if (aiolComment == null) { @@ -187,11 +201,49 @@ public class AiolCommentController extends JeecgController> queryCourseCommentList(@PathVariable("courseId") String courseId) { - List list = aiolCommentService.getCommentList("course", courseId); - return Result.OK(list); + try { + // 1. 查询课程的一级评论(target_type=course, target_id=courseId) + List parentComments = aiolCommentService.getCommentList("course", courseId); + + // 2. 为每个一级评论查询其所有子评论(递归查询所有层级) + for (CommentWithUserInfo parentComment : parentComments) { + List allReplies = getAllRepliesRecursively(parentComment.getId()); + parentComment.setReplies(allReplies); + } + + log.info("查询课程评论列表成功: courseId={}, 一级评论数量={}", courseId, parentComments.size()); + return Result.OK(parentComments); + + } catch (Exception e) { + log.error("查询课程评论列表失败: courseId={}, error={}", courseId, e.getMessage(), e); + return Result.error("查询课程评论列表失败: " + e.getMessage()); + } + } + + /** + * 递归查询评论的所有子评论 + * @param commentId 评论ID + * @return 所有子评论列表 + */ + private List getAllRepliesRecursively(String commentId) { + List allReplies = new ArrayList<>(); + + // 查询直接子评论(target_type=comment, target_id=commentId) + List directReplies = aiolCommentService.getCommentList("comment", commentId); + + for (CommentWithUserInfo reply : directReplies) { + // 将当前回复添加到总列表中 + allReplies.add(reply); + + // 递归查询当前回复的子评论 + List subReplies = getAllRepliesRecursively(reply.getId()); + allReplies.addAll(subReplies); + } + + return allReplies; } // @GetMapping("/activity/{activityId}/list") @@ -243,11 +295,9 @@ public class AiolCommentController extends JeecgController likeComment(@PathVariable("commentId") String commentId) { + try { + // 1. 查询评论是否存在 + AiolComment comment = aiolCommentService.getById(commentId); + if (comment == null) { + return Result.error("评论不存在"); + } + + // 2. 更新点赞数 + Integer currentLikeCount = comment.getLikeCount() != null ? comment.getLikeCount() : 0; + comment.setLikeCount(currentLikeCount + 1); + + boolean updated = aiolCommentService.updateById(comment); + if (!updated) { + return Result.error("点赞失败"); + } + + log.info("评论点赞成功: commentId={}, 当前点赞数={}", commentId, comment.getLikeCount()); + return Result.OK("点赞成功!"); + + } catch (Exception e) { + log.error("评论点赞失败: commentId={}, error={}", commentId, e.getMessage(), e); + return Result.error("点赞失败: " + e.getMessage()); + } + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolDiscussionController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolDiscussionController.java new file mode 100644 index 00000000..f430f86b --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolDiscussionController.java @@ -0,0 +1,205 @@ +package org.jeecg.modules.aiol.controller; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.aiol.entity.AiolDiscussion; +import org.jeecg.modules.aiol.service.IAiolDiscussionService; +import org.jeecg.modules.aiol.service.IAiolEntityLinkService; +import org.jeecg.modules.aiol.constant.EntityLinkConst; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + /** + * @Description: 讨论 + * @Author: jeecg-boot + * @Date: 2025-09-19 + * @Version: V1.0 + */ +@Tag(name="讨论") +@RestController +@RequestMapping("/aiol/aiolDiscussion") +@Slf4j +public class AiolDiscussionController extends JeecgController { + @Autowired + private IAiolDiscussionService aiolDiscussionService; + @Autowired + private IAiolEntityLinkService aiolEntityLinkService; + + /** + * 分页列表查询 + * + * @param aiolDiscussion + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "讨论-分页列表查询") + @Operation(summary="讨论-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(AiolDiscussion aiolDiscussion, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + + + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(aiolDiscussion, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = aiolDiscussionService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param aiolDiscussion + * @param sectionId 可选的章节ID,如果传入则创建与章节的关联关系 + * @return + */ + @AutoLog(value = "讨论-添加") + @Operation(summary="讨论-添加", description="添加讨论,可选择关联到指定章节") + @RequiresPermissions("aiol:aiol_discussion:add") + @PostMapping(value = "/add") + public Result add(@RequestBody AiolDiscussion aiolDiscussion, + @RequestParam(value = "sectionId", required = false) String sectionId) { + try { + // 保存讨论记录 + aiolDiscussionService.save(aiolDiscussion); + + // 如果传入了sectionId,创建与章节的关联关系 + if (sectionId != null && !sectionId.trim().isEmpty()) { + aiolEntityLinkService.save( + EntityLinkConst.SourceType.COURSE_SECTION, + sectionId.trim(), + EntityLinkConst.TargetType.DISCUSSION, + aiolDiscussion.getId() + ); + log.info("讨论 {} 成功关联到章节 {}", aiolDiscussion.getId(), sectionId); + } + + return Result.OK("添加成功!"); + } catch (Exception e) { + log.error("添加讨论失败: {}", e.getMessage(), e); + return Result.error("添加讨论失败: " + e.getMessage()); + } + } + + /** + * 编辑 + * + * @param aiolDiscussion + * @return + */ + @AutoLog(value = "讨论-编辑") + @Operation(summary="讨论-编辑") + @RequiresPermissions("aiol:aiol_discussion:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody AiolDiscussion aiolDiscussion) { + aiolDiscussionService.updateById(aiolDiscussion); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "讨论-通过id删除") + @Operation(summary="讨论-通过id删除") + @RequiresPermissions("aiol:aiol_discussion:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + aiolDiscussionService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "讨论-批量删除") + @Operation(summary="讨论-批量删除") + @RequiresPermissions("aiol:aiol_discussion:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.aiolDiscussionService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "讨论-通过id查询") + @Operation(summary="讨论-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + AiolDiscussion aiolDiscussion = aiolDiscussionService.getById(id); + if(aiolDiscussion==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(aiolDiscussion); + } + + /** + * 导出excel + * + * @param request + * @param aiolDiscussion + */ + @RequiresPermissions("aiol:aiol_discussion:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, AiolDiscussion aiolDiscussion) { + return super.exportXls(request, aiolDiscussion, AiolDiscussion.class, "讨论"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("aiol:aiol_discussion:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, AiolDiscussion.class); + } + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolHomeworkController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolHomeworkController.java index 0aafe618..2396a0dc 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolHomeworkController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolHomeworkController.java @@ -1,6 +1,7 @@ package org.jeecg.modules.aiol.controller; import java.util.Arrays; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,10 +16,17 @@ import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryRuleEnum; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.aiol.dto.AiolHomeworkSaveDTO; import org.jeecg.modules.aiol.dto.StudentSubmitHomework; import org.jeecg.modules.aiol.entity.AiolHomework; import org.jeecg.modules.aiol.entity.AiolHomeworkSubmit; import org.jeecg.modules.aiol.service.IAiolHomeworkService; +import org.jeecg.modules.aiol.service.IAiolEntityLinkService; +import org.jeecg.modules.aiol.constant.EntityLinkConst; +import org.jeecg.modules.aiol.mapper.AiolClassStudentMapper; +import org.jeecg.modules.aiol.mapper.AiolCourseSignupMapper; +import org.jeecg.modules.aiol.entity.AiolClassStudent; +import org.jeecg.modules.aiol.entity.AiolCourseSignup; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -32,6 +40,7 @@ import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -186,6 +195,15 @@ public class AiolHomeworkController extends JeecgController teacherDelete(@RequestParam(name = "id", required = true) String homeworkId) { + try { + // 1. 删除作业提交记录 + QueryWrapper submitWrapper = new QueryWrapper<>(); + submitWrapper.eq("homework_id", homeworkId); + List submitList = homeworkSubmitService.list(submitWrapper); + + if (!submitList.isEmpty()) { + List submitIds = submitList.stream() + .map(AiolHomeworkSubmit::getId) + .collect(Collectors.toList()); + homeworkSubmitService.removeByIds(submitIds); + log.info("删除作业提交记录成功: homeworkId={}, 删除数量={}", homeworkId, submitIds.size()); + } + + // 2. 删除作业记录 + boolean deleted = aiolHomeworkService.removeById(homeworkId); + if (!deleted) { + return Result.error("删除作业失败,作业不存在"); + } + + log.info("教师删除作业成功: homeworkId={}", homeworkId); + return Result.OK("删除成功!"); + + } catch (Exception e) { + log.error("教师删除作业失败: homeworkId={}, error={}", homeworkId, e.getMessage(), e); + return Result.error("删除作业失败: " + e.getMessage()); + } + } + + @AutoLog(value = "作业-教师添加") + @Operation(summary = "作业-教师添加", description = "教师添加作业,支持指定班级、课程和章节,自动为学生创建作业提交记录") + @RequiresPermissions("aiol:aiol_homework:add") + @PostMapping(value = "/teacher_add") + public Result teacherAdd(@RequestBody AiolHomeworkSaveDTO homeworkSaveDTO) { + try { + // 1. 保存作业记录 + AiolHomework aiolHomework = new AiolHomework(); + // 复制DTO中的作业字段到实体 + BeanUtils.copyProperties(homeworkSaveDTO, aiolHomework); + aiolHomeworkService.save(aiolHomework); + + String homeworkId = aiolHomework.getId(); + String classId = homeworkSaveDTO.getClassId(); + String courseId = homeworkSaveDTO.getCourseId(); + String sectionId = homeworkSaveDTO.getSectionId(); + + // 2. 为学生创建作业提交记录 + List studentIds = new ArrayList<>(); + + if (classId != null && !classId.trim().isEmpty()) { + // 如果传递了班级ID,查询指定班级的学生 + String[] classIds = classId.split(","); + for (String singleClassId : classIds) { + if (singleClassId != null && !singleClassId.trim().isEmpty()) { + singleClassId = singleClassId.trim(); + QueryWrapper classStudentWrapper = new QueryWrapper<>(); + classStudentWrapper.eq("class_id", singleClassId); + List classStudents = aiolClassStudentMapper.selectList(classStudentWrapper); + + for (AiolClassStudent classStudent : classStudents) { + String studentId = classStudent.getStudentId(); + if (!studentIds.contains(studentId)) { + studentIds.add(studentId); + } + } + } + } + } else if (courseId != null && !courseId.trim().isEmpty()) { + // 如果没有传递班级ID,查询课程下的所有学生 + QueryWrapper courseSignupWrapper = new QueryWrapper<>(); + courseSignupWrapper.eq("course_id", courseId); + List courseSignups = aiolCourseSignupMapper.selectList(courseSignupWrapper); + + for (AiolCourseSignup courseSignup : courseSignups) { + String studentId = courseSignup.getUserId(); + if (!studentIds.contains(studentId)) { + studentIds.add(studentId); + } + } + } + + // 为每个学生创建空的作业提交记录 + for (String studentId : studentIds) { + homeworkSubmitService.createEmptySubmit(homeworkId, studentId); + } + + // 3. 如果传递了章节ID,创建章节与作业的关联关系 + if (sectionId != null && !sectionId.trim().isEmpty()) { + entityLinkBizService.save( + EntityLinkConst.SourceType.COURSE_SECTION, + sectionId.trim(), + EntityLinkConst.TargetType.HOMEWORK, + homeworkId + ); + log.info("作业 {} 成功关联到章节 {}", homeworkId, sectionId); + } + + log.info("教师添加作业成功: homeworkId={}, courseId={}, classId={}, sectionId={}, 学生数量={}", + homeworkId, courseId, classId, sectionId, studentIds.size()); + + return Result.OK("添加成功!"); + + } catch (Exception e) { + log.error("教师添加作业失败: homeworkSaveDTO={}, error={}", homeworkSaveDTO, e.getMessage(), e); + return Result.error("添加作业失败: " + e.getMessage()); + } + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolMessageController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolMessageController.java index c5ccb4a5..45890619 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolMessageController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolMessageController.java @@ -14,10 +14,17 @@ import org.jeecg.common.system.vo.LoginUser; import org.springframework.web.bind.annotation.RequestParam; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.jeecg.modules.system.model.AnnouncementSendModel; import org.jeecg.modules.system.service.ISysAnnouncementSendService; +import org.jeecg.modules.system.entity.SysAnnouncementSend; +import org.jeecg.modules.system.entity.SysAnnouncement; +import org.jeecg.modules.system.service.ISysAnnouncementService; import org.apache.commons.lang3.StringUtils; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @RestController @RequestMapping("/aiol/message") @@ -27,6 +34,9 @@ public class AiolMessageController { @Autowired private ISysAnnouncementSendService sysAnnouncementSendService; + + @Autowired + private ISysAnnouncementService sysAnnouncementService; @GetMapping("/test") public void test() { @@ -113,4 +123,96 @@ public class AiolMessageController { return Result.error("查询点赞消息失败: " + e.getMessage()); } } + + @GetMapping("/system") + public Result> querySystemMessages( + AnnouncementSendModel model, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { + try { + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = sysUser.getId(); + model.setUserId(userId); + model.setPageNo((pageNo - 1) * pageSize); + model.setPageSize(pageSize); + // 处理时间范围与SysAnnouncementSendController一致 + if (StringUtils.isNotEmpty(model.getSendTimeBegin())) { + model.setSendTimeBegin(model.getSendTimeBegin() + " 00:00:00"); + } + if (StringUtils.isNotEmpty(model.getSendTimeEnd())) { + model.setSendTimeEnd(model.getSendTimeEnd() + " 23:59:59"); + } + // 系统消息 消息类别 = 2 + model.setMsgCategory("2"); + + Page page = new Page<>(pageNo, pageSize); + IPage pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(page, model); + return Result.OK(pageList); + } catch (Exception e) { + return Result.error("查询系统消息失败: " + e.getMessage()); + } + } + + @GetMapping("/unread_count") + public Result> queryUnreadMessageCount() { + try { + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String userId = sysUser.getId(); + + Map result = new HashMap<>(); + + // 1. 先查询用户所有未读消息的annt_id + QueryWrapper unreadWrapper = new QueryWrapper<>(); + unreadWrapper.eq("user_id", userId) + .eq("read_flag", 0); + List unreadMessages = sysAnnouncementSendService.list(unreadWrapper); + + if (unreadMessages.isEmpty()) { + // 如果没有未读消息,返回0 + result.put("commentsUnreadCount", 0); + result.put("likesUnreadCount", 0); + result.put("systemUnreadCount", 0); + result.put("totalUnreadCount", 0); + return Result.OK(result); + } + + // 2. 提取所有annt_id + List anntIds = unreadMessages.stream() + .map(SysAnnouncementSend::getAnntId) + .collect(java.util.stream.Collectors.toList()); + + // 3. 根据annt_id查询对应的消息详情,获取msg_category + QueryWrapper announcementWrapper = new QueryWrapper<>(); + announcementWrapper.in("id", anntIds); + List announcements = sysAnnouncementService.list(announcementWrapper); + + // 4. 按msg_category分类统计 + long commentsUnreadCount = 0; // msg_category=3 + long likesUnreadCount = 0; // msg_category=4 + long systemUnreadCount = 0; // msg_category=2 + + for (SysAnnouncement announcement : announcements) { + String msgCategory = announcement.getMsgCategory(); + if ("3".equals(msgCategory)) { + commentsUnreadCount++; + } else if ("4".equals(msgCategory)) { + likesUnreadCount++; + } else if ("2".equals(msgCategory)) { + systemUnreadCount++; + } + } + + // 5. 计算总未读数量 + long totalUnreadCount = commentsUnreadCount + likesUnreadCount + systemUnreadCount; + + result.put("commentsUnreadCount", commentsUnreadCount); + result.put("likesUnreadCount", likesUnreadCount); + result.put("systemUnreadCount", systemUnreadCount); + result.put("totalUnreadCount", totalUnreadCount); + + return Result.OK(result); + } catch (Exception e) { + return Result.error("查询未读消息数量失败: " + e.getMessage()); + } + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolResourceController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolResourceController.java index c63af50f..984e5ff5 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolResourceController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolResourceController.java @@ -368,6 +368,74 @@ public class AiolResourceController extends JeecgController uploadImage( + @RequestParam("file") MultipartFile file, + @RequestParam("courseId") String courseId, + @RequestParam("name") String name, + @RequestParam(value = "description", required = false) String description, + HttpServletRequest request) throws Exception { + + if (file == null || file.isEmpty()) { + return Result.error("没有找到上传的文件"); + } + + if (courseId == null || courseId.trim().isEmpty()) { + return Result.error("课程ID不能为空"); + } + + if (name == null || name.trim().isEmpty()) { + return Result.error("图片名称不能为空"); + } + + // 检查文件类型 + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null || !isValidImageType(originalFilename)) { + return Result.error("不支持的文件类型,仅支持jpg、jpeg、png、gif、bmp、webp等格式"); + } + + try { + // 1. 上传图片文件 + String fileUrl = uploadImageFile(file, request); + + // 2. 获取文件大小 + Integer fileSize = (int) file.getSize(); + + // 3. 创建资源记录 + AiolResource resource = new AiolResource(); + resource.setName(name.trim()); + resource.setDescription(description != null ? description.trim() : ""); + resource.setType(ResourceTypeConst.IMAGE); // 1:图片 + resource.setFileUrl(fileUrl); + resource.setFileSize(fileSize); + + // 4. 保存资源记录 + boolean saved = aiolResourceService.save(resource); + if (!saved) { + return Result.error("保存资源记录失败"); + } + + // 5. 创建课程与资源的关联关系 + entityLinkBizService.save( + EntityLinkConst.SourceType.COURSE, + courseId, + EntityLinkConst.TargetType.RESOURCE, + resource.getId() + ); + + log.info("图片上传成功: resourceId={}, courseId={}, name={}", + resource.getId(), courseId, name); + + return Result.OK(resource.getId()); + + } catch (Exception e) { + log.error("图片上传失败: courseId={}, name={}, error={}", + courseId, name, e.getMessage(), e); + return Result.error("图片上传失败: " + e.getMessage()); + } + } + @GetMapping("/course_materials") @Operation(summary = "查询课程课件", description = "根据课程ID、资源分类和资源名关键词查询课程相关资源") @IgnoreAuth @@ -430,6 +498,20 @@ public class AiolResourceController extends JeecgController replies; } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolDiscussion.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolDiscussion.java new file mode 100644 index 00000000..80cec3aa --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolDiscussion.java @@ -0,0 +1,64 @@ +package org.jeecg.modules.aiol.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: 讨论 + * @Author: jeecg-boot + * @Date: 2025-09-19 + * @Version: V1.0 + */ +@Data +@TableName("aiol_discussion") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description="讨论") +public class AiolDiscussion implements Serializable { + private static final long serialVersionUID = 1L; + + /**主键*/ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键") + private java.lang.String id; + /**讨论标题*/ + @Excel(name = "讨论标题", width = 15) + @Schema(description = "讨论标题") + private java.lang.String title; + /**讨论描述*/ + @Excel(name = "讨论描述", width = 15) + @Schema(description = "讨论描述") + private java.lang.String description; + /**创建人*/ + @Schema(description = "创建人") + private java.lang.String createBy; + /**创建日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建日期") + private java.util.Date createTime; + /**更新人*/ + @Schema(description = "更新人") + private java.lang.String updateBy; + /**更新日期*/ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新日期") + private java.util.Date updateTime; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolHomework.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolHomework.java index acbd53d4..9afc739b 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolHomework.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolHomework.java @@ -22,7 +22,7 @@ import lombok.experimental.Accessors; /** * @Description: 作业 * @Author: jeecg-boot - * @Date: 2025-08-31 + * @Date: 2025-09-19 * @Version: V1.0 */ @Data @@ -74,6 +74,20 @@ public class AiolHomework implements Serializable { @Dict(dicCode = "course_status") @Schema(description = "状态") private java.lang.Integer status; + /**是否允许补交*/ + @Excel(name = "是否允许补交", width = 15) + @Schema(description = "是否允许补交") + private java.lang.Integer allowMakeup; + /**补交截止时间*/ + @Excel(name = "补交截止时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @Schema(description = "补交截止时间") + private java.util.Date makeupTime; + /**作业通知时间*/ + @Excel(name = "作业通知时间", width = 15) + @Schema(description = "作业通知时间") + private java.lang.Integer notifyTime; /**创建人*/ @Schema(description = "创建人") private java.lang.String createBy; diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/AiolDiscussionMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/AiolDiscussionMapper.java new file mode 100644 index 00000000..107198a3 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/AiolDiscussionMapper.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.aiol.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.aiol.entity.AiolDiscussion; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: 讨论 + * @Author: jeecg-boot + * @Date: 2025-09-19 + * @Version: V1.0 + */ +public interface AiolDiscussionMapper extends BaseMapper { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/xml/AiolDiscussionMapper.xml b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/xml/AiolDiscussionMapper.xml new file mode 100644 index 00000000..7ff0ba2e --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/mapper/xml/AiolDiscussionMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolDiscussionService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolDiscussionService.java new file mode 100644 index 00000000..1d571db0 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolDiscussionService.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.aiol.service; + +import org.jeecg.modules.aiol.entity.AiolDiscussion; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: 讨论 + * @Author: jeecg-boot + * @Date: 2025-09-19 + * @Version: V1.0 + */ +public interface IAiolDiscussionService extends IService { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolHomeworkSubmitService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolHomeworkSubmitService.java index 39a9a3d9..ef3b94c6 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolHomeworkSubmitService.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/IAiolHomeworkSubmitService.java @@ -19,4 +19,9 @@ public interface IAiolHomeworkSubmitService extends IService List submitted(String studentId); Integer correct(String homeworkSubmitId, Integer score, String comment, String teacherId); + + /** + * 新增作业时创建预留空记录,用于查询作业列表 + */ + boolean createEmptySubmit(String homeworkId, String studentId); } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolDiscussionServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolDiscussionServiceImpl.java new file mode 100644 index 00000000..00b70010 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolDiscussionServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.aiol.service.impl; + +import org.jeecg.modules.aiol.entity.AiolDiscussion; +import org.jeecg.modules.aiol.mapper.AiolDiscussionMapper; +import org.jeecg.modules.aiol.service.IAiolDiscussionService; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +/** + * @Description: 讨论 + * @Author: jeecg-boot + * @Date: 2025-09-19 + * @Version: V1.0 + */ +@Service +public class AiolDiscussionServiceImpl extends ServiceImpl implements IAiolDiscussionService { + +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolHomeworkSubmitServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolHomeworkSubmitServiceImpl.java index 135751b8..546c0483 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolHomeworkSubmitServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/service/impl/AiolHomeworkSubmitServiceImpl.java @@ -83,4 +83,14 @@ public class AiolHomeworkSubmitServiceImpl extends ServiceImpl 0; + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionForm.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionForm.vue new file mode 100644 index 00000000..49e01beb --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionForm.vue @@ -0,0 +1,89 @@ + + + diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionList.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionList.vue new file mode 100644 index 00000000..2919c2be --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp/AiolDiscussionList.vue @@ -0,0 +1,44 @@ + + + + diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionData.ts b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionData.ts new file mode 100644 index 00000000..848bdc1c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionData.ts @@ -0,0 +1,14 @@ +import { render } from '@/common/renderUtils'; +//列表数据 +export const columns = [ + { + title: '讨论标题', + align:"center", + dataIndex: 'title' + }, + { + title: '讨论描述', + align:"center", + dataIndex: 'description' + }, +]; \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionForm.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionForm.vue new file mode 100644 index 00000000..5c891ea3 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionForm.vue @@ -0,0 +1,222 @@ + +{ +layout: 'default', +style: { +navigationStyle: 'custom', +navigationBarTitleText: '讨论', +}, +} + + + + + + diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionList.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionList.vue new file mode 100644 index 00000000..6fa99325 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/uniapp3/AiolDiscussionList.vue @@ -0,0 +1,148 @@ + +{ +layout: 'default', +style: { +navigationBarTitleText: '讨论', +navigationStyle: 'custom', +}, +} + + + + + + diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.api.ts b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.api.ts new file mode 100644 index 00000000..969dcbb9 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.api.ts @@ -0,0 +1,64 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/aiol/aiolDiscussion/list', + save='/aiol/aiolDiscussion/add', + edit='/aiol/aiolDiscussion/edit', + deleteOne = '/aiol/aiolDiscussion/delete', + deleteBatch = '/aiol/aiolDiscussion/deleteBatch', + importExcel = '/aiol/aiolDiscussion/importExcel', + exportXls = '/aiol/aiolDiscussion/exportXls', +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +/** + * 列表接口 + * @param params + */ +export const list = (params) => + defHttp.get({url: Api.list, params}); + +/** + * 删除单个 + */ +export const deleteOne = (params,handleSuccess) => { + return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); +} +/** + * 批量删除 + * @param params + */ +export const batchDelete = (params, handleSuccess) => { + createConfirm({ + iconType: 'warning', + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.data.ts b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.data.ts new file mode 100644 index 00000000..e3f5bba3 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussion.data.ts @@ -0,0 +1,56 @@ +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + { + title: '讨论标题', + align:"center", + dataIndex: 'title' + }, + { + title: '讨论描述', + align:"center", + dataIndex: 'description' + }, +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +]; +//表单数据 +export const formSchema: FormSchema[] = [ + { + label: '讨论标题', + field: 'title', + component: 'Input', + }, + { + label: '讨论描述', + field: 'description', + component: 'Input', + }, + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, +]; + +// 高级查询数据 +export const superQuerySchema = { + title: {title: '讨论标题',order: 0,view: 'text', type: 'string',}, + description: {title: '讨论描述',order: 1,view: 'text', type: 'string',}, +}; + +/** +* 流程表单调用这个方法获取formSchema +* @param param +*/ +export function getBpmFormSchema(_formData): FormSchema[]{ + // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema + return formSchema; +} \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussionList.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussionList.vue new file mode 100644 index 00000000..87f381aa --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolDiscussionList.vue @@ -0,0 +1,206 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/V20250919_1__menu_insert_AiolDiscussion.sql b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/V20250919_1__menu_insert_AiolDiscussion.sql new file mode 100644 index 00000000..05b43220 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/V20250919_1__menu_insert_AiolDiscussion.sql @@ -0,0 +1,26 @@ +-- 注意:该页面对应的前台目录为views/aiol文件夹下 +-- 如果你想更改到其他目录,请修改sql中component字段对应的值 + + +INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external) +VALUES ('2025091908381460460', NULL, '讨论', '/aiol/aiolDiscussionList', 'aiol/AiolDiscussionList', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 0, 0, 0, 0, NULL, '1', 0, 0, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0); + +-- 权限控制sql +-- 新增 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('2025091908381460461', '2025091908381460460', '添加讨论', NULL, NULL, 0, NULL, NULL, 2, 'aiol:aiol_discussion:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0, 0, '1', 0); +-- 编辑 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('2025091908381460462', '2025091908381460460', '编辑讨论', NULL, NULL, 0, NULL, NULL, 2, 'aiol:aiol_discussion:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0, 0, '1', 0); +-- 删除 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('2025091908381460463', '2025091908381460460', '删除讨论', NULL, NULL, 0, NULL, NULL, 2, 'aiol:aiol_discussion:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0, 0, '1', 0); +-- 批量删除 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('2025091908381460464', '2025091908381460460', '批量删除讨论', NULL, NULL, 0, NULL, NULL, 2, 'aiol:aiol_discussion:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0, 0, '1', 0); +-- 导出excel +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('2025091908381460465', '2025091908381460460', '导出excel_讨论', NULL, NULL, 0, NULL, NULL, 2, 'aiol:aiol_discussion:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0, 0, '1', 0); +-- 导入excel +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('2025091908381460466', '2025091908381460460', '导入excel_讨论', NULL, NULL, 0, NULL, NULL, 2, 'aiol:aiol_discussion:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2025-09-19 08:38:46', NULL, NULL, 0, 0, '1', 0); \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionForm.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionForm.vue new file mode 100644 index 00000000..12a4dee9 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionForm.vue @@ -0,0 +1,70 @@ + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionModal.vue b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionModal.vue new file mode 100644 index 00000000..b7addcb8 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/components/AiolDiscussionModal.vue @@ -0,0 +1,99 @@ + + + + + \ No newline at end of file diff --git a/jeecgboot-vue3/src/views/aiol/AiolHomework.data.ts b/jeecgboot-vue3/src/views/aiol/AiolHomework.data.ts index 4ee7f9c2..d20bd6b7 100644 --- a/jeecgboot-vue3/src/views/aiol/AiolHomework.data.ts +++ b/jeecgboot-vue3/src/views/aiol/AiolHomework.data.ts @@ -45,6 +45,21 @@ export const columns: BasicColumn[] = [ align:"center", dataIndex: 'status_dictText' }, + { + title: '是否允许补交', + align:"center", + dataIndex: 'allowMakeup' + }, + { + title: '补交截止时间', + align:"center", + dataIndex: 'makeupTime' + }, + { + title: '作业通知时间', + align:"center", + dataIndex: 'notifyTime' + }, ]; //查询数据 export const searchFormSchema: FormSchema[] = [ @@ -104,6 +119,25 @@ export const formSchema: FormSchema[] = [ dictCode:"course_status", type: "radio" }, + }, + { + label: '是否允许补交', + field: 'allowMakeup', + component: 'InputNumber', + }, + { + label: '补交截止时间', + field: 'makeupTime', + component: 'DatePicker', + componentProps: { + showTime: true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + }, + { + label: '作业通知时间', + field: 'notifyTime', + component: 'InputNumber', }, // TODO 主键隐藏字段,目前写死为ID { @@ -124,6 +158,9 @@ export const superQuerySchema = { startTime: {title: '开始时间',order: 5,view: 'datetime', type: 'string',}, endTime: {title: '结束时间',order: 6,view: 'datetime', type: 'string',}, status: {title: '状态',order: 7,view: 'number', type: 'number',dictCode: 'course_status',}, + allowMakeup: {title: '是否允许补交',order: 8,view: 'number', type: 'number',}, + makeupTime: {title: '补交截止时间',order: 9,view: 'datetime', type: 'string',}, + notifyTime: {title: '作业通知时间',order: 10,view: 'number', type: 'number',}, }; /**