diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseController.java index f1626c71..d503a0fb 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseController.java @@ -19,6 +19,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.shiro.IgnoreAuth; import org.jeecg.modules.aiol.dto.CourseWithTeacherInfo; +import org.jeecg.modules.aiol.dto.AiolCourseSaveDTO; import org.jeecg.modules.aiol.dto.TeacherInfo; import org.jeecg.modules.aiol.entity.*; import org.jeecg.modules.aiol.service.IAiolCourseService; @@ -27,6 +28,7 @@ import org.jeecg.modules.aiol.service.IAiolEntityPermissionService; import org.jeecg.modules.aiol.constant.EntityPermissionConst; import org.jeecg.modules.aiol.mapper.AiolCourseSignupMapper; import org.jeecg.modules.aiol.mapper.AiolCourseTeacherMapper; +import org.jeecg.modules.aiol.mapper.AiolEntityLinkMapper; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.mapper.SysUserMapper; import org.springframework.beans.BeanUtils; @@ -47,6 +49,7 @@ 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 org.springframework.transaction.annotation.Transactional; import com.alibaba.fastjson.JSON; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; @@ -100,8 +103,21 @@ public class AiolCourseController extends JeecgController add(@RequestBody AiolCourse aiolCourse) { - aiolCourseService.save(aiolCourse); + @Transactional(rollbackFor = Exception.class) + public Result add(@RequestBody AiolCourseSaveDTO dto) { + aiolCourseService.save(dto); + + String categoryId = dto.getCategoryId(); + if (categoryId != null && !categoryId.trim().isEmpty()) { + AiolEntityLink link = new AiolEntityLink(); + link.setSourceType("course_category"); + link.setSourceId(categoryId); + link.setTargetType("course"); + link.setTargetId(dto.getId()); + link.setCreateBy(dto.getCreateBy()); + link.setCreateTime(new Date()); + entityLinkMapper.insert(link); + } return Result.OK("添加成功!"); } @@ -116,8 +132,27 @@ public class AiolCourseController extends JeecgController edit(@RequestBody AiolCourse aiolCourse) { - aiolCourseService.updateById(aiolCourse); + @Transactional(rollbackFor = Exception.class) + public Result edit(@RequestBody AiolCourseSaveDTO dto) { + aiolCourseService.updateById(dto); + + QueryWrapper deleteWrapper = new QueryWrapper<>(); + deleteWrapper.eq("target_type", "course").eq("target_id", dto.getId()) + .eq("source_type", "course_category"); + entityLinkMapper.delete(deleteWrapper); + + String categoryId = dto.getCategoryId(); + if (categoryId != null && !categoryId.trim().isEmpty()) { + AiolEntityLink link = new AiolEntityLink(); + link.setSourceType("course_category"); + link.setSourceId(categoryId); + link.setTargetType("course"); + link.setTargetId(dto.getId()); + link.setCreateBy(dto.getUpdateBy()); + link.setCreateTime(new Date()); + entityLinkMapper.insert(link); + } + return Result.OK("编辑成功!"); } @@ -205,6 +240,8 @@ public class AiolCourseController extends JeecgController { @Autowired private IAiolUserFollowService aiolUserFollowService; + @Autowired + private ISysBaseAPI sysBaseApi; /** * 分页列表查询 @@ -154,6 +161,97 @@ public class AiolUserFollowController extends JeecgController follow(@RequestParam(name="followedId", required=true) String followedId, + HttpServletRequest request) { + try { + // 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("用户未登录或登录已过期"); + } + + // 2. 检查是否已经关注 + QueryWrapper checkWrapper = new QueryWrapper<>(); + checkWrapper.eq("follower_id", sysUser.getId()) + .eq("followed_id", followedId); + AiolUserFollow existingFollow = aiolUserFollowService.getOne(checkWrapper); + + if (existingFollow != null) { + return Result.error("已经关注过该用户"); + } + + // 3. 检查是否关注自己 + if (sysUser.getId().equals(followedId)) { + return Result.error("不能关注自己"); + } + + // 4. 创建关注关系 + AiolUserFollow userFollow = new AiolUserFollow(); + userFollow.setFollowerId(sysUser.getId()); + userFollow.setFollowedId(followedId); + userFollow.setCreateBy(sysUser.getUsername()); + userFollow.setCreateTime(new Date()); + + aiolUserFollowService.save(userFollow); + return Result.OK("关注成功!"); + + } catch (Exception e) { + log.error("关注用户失败: followedId={}, error={}", followedId, e.getMessage(), e); + return Result.error("关注失败: " + e.getMessage()); + } + } + + /** + * 取消关注用户 + * + * @param followedId 被关注者ID + * @param request + * @return + */ + @AutoLog(value = "关注关系-取消关注用户") + @Operation(summary="取消关注用户", description = "当前登录用户取消关注指定用户") + @DeleteMapping(value = "/unfollow") + public Result unfollow(@RequestParam(name="followedId", required=true) String followedId, + HttpServletRequest request) { + try { + // 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("用户未登录或登录已过期"); + } + + // 2. 查找关注关系 + QueryWrapper deleteWrapper = new QueryWrapper<>(); + deleteWrapper.eq("follower_id", sysUser.getId()) + .eq("followed_id", followedId); + + boolean removed = aiolUserFollowService.remove(deleteWrapper); + if (removed) { + return Result.OK("取消关注成功!"); + } else { + return Result.error("未找到关注关系"); + } + + } catch (Exception e) { + log.error("取消关注用户失败: followedId={}, error={}", followedId, e.getMessage(), e); + return Result.error("取消关注失败: " + e.getMessage()); + } + } + /** * 导出excel * diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSaveDTO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSaveDTO.java new file mode 100644 index 00000000..89d7c4d1 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSaveDTO.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.aiol.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.jeecg.modules.aiol.entity.AiolCourse; + +@Data +@EqualsAndHashCode(callSuper = false) +@Schema(description = "课程保存DTO,扩展课程分类") +public class AiolCourseSaveDTO extends AiolCourse { + + @Schema(description = "课程分类ID") + private String categoryId; +} + +