diff --git a/src/main/java/com/greenorange/promotion/constant/SystemConstant.java b/src/main/java/com/greenorange/promotion/constant/SystemConstant.java index 49b1d77..8ebfe0f 100644 --- a/src/main/java/com/greenorange/promotion/constant/SystemConstant.java +++ b/src/main/java/com/greenorange/promotion/constant/SystemConstant.java @@ -7,4 +7,10 @@ public interface SystemConstant { */ String VERIFICATION_CODE = "verificationCode"; + + /** + * 文件公共前缀 + */ + String FILE_COMMON_PREFIX = "http://27.30.77.229:9091/file/download/"; + } diff --git a/src/main/java/com/greenorange/promotion/controller/course/CourseController.java b/src/main/java/com/greenorange/promotion/controller/course/CourseController.java index c4d0cc9..7ba3389 100644 --- a/src/main/java/com/greenorange/promotion/controller/course/CourseController.java +++ b/src/main/java/com/greenorange/promotion/controller/course/CourseController.java @@ -12,15 +12,21 @@ import com.greenorange.promotion.common.ResultUtils; import com.greenorange.promotion.constant.UserConstant; import com.greenorange.promotion.model.dto.CommonBatchRequest; import com.greenorange.promotion.model.dto.CommonRequest; +import com.greenorange.promotion.model.dto.CommonStringRequest; import com.greenorange.promotion.model.dto.course.CourseAddRequest; +import com.greenorange.promotion.model.dto.course.CourseQrcodeAddRequest; import com.greenorange.promotion.model.dto.course.CourseQueryRequest; import com.greenorange.promotion.model.dto.course.CourseUpdateRequest; import com.greenorange.promotion.model.entity.Course; import com.greenorange.promotion.model.entity.CourseChapter; +import com.greenorange.promotion.model.vo.course.CourseCardVO; +import com.greenorange.promotion.model.vo.course.CourseDetailVO; import com.greenorange.promotion.model.vo.course.CourseVO; +import com.greenorange.promotion.model.vo.courseChapter.CourseChapterVO; import com.greenorange.promotion.service.common.CommonService; import com.greenorange.promotion.service.course.CourseChapterService; import com.greenorange.promotion.service.course.CourseService; +import com.greenorange.promotion.service.wechat.WechatGetQrcodeService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -52,6 +58,64 @@ public class CourseController { @Resource private CourseChapterService courseChapterService; + @Resource + private WechatGetQrcodeService wechatGetQrcodeService; + + + /** + * 小程序端用户根据类别查看课程列表 + * @param commonStringRequest 课程类别 + * @return 课程信息列表 + */ + @PostMapping("query/type") + @Operation(summary = "小程序端用户根据类别查看课程列表", description = "参数:课程添加请求体,权限:管理员,方法名:miniQueryCourseByType") + @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE) + @SysLog(title = "课程管理", content = "小程序端用户根据类别查看课程列表") + public BaseResponse> miniQueryCourseByType(@Valid @RequestBody CommonStringRequest commonStringRequest) { + String courseType = commonStringRequest.getTemplateString(); + LambdaQueryWrapper lambdaQueryWrapper = commonService.buildQueryWrapperByField(Course::getType, courseType, courseService); + List courseList = courseService.list(lambdaQueryWrapper); + List courseCardVOS = commonService.convertList(courseList, CourseCardVO.class); + return ResultUtils.success(courseCardVOS); + } + + + /** + * 小程序端用户根据id查询课程详情 + * @param commonRequest 课程id + * @return 课程信息列表 + */ + @PostMapping("query/id") + @Operation(summary = "小程序端用户根据id查询课程详情", description = "参数:课程id,权限:管理员,方法名:miniQueryCourseById") + @SysLog(title = "课程管理", content = "小程序端用户根据id查询课程详情") + public BaseResponse miniQueryCourseById(@Valid @RequestBody CommonRequest commonRequest) { + Long id = commonRequest.getId(); + Course course = courseService.getById(id); + CourseDetailVO courseDetailVO = commonService.copyProperties(course, CourseDetailVO.class); + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(CourseChapter::getCourseId, id); + List courseChapterList = courseChapterService.list(lambdaQueryWrapper); + List courseChapterVOS = commonService.convertList(courseChapterList, CourseChapterVO.class); + courseDetailVO.setCourseChapters(courseChapterVOS); + return ResultUtils.success(courseDetailVO); + } + + + /** + * 小程序端用户生成推广码 + * @param courseQrcodeAddRequest 课程id + * @return 课程信息列表 + */ + @PostMapping("generate/qrcode") + @Operation(summary = "小程序端用户生成推广码", description = "参数:课程id,权限:管理员,方法名:miniGenerateQrcode") + @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE) + @SysLog(title = "课程管理", content = "小程序端用户生成推广码") + public BaseResponse miniGenerateQrcode(@Valid @RequestBody CourseQrcodeAddRequest courseQrcodeAddRequest) throws Exception { + String videoView = wechatGetQrcodeService.getWxCourseQrCode(courseQrcodeAddRequest); + return ResultUtils.success(videoView); + } + + /** * web端管理员添加课程 * @param courseAddRequest 课程添加请求体 diff --git a/src/main/java/com/greenorange/promotion/controller/wechat/WechatGetQrcodeController.java b/src/main/java/com/greenorange/promotion/controller/wechat/WechatGetQrcodeController.java index 2e15abc..1ec95c7 100644 --- a/src/main/java/com/greenorange/promotion/controller/wechat/WechatGetQrcodeController.java +++ b/src/main/java/com/greenorange/promotion/controller/wechat/WechatGetQrcodeController.java @@ -12,6 +12,7 @@ import com.greenorange.promotion.common.ResultUtils; import com.greenorange.promotion.config.WxAccessToken; import com.greenorange.promotion.constant.UserConstant; import com.greenorange.promotion.model.dto.CommonStringRequest; +import com.greenorange.promotion.model.dto.course.CourseQrcodeAddRequest; import com.greenorange.promotion.service.wechat.WechatGetQrcodeService; import com.greenorange.promotion.utils.QRCodeUtil; import io.swagger.v3.oas.annotations.Hidden; @@ -72,7 +73,7 @@ public class WechatGetQrcodeController { * @return * @throws IOException */ -// @Hidden + @Hidden @PostMapping("/get/qrcode") @Operation(summary = "微信小程序获取二维码", description = "参数:无, 权限:所有人, 方法名:getQrcode") // @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE) @@ -88,13 +89,12 @@ public class WechatGetQrcodeController { * @return * @throws IOException */ -// @Hidden + @Hidden @PostMapping("/get/course/qrcode") @Operation(summary = "微信小程序获取课程码", description = "参数:无, 权限:所有人, 方法名:getCourseQrcode") // @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE) - public BaseResponse getCourseQrcode(@Valid @RequestBody CommonStringRequest commonStringRequest) throws Exception { - String inviteCode = commonStringRequest.getTemplateString(); - String view = wechatGetQrcodeService.getWxCourseQrCode(inviteCode); + public BaseResponse getCourseQrcode(@Valid @RequestBody CourseQrcodeAddRequest courseQrcodeAddRequest) throws Exception { + String view = wechatGetQrcodeService.getWxCourseQrCode(courseQrcodeAddRequest); return ResultUtils.success(view); } diff --git a/src/main/java/com/greenorange/promotion/model/dto/course/CourseQrcodeAddRequest.java b/src/main/java/com/greenorange/promotion/model/dto/course/CourseQrcodeAddRequest.java new file mode 100644 index 0000000..bdffed3 --- /dev/null +++ b/src/main/java/com/greenorange/promotion/model/dto/course/CourseQrcodeAddRequest.java @@ -0,0 +1,78 @@ +package com.greenorange.promotion.model.dto.course; + +import com.greenorange.promotion.annotation.EnumValue; +import com.greenorange.promotion.model.enums.CourseTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 课程推广码生成请求体 + */ +@Data +@Schema(description = "课程推广码生成请求体", requiredProperties = { + "id", + "name", + "type", + "image", + "originPrice", + "discountPrice", + "invitationCode" +}) +public class CourseQrcodeAddRequest implements Serializable { + /** + * 课程ID + */ + @Min(value = 1L, message = "课程ID ID不能小于1") + @Schema(description = "课程ID", example = "1") + private Long id; + + /** + * 课程名称 + */ + @NotBlank(message = "课程名称不能为空") + @Schema(description = "课程名称", example = "数据分析工程师训练营") + private String name; + + /** + * 课程类别[考公考研,自媒体,财经] + */ + @NotBlank(message = "课程类别不能为空") + @EnumValue(enumClass = CourseTypeEnum.class) + @Schema(description = "课程类别[考公考研,自媒体,财经]", example = "自媒体") + private String type; + + /** + * 课程图片URL + */ + @NotBlank(message = "课程图片URL不能为空") + @Schema(description = "课程图片URL", example = "324IEHJDE") + private String image; + + /** + * 课程原价 + */ + @DecimalMin(value = "0.0", message = "课程原价不能小于0") + @Schema(description = "课程原价", example = "3499") + private BigDecimal originPrice; + + /** + * 折扣价格 + */ + @DecimalMin(value = "0.0", message = "折扣价格不能小于0") + @Schema(description = "折扣价格", example = "2499") + private BigDecimal discountPrice; + + /** + * 邀请码 + */ + @Schema(description = "邀请码", example = "666999") + @NotBlank(message = "邀请码不能为空") + private String invitationCode; + +} diff --git a/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoRegisterRequest.java b/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoRegisterRequest.java index b7b8df5..e190a15 100644 --- a/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoRegisterRequest.java +++ b/src/main/java/com/greenorange/promotion/model/dto/userInfo/UserInfoRegisterRequest.java @@ -42,6 +42,7 @@ public class UserInfoRegisterRequest implements Serializable { * 邀请码 */ @Schema(description = "邀请码", example = "666999") + @NotBlank(message = "邀请码不能为空") private String invitationCode; /** diff --git a/src/main/java/com/greenorange/promotion/model/entity/CourseChapter.java b/src/main/java/com/greenorange/promotion/model/entity/CourseChapter.java index b7235c7..a7bf0a6 100644 --- a/src/main/java/com/greenorange/promotion/model/entity/CourseChapter.java +++ b/src/main/java/com/greenorange/promotion/model/entity/CourseChapter.java @@ -29,12 +29,12 @@ public class CourseChapter implements Serializable { /** * 章节时长(格式可自定义,如"00:10:00") */ - private String duration; + private Long duration; /** * 试看权限 */ - private Object permissions; + private String permissions; /** * 视频文件 view 值 diff --git a/src/main/java/com/greenorange/promotion/model/vo/course/CourseCardVO.java b/src/main/java/com/greenorange/promotion/model/vo/course/CourseCardVO.java new file mode 100644 index 0000000..2d675cd --- /dev/null +++ b/src/main/java/com/greenorange/promotion/model/vo/course/CourseCardVO.java @@ -0,0 +1,54 @@ +package com.greenorange.promotion.model.vo.course; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Schema(description = "课程卡片 视图对象") +public class CourseCardVO implements Serializable { + + /** + * 课程ID + */ + @Schema(description = "课程ID", example = "1") + private Long id; + + /** + * 课程名称 + */ + @Schema(description = "课程名称", example = "数据分析工程师训练营") + private String name; + + /** + * 课程类别[考公考研,自媒体,财经] + */ + @Schema(description = "课程类别[考公考研,自媒体,财经]", example = "自媒体") + private String type; + + /** + * 课程图片URL + */ + @Schema(description = "课程图片URL", example = "324IEHJDE") + private String image; + + /** + * 折扣价格 + */ + @Schema(description = "折扣价格", example = "2499") + private BigDecimal discountPrice; + + /** + * 已下单人数 + */ + @Schema(description = "已下单人数", example = "100") + private Integer orderCount; + + + @Serial + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/greenorange/promotion/model/vo/course/CourseDetailVO.java b/src/main/java/com/greenorange/promotion/model/vo/course/CourseDetailVO.java new file mode 100644 index 0000000..e5d9056 --- /dev/null +++ b/src/main/java/com/greenorange/promotion/model/vo/course/CourseDetailVO.java @@ -0,0 +1,75 @@ +package com.greenorange.promotion.model.vo.course; + +import com.greenorange.promotion.model.vo.courseChapter.CourseChapterVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + + +@Data +@Schema(description = "课程详情 视图对象") +public class CourseDetailVO implements Serializable { + + /** + * 课程ID + */ + @Schema(description = "课程ID", example = "1") + private Long id; + + /** + * 课程名称 + */ + @Schema(description = "课程名称", example = "数据分析工程师训练营") + private String name; + + /** + * 课程类别[考公考研,自媒体,财经] + */ + @Schema(description = "课程类别[考公考研,自媒体,财经]", example = "自媒体") + private String type; + + /** + * 课程概述(富文本) + */ + @Schema(description = "课程概述(富文本)", example = "富文本") + private String detail; + + /** + * 推广码说明(富文本) + */ + @Schema(description = "推广码说明(富文本)", example = "富文本") + private String promoCodeDesc; + + /** + * 课程图片URL + */ + @Schema(description = "课程图片URL", example = "324IEHJDE") + private String image; + + /** + * 课程原价 + */ + @Schema(description = "课程原价", example = "3499") + private BigDecimal originPrice; + + /** + * 折扣价格 + */ + @Schema(description = "折扣价格", example = "2499") + private BigDecimal discountPrice; + + /** + * 课程章节 + */ + @Schema(description = "课程章节") + private List courseChapters; + + + @Serial + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/greenorange/promotion/service/wechat/WechatGetQrcodeService.java b/src/main/java/com/greenorange/promotion/service/wechat/WechatGetQrcodeService.java index 362d89f..ffd4d20 100644 --- a/src/main/java/com/greenorange/promotion/service/wechat/WechatGetQrcodeService.java +++ b/src/main/java/com/greenorange/promotion/service/wechat/WechatGetQrcodeService.java @@ -1,6 +1,7 @@ package com.greenorange.promotion.service.wechat; import com.greenorange.promotion.config.WxAccessToken; +import com.greenorange.promotion.model.dto.course.CourseQrcodeAddRequest; import java.io.IOException; @@ -27,5 +28,5 @@ public interface WechatGetQrcodeService { /** * 微信小程序获取课程码 */ - String getWxCourseQrCode(String inviteCode) throws Exception; + String getWxCourseQrCode(CourseQrcodeAddRequest courseQrcodeAddRequest) throws Exception; } diff --git a/src/main/java/com/greenorange/promotion/service/wechat/impl/WechatGetQrcodeServiceImpl.java b/src/main/java/com/greenorange/promotion/service/wechat/impl/WechatGetQrcodeServiceImpl.java index 1a0e8ef..d658ee3 100644 --- a/src/main/java/com/greenorange/promotion/service/wechat/impl/WechatGetQrcodeServiceImpl.java +++ b/src/main/java/com/greenorange/promotion/service/wechat/impl/WechatGetQrcodeServiceImpl.java @@ -12,7 +12,9 @@ import com.freewayso.image.combiner.enums.ZoomMode; import com.google.gson.Gson; import com.greenorange.promotion.common.ErrorCode; import com.greenorange.promotion.config.WxAccessToken; +import com.greenorange.promotion.constant.SystemConstant; import com.greenorange.promotion.exception.BusinessException; +import com.greenorange.promotion.model.dto.course.CourseQrcodeAddRequest; import com.greenorange.promotion.model.entity.FileInfo; import com.greenorange.promotion.service.file.FileInfoService; import com.greenorange.promotion.service.wechat.WechatGetQrcodeService; @@ -197,14 +199,14 @@ public class WechatGetQrcodeServiceImpl implements WechatGetQrcodeService { */ @Override @Transactional(rollbackFor = Exception.class) - public String getWxCourseQrCode(String inviteCode) throws Exception { + public String getWxCourseQrCode(CourseQrcodeAddRequest courseQrcodeAddRequest) throws Exception { String accessToken = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY); if (accessToken == null) { accessToken = this.getAccessToken().getAccess_token(); } Map param = new HashMap<>(); param.put("page", "pages/loginModule/register/register"); - param.put("scene", "invitationCode=" + inviteCode); + param.put("scene", "invitationCode=" + courseQrcodeAddRequest.getInvitationCode()); param.put("width", 430); param.put("check_path", false); param.put("env_version", "develop"); @@ -216,9 +218,9 @@ public class WechatGetQrcodeServiceImpl implements WechatGetQrcodeService { .execute() .bodyBytes(); - String courseTitle = "【早鸟42折】掌握CAD技能实战技能实战技能实战技能实战工作训练营"; - String originalPrice = "2680元"; - String discountPrice = "1680"; + String courseTitle = courseQrcodeAddRequest.getName(); + String originalPrice = String.valueOf(courseQrcodeAddRequest.getOriginPrice()); + String discountPrice = String.valueOf(courseQrcodeAddRequest.getDiscountPrice()); String discountText = "元券后价"; String FontType = "Microsoft YaHei UI"; int FontStyle = Font.PLAIN; @@ -228,7 +230,7 @@ public class WechatGetQrcodeServiceImpl implements WechatGetQrcodeService { ImageCombiner combiner = new ImageCombiner(blankUrl, 341, 391, ZoomMode.WidthHeight, OutputFormat.PNG); // 加载课程图片 - String courseUrl = "https://img.picui.cn/free/2025/06/22/6856ef5908d4b.jpg"; + String courseUrl = SystemConstant.FILE_COMMON_PREFIX + courseQrcodeAddRequest.getImage(); BufferedImage courseImage = ImageIO.read(new URL(courseUrl)); // Graphics2D graphics = courseImage.createGraphics(); @@ -314,18 +316,6 @@ public class WechatGetQrcodeServiceImpl implements WechatGetQrcodeService { return biz + "-" + view; } - public static void main(String[] args) { - // 获取本地图形环境 - GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - // 列出所有可用字体家族名 - String[] families = ge.getAvailableFontFamilyNames(); - - // 打印全部字体(可选) - System.out.println("=== Available Font Families ==="); - Arrays.stream(families).forEach(System.out::println); - } - -