From 25743ef4cfb9da0be8d3e488c93f5429ffd02f8a Mon Sep 17 00:00:00 2001 From: 44323 <443237572@qq.com> Date: 星期二, 21 五月 2024 14:21:25 +0800 Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/DolphinEnglish --- ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/TGoodsVO.java | 233 ++++ ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TIntegralRecordMapper.java | 13 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java | 31 ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml | 17 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodQueryDTO.java | 33 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITOrderService.java | 8 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java | 38 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java | 16 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java | 52 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java | 17 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java | 40 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java | 65 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TOrderServiceImpl.java | 6 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameRecordService.java | 9 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java | 61 + ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java | 15 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java | 98 ++ ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java | 11 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java | 174 +++ ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/request/RegisterPhoneRequest.java | 22 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserService.java | 14 ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java | 16 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameRecordServiceImpl.java | 18 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TGoodsMapper.java | 11 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/task/StudyRecordTimedTask.java | 44 ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java | 1 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java | 68 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Region.java | 21 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java | 97 + ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java | 7 ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/factory/TManagementFallbackFactory.java | 3 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStudyMapper.java | 12 ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml | 14 ruoyi-common/ruoyi-common-redis/pom.xml | 7 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TGameRecord.java | 21 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TOrderMapper.java | 7 ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java | 69 + ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TOrderMapper.xml | 3 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/utils/SendMsgUtils.java | 42 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java | 120 ++ ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java | 84 + ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java | 10 ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml | 49 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITIntegralRecordService.java | 21 ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TUserController.java | 16 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java | 28 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteGameDTO.java | 50 + ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRegionService.java | 6 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java | 54 + ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TProtocolController.java | 26 ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TPageController.java | 26 ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java | 1 ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/RecipientMapper.xml | 5 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteStudyDTO.java | 26 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RedisConstants.java | 33 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TIntegralRecordServiceImpl.java | 21 ruoyi-service/ruoyi-goods/pom.xml | 12 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java | 509 +++++++++- ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java | 8 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java | 310 +++-- ruoyi-service/ruoyi-study/pom.xml | 6 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java | 9 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java | 30 63 files changed, 2,535 insertions(+), 359 deletions(-) diff --git a/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java b/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java index 6e59292..76f4cfd 100644 --- a/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java +++ b/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java @@ -16,8 +16,7 @@ public class GoodsFallbackFactory implements FallbackFactory<GoodsClient> { @Override - public GoodsClient create(Throwable cause) - { + public GoodsClient create(Throwable cause) { return new GoodsClient() { @Override @@ -69,6 +68,11 @@ public R<List<TGoodsType>> getGoodsInfo() { return R.fail("获取商品类型列表" + cause.getMessage()); } + + @Override + public R<List<TGoodsVO>> goodRecommend(String userId) { + return R.fail("获取商品推荐列表" + cause.getMessage()); + } }; } } diff --git a/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java b/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java index 53a5168..e953e27 100644 --- a/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java +++ b/ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java @@ -10,7 +10,10 @@ import com.ruoyi.goods.api.model.TGoodsVO; import io.swagger.annotations.ApiOperation; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import java.util.List; @@ -42,4 +45,15 @@ @PostMapping("/base/goods/getGoodsTypeList") R<List<TGoodsType>> getGoodsInfo(); + + /** + * 可兑换商品推荐 + * + * @param userId 用户id + * @return 推荐商品信息 + */ + @GetMapping("/goodRecommend") + @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"}) + R<List<TGoodsVO>> goodRecommend(String userId); + } diff --git a/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/factory/TManagementFallbackFactory.java b/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/factory/TManagementFallbackFactory.java index 82dc9c2..54bb73c 100644 --- a/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/factory/TManagementFallbackFactory.java +++ b/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/factory/TManagementFallbackFactory.java @@ -16,7 +16,7 @@ /** * 门店服务降级处理 - * + * * @author ruoyi */ @Component @@ -47,6 +47,7 @@ public R addFeedBack(TFeedback dto) { return R.fail("家长端发布意见反馈失败"+cause.getMessage()); } + }; } } diff --git a/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java b/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java index 16601be..e56667b 100644 --- a/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java +++ b/ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java @@ -21,6 +21,7 @@ @PostMapping(value = "/tSysSet/getPage1") R<List<TPage>> getPage1(); + @PostMapping("/tUser/getVipSet1") R<List<TVipSet>> getVipSet1(); diff --git a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java index cffb7e4..7d60d21 100644 --- a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java +++ b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java @@ -2,6 +2,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.page.PageInfo; +import com.ruoyi.study.api.domain.TUser; import com.ruoyi.study.api.dto.*; import com.ruoyi.study.api.feignClient.StudyClient; import com.ruoyi.study.api.model.TStory; @@ -123,6 +124,16 @@ public R updateState1(Integer id, Integer state) { return R.fail("修改故事状态失败" + cause.getMessage()); } + + @Override + public R<TUser> userInfo() { + return R.fail("获取用户信息失败" + cause.getMessage()); + } + + @Override + public R<Boolean> addIntegralDetail(String integral, String method) { + return R.fail("生成积分明细信息失败" + cause.getMessage()); + } }; } } diff --git a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java index bfe4919..e73edc1 100644 --- a/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java +++ b/ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java @@ -2,8 +2,8 @@ import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.PageInfo; +import com.ruoyi.study.api.domain.TUser; import com.ruoyi.study.api.dto.*; import com.ruoyi.study.api.factory.StudyFallbackFactory; import com.ruoyi.study.api.model.TStory; @@ -12,10 +12,7 @@ import com.ruoyi.study.api.vo.*; import io.swagger.annotations.ApiOperation; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -24,48 +21,64 @@ @PostMapping("/base/user/vipBack/{id}") R vipBack(@PathVariable("id") Integer id); + @PostMapping("/base/user/userList") R<PageInfo<AppUserVO>> couponReceive(@RequestBody AppUserQuery query); + @PostMapping("/base/user/getUserInfo") - R<UserInfoVO> getUserInfo(@RequestBody UserInfoQuery dto); + R<UserInfoVO> getUserInfo(@RequestBody UserInfoQuery dto); + @PostMapping("/base/user/freeze/{id}") - R freeze(@PathVariable("id") Integer id); + R freeze(@PathVariable("id") Integer id); + @PostMapping("/base/user/vipOrderList") - R<PageInfo<VipOrderVO>> vipOrderList(@RequestBody AppUserQuery query); + R<PageInfo<VipOrderVO>> vipOrderList(@RequestBody AppUserQuery query); + /** * 选择故事列表查询 + * * @param query * @return */ @PostMapping("/base/study/storyList") R<PageInfo<TStory>> storyList(@RequestBody ChoiceStory query); + /** * 选择题目列表查询 + * * @param query * @return */ @PostMapping("/base/study/subjectList") R<PageInfo<TSubject>> subjectList(@RequestBody ChoiceSubject query); + /** * 新增/修改学习类型配置 + * * @return */ @PostMapping("/base/study/addStudySet") - R<Object> addStudySet(@RequestBody AddStudySetDTO dto); + R<Object> addStudySet(@RequestBody AddStudySetDTO dto); + /** * 通过类型、周目、day查询学习配置 + * * @return */ @PostMapping("/base/study/getStudySet") R<StudyVO> getStudySet(@RequestBody StudyDTO dto); + /** * 学习类型列表查询 + * * @return */ @PostMapping("/base/study/getStudyList") R<List<StudyListVO>> getStudyList(); + /** * 添加周目 + * * @return */ @PostMapping("/base/study/addWeek") @@ -73,19 +86,24 @@ /** * 题目管理列表查询 + * * @param query * @return */ @PostMapping("/base/tSubject/subjectList") R<PageInfo<SubjectVO>> subjectList(@RequestBody SubjectQuery query); + /** * 题目管理添加 + * * @return */ @PostMapping("/base/tSubject/add") - R add(@RequestBody SubjectDTO dto) ; + R add(@RequestBody SubjectDTO dto); + /** * 题目管理编辑 + * * @return */ @PostMapping("/base/tSubject/update") @@ -93,13 +111,16 @@ /** * 查看详情 + * * @param id * @return */ @PostMapping("/base/tSubject/getInfo") R<SubjectDTO> getInfo(@RequestParam("id") Integer id); + /** * 修改题目状态 + * * @param id * @return */ @@ -108,6 +129,7 @@ /** * 故事管理列表查询 + * * @param query * @return */ @@ -116,20 +138,25 @@ /** * 故事管理添加 + * * @param dto * @return */ @PostMapping("/base/tStory/add") R add(@RequestBody StoryDTO dto); + /** * 故事管理编辑 + * * @param dto * @return */ @PostMapping("/base/tStory/update") R update(@RequestBody StoryDTO dto); + /** * 故事管理查看详情 + * * @return */ @PostMapping("/base/tStory/getInfo") @@ -137,10 +164,30 @@ /** * 故事管理修改状态 + * * @param id * @param state * @return */ @PostMapping("/base/tStory/updateState/{id}/{state}") - R updateState1(@PathVariable("id") Integer id,@PathVariable("state")Integer state); + R updateState1(@PathVariable("id") Integer id, @PathVariable("state") Integer state); + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("/base/user/userInfo") + @ApiOperation(value = "用户详情", tags = {"用户详情"}) + R<TUser> userInfo(); + + /** + * 生成积分明细-用于远程调用 + * + * @param integral 积分变动信息 + * @param method 变动源 + */ + @GetMapping("/base/study/addIntegralDetail") + R<Boolean> addIntegralDetail(@RequestParam("integral") String integral, @RequestParam("method") String method); + } diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java index d79784a..b9f650b 100644 --- a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java @@ -44,6 +44,7 @@ @Autowired private SysUserClient userClient; + @PostMapping("login") public R<?> login(@RequestBody LoginBody form) { diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java index 56f106e..22aa0ef 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java @@ -2,11 +2,10 @@ /** * 通用常量信息 - * + * * @author ruoyi */ -public class Constants -{ +public class Constants { /** * UTF-8 字符集 */ @@ -120,7 +119,7 @@ /** * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) */ - public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" }; + public static final String[] JOB_WHITELIST_STR = {"com.ruoyi"}; /** * 时间格式化 @@ -131,6 +130,47 @@ /** * 定时任务违规的字符 */ - public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", - "org.springframework", "org.apache", "com.ruoyi.common.core.utils.file" }; + public static final String[] JOB_ERROR_STR = {"java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.ruoyi.common.core.utils.file"}; + + /** + * 60数字 + */ + public static final Integer SIXTY = 60; + + /** + * 1000数字 + */ + public static final Integer ONE_THOUSAND = 1000; + + /** + * 积分明细 符号 - + */ + public static final String BURDEN = "-"; + + /** + * 积分明细来源 商城消费 + */ + public static final String SHOPPING_CONSUME = "商城消费"; + + /** + * 手机号码正则 + */ + public static final String PHONE = ("^((13[0-9])|(14[0,1,4-9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0-8])|(18[0-9])|(19[0-3,5-9]))\\d{8}$"); + + /** + * 日 + */ + public static final String DAY = "day"; + + /** + * 周 + */ + public static final String WEEK = "week"; + + /** + * 月 + */ + public static final String MONTH = "month"; + } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RedisConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RedisConstants.java new file mode 100644 index 0000000..c01be78 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/RedisConstants.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.core.constant; + +/** + * redis key常量 + * + * @author HJL + * @version 1.0 + * @since 2024-05-17 10:26 + */ +public class RedisConstants { + + /** + * 学习端 验证码登录key + */ + public final static String PHONE_CODE = "phone_code:"; + + /** + * 省市区三级树 + */ + public final static String ADDRESS_TREE = "regin_tree"; + + /** + * 商品库存key前缀 + */ + public final static String GOOD_STOCK = "good_stock:%s"; + + /** + * 游戏项目 + */ + public final static String HEARING_TREE = "game_subject"; + + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java index e0e99f4..47a5658 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java @@ -1,12 +1,13 @@ package com.ruoyi.common.core.utils; -import java.util.Map; import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.TokenConstants; import com.ruoyi.common.core.text.Convert; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; + +import java.util.Map; /** * Jwt工具类 @@ -64,6 +65,18 @@ } /** + * 学习端根据令牌获取用户标识 + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserKeyStudy(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.USER_STUDY_KEY); + } + + /** * 根据令牌获取用户标识 * * @param claims 身份信息 diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml index 97c986b..32b7f96 100644 --- a/ruoyi-common/ruoyi-common-redis/pom.xml +++ b/ruoyi-common/ruoyi-common-redis/pom.xml @@ -16,6 +16,13 @@ </description> <dependencies> + + <!--redission依赖--> + <dependency> + <groupId>org.redisson</groupId> + <artifactId>redisson</artifactId> + <version>3.13.6</version> + </dependency> <!-- SpringBoot Boot Redis --> <dependency> diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java index 6e1ec8a..6a8dc47 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java @@ -12,18 +12,16 @@ /** * redis配置 - * + * * @author ruoyi */ @Configuration @EnableCaching @AutoConfigureBefore(RedisAutoConfiguration.class) -public class RedisConfig extends CachingConfigurerSupport -{ +public class RedisConfig extends CachingConfigurerSupport { @Bean - @SuppressWarnings(value = { "unchecked", "rawtypes" }) - public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) - { + @SuppressWarnings(value = {"unchecked", "rawtypes"}) + public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java index a9cb1b7..df981c5 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java @@ -1,9 +1,14 @@ package com.ruoyi.common.security.handler; -import javax.naming.SizeLimitExceededException; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.fileupload.FileUploadBase; +import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.exception.DemoModeException; +import com.ruoyi.common.core.exception.GlobalException; +import com.ruoyi.common.core.exception.InnerAuthException; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.exception.auth.NotPermissionException; +import com.ruoyi.common.core.exception.auth.NotRoleException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.web.domain.AjaxResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -12,25 +17,17 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import com.ruoyi.common.core.constant.HttpStatus; -import com.ruoyi.common.core.exception.DemoModeException; -import com.ruoyi.common.core.exception.InnerAuthException; -import com.ruoyi.common.core.exception.ServiceException; -import com.ruoyi.common.core.exception.auth.NotPermissionException; -import com.ruoyi.common.core.exception.auth.NotRoleException; -import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.core.web.domain.AjaxResult; import org.springframework.web.multipart.MaxUploadSizeExceededException; -import org.springframework.web.multipart.MultipartException; + +import javax.servlet.http.HttpServletRequest; /** * 全局异常处理器 - * + * * @author ruoyi */ @RestControllerAdvice -public class GlobalExceptionHandler -{ +public class GlobalExceptionHandler { private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); @Value("${spring.servlet.multipart.max-file-size:4MB}") @@ -43,8 +40,7 @@ * 权限码异常 */ @ExceptionHandler(NotPermissionException.class) - public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) - { + public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage()); return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权"); @@ -54,8 +50,7 @@ * 角色权限异常 */ @ExceptionHandler(NotRoleException.class) - public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request) - { + public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage()); return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权"); @@ -66,8 +61,7 @@ */ @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, - HttpServletRequest request) - { + HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); return AjaxResult.error(e.getMessage()); @@ -77,8 +71,7 @@ * 业务异常 */ @ExceptionHandler(ServiceException.class) - public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) - { + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) { log.error(e.getMessage(), e); Integer code = e.getCode(); return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); @@ -88,8 +81,7 @@ * 拦截未知的运行时异常 */ @ExceptionHandler(RuntimeException.class) - public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) - { + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',发生未知异常.", requestURI, e); return AjaxResult.error(e.getMessage()); @@ -99,8 +91,7 @@ * 系统异常 */ @ExceptionHandler(Exception.class) - public AjaxResult handleException(Exception e, HttpServletRequest request) - { + public AjaxResult handleException(Exception e, HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',发生系统异常.", requestURI, e); return AjaxResult.error(e.getMessage()); @@ -110,8 +101,7 @@ * 自定义验证异常 */ @ExceptionHandler(BindException.class) - public AjaxResult handleBindException(BindException e) - { + public AjaxResult handleBindException(BindException e) { log.error(e.getMessage(), e); String message = e.getAllErrors().get(0).getDefaultMessage(); return AjaxResult.error(message); @@ -121,8 +111,7 @@ * 自定义验证异常 */ @ExceptionHandler(MethodArgumentNotValidException.class) - public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) - { + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { log.error(e.getMessage(), e); String message = e.getBindingResult().getFieldError().getDefaultMessage(); return AjaxResult.error(message); @@ -132,8 +121,7 @@ * 内部认证异常 */ @ExceptionHandler(InnerAuthException.class) - public AjaxResult handleInnerAuthException(InnerAuthException e) - { + public AjaxResult handleInnerAuthException(InnerAuthException e) { return AjaxResult.error(e.getMessage()); } @@ -141,8 +129,7 @@ * 演示模式异常 */ @ExceptionHandler(DemoModeException.class) - public AjaxResult handleDemoModeException(DemoModeException e) - { + public AjaxResult handleDemoModeException(DemoModeException e) { return AjaxResult.error("演示模式,不允许操作"); } @@ -151,4 +138,13 @@ log.error("上传文件异常 => : {}", e.getMessage()); return AjaxResult.error("文件识别大小超出限制,允许的大小在" + maxFileSize); } + + /** + * 捕获全局自定义异常 + */ + @ExceptionHandler(GlobalException.class) + public AjaxResult globalExceptionHandler(GlobalException e) { + return AjaxResult.error(e.getMessage()); + } + } diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java index 294696f..d114fd9 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java @@ -1,13 +1,5 @@ package com.ruoyi.common.security.service; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; - -import com.ruoyi.system.api.model.LoginUserParent; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.utils.JwtUtils; @@ -18,10 +10,18 @@ import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.api.model.LoginUserParent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** * token验证处理 - * + * * @author ruoyi */ @Component @@ -85,6 +85,27 @@ rspMap.put("expires_in", expireTime); return rspMap; } + + public Map<String, Object> createTokenStudy(LoginUserParent loginUser) + { + String token = IdUtils.fastUUID(); + Integer userId = loginUser.getUserid(); + String name = loginUser.getName(); + loginUser.setToken(token); + loginUser.setIpaddr(IpUtils.getIpAddr()); + refreshTokenStudy(loginUser); + // Jwt存储信息 + Map<String, Object> claimsMap = new HashMap<String, Object>(8); + claimsMap.put(SecurityConstants.USER_STUDY_KEY, token); + claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); + claimsMap.put(SecurityConstants.DETAILS_USERNAME, name); + // 接口返回信息 + Map<String, Object> rspMap = new HashMap<String, Object>(); + rspMap.put("access_token", JwtUtils.createToken(claimsMap)); + rspMap.put("expires_in", expireTime); + return rspMap; + } + /** * 获取用户身份信息 * @@ -117,6 +138,16 @@ } /** + * 学习端获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUserParent getLoginUserStudy() + { + return getLoginUserStudy(ServletUtils.getRequest()); + } + + /** * 获取用户身份信息 * * @return 用户信息 @@ -126,6 +157,18 @@ // 获取请求携带的令牌 String token = SecurityUtils.getToken(request); return getLoginUser1(token); + } + + /** + * 学习端获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUserParent getLoginUserStudy(HttpServletRequest request) + { + // 获取请求携带的令牌 + String token = SecurityUtils.getToken(request); + return getLoginUserStudy(token); } /** @@ -163,6 +206,30 @@ if (StringUtils.isNotEmpty(token)) { String userkey = JwtUtils.getUserKey1(token); + user = redisService.getCacheObject(getTokenKey(userkey)); + return user; + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return user; + } + + /** + * 学习端 获取用户身份信息 + * + * @return 用户信息 + */ + public LoginUserParent getLoginUserStudy(String token) + { + LoginUserParent user = null; + try + { + if (StringUtils.isNotEmpty(token)) + { + String userkey = JwtUtils.getUserKeyStudy(token); user = redisService.getCacheObject(getTokenKey(userkey)); return user; } @@ -263,6 +330,18 @@ redisService.setCacheObject(userKey, dto, expireTime, TimeUnit.MINUTES); } + /** + * 学习端用户登录 + */ + public void refreshTokenStudy(LoginUserParent dto) + { + dto.setLoginTime(System.currentTimeMillis()); + dto.setExpireTime(dto.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(dto.getToken()); + redisService.setCacheObject(userKey, dto, expireTime, TimeUnit.MINUTES); + } + private String getTokenKey(String token) { return ACCESS_TOKEN + token; diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java index 101de63..8c757e8 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java @@ -1,14 +1,5 @@ package com.ruoyi.gateway.filter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.core.Ordered; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.stereotype.Component; -import org.springframework.web.server.ServerWebExchange; import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.HttpStatus; import com.ruoyi.common.core.constant.SecurityConstants; @@ -19,16 +10,24 @@ import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; import io.jsonwebtoken.Claims; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 网关鉴权 - * + * * @author ruoyi */ @Component -public class AuthFilter implements GlobalFilter, Ordered -{ +public class AuthFilter implements GlobalFilter, Ordered { private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); // 排除过滤的 uri 地址,nacos自行添加 @@ -40,37 +39,31 @@ @Override - public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) - { + public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest.Builder mutate = request.mutate(); String url = request.getURI().getPath(); // 跳过不需要验证的路径 - if (StringUtils.matches(url, ignoreWhite.getWhites())) - { + if (StringUtils.matches(url, ignoreWhite.getWhites())) { return chain.filter(exchange); } String token = getToken(request); - if (StringUtils.isEmpty(token)) - { + if (StringUtils.isEmpty(token)) { return unauthorizedResponse(exchange, "令牌不能为空"); } Claims claims = JwtUtils.parseToken(token); - if (claims == null) - { + if (claims == null) { return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); } String userkey = JwtUtils.getUserKey(claims); boolean islogin = redisService.hasKey(getTokenKey(userkey)); - if (!islogin) - { + if (!islogin) { return unauthorizedResponse(exchange, "登录状态已过期"); } String userid = JwtUtils.getUserId(claims); String username = JwtUtils.getUserName(claims); - if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) - { + if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) { return unauthorizedResponse(exchange, "令牌验证失败"); } @@ -83,10 +76,8 @@ return chain.filter(exchange.mutate().request(mutate.build()).build()); } - private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) - { - if (value == null) - { + private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) { + if (value == null) { return; } String valueStr = value.toString(); @@ -94,13 +85,11 @@ mutate.header(name, valueEncode); } - private void removeHeader(ServerHttpRequest.Builder mutate, String name) - { + private void removeHeader(ServerHttpRequest.Builder mutate, String name) { mutate.headers(httpHeaders -> httpHeaders.remove(name)).build(); } - private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) - { + private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) { log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath()); return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED); } @@ -108,28 +97,24 @@ /** * 获取缓存key */ - private String getTokenKey(String token) - { + private String getTokenKey(String token) { return CacheConstants.LOGIN_TOKEN_KEY + token; } /** * 获取请求token */ - private String getToken(ServerHttpRequest request) - { + private String getToken(ServerHttpRequest request) { String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION); // 如果前端设置了令牌前缀,则裁剪掉前缀 - if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) - { + if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) { token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY); } return token; } @Override - public int getOrder() - { + public int getOrder() { return -200; } } \ No newline at end of file diff --git a/ruoyi-service/ruoyi-goods/pom.xml b/ruoyi-service/ruoyi-goods/pom.xml index e9a6b02..954e482 100644 --- a/ruoyi-service/ruoyi-goods/pom.xml +++ b/ruoyi-service/ruoyi-goods/pom.xml @@ -16,6 +16,12 @@ <dependencies> + <dependency> + <groupId>com.ruoyi</groupId> + <artifactId>ruoyi-api-study</artifactId> + <version>3.6.2</version> + </dependency> + <dependency> <groupId>com.ruoyi</groupId> @@ -98,6 +104,12 @@ <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> + <!--redission依赖--> + <dependency> + <groupId>org.redisson</groupId> + <artifactId>redisson</artifactId> + <version>3.13.6</version> + </dependency> <!--mybatis-plus--> <!--<dependency> diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java new file mode 100644 index 0000000..c9a8d86 --- /dev/null +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java @@ -0,0 +1,30 @@ +package com.ruoyi.goods.config; + +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-20 15:27 + */ +@Configuration +public class RedissonConfig { + + /** + * 创建客户端 + * + * @return 客户端连接 + */ + @Bean + public RedissonClient redissonClient() { + Config config = new Config(); + config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456"); + return Redisson.create(config); + } + + +} diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java index ac65535..a69a0d3 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java @@ -4,13 +4,12 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.page.PageInfo; -import com.ruoyi.goods.domain.TGoods; -import com.ruoyi.goods.domain.TGoodsType; -import com.ruoyi.goods.domain.TOrder; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.goods.domain.*; +import com.ruoyi.goods.dto.GoodExchangeDTO; +import com.ruoyi.goods.dto.GoodQueryDTO; import com.ruoyi.goods.dto.GoodsTypeQuery; -import com.ruoyi.goods.service.ITGoodsService; -import com.ruoyi.goods.service.ITGoodsTypeService; -import com.ruoyi.goods.service.ITOrderService; +import com.ruoyi.goods.service.*; import com.ruoyi.goods.vo.TGoodsVO; import io.swagger.annotations.ApiOperation; import org.springframework.beans.BeanUtils; @@ -18,7 +17,11 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * <p> @@ -31,17 +34,22 @@ @RestController @RequestMapping("/base/goods") public class TGoodsController { - @Autowired + @Resource private ITGoodsService goodsService; @Autowired private ITGoodsTypeService goodsTypeService; @Autowired private ITOrderService orderService; + @Resource + private IRecipientService recipientService; + @Resource + private IRegionService regionService; + @PostMapping("/listType") @ApiOperation(value = "列表查询", tags = {"后台-商品类型管理"}) - public R<PageInfo<TGoodsType>> listType(@RequestBody GoodsTypeQuery query){ + public R<PageInfo<TGoodsType>> listType(@RequestBody GoodsTypeQuery query) { QueryWrapper<TGoodsType> wrapper = new QueryWrapper<>(); - if (StringUtils.hasLength(query.getName())){ + if (StringUtils.hasLength(query.getName())) { wrapper.like("name", query.getName()); } // wrapper.ne("isDelete",1); @@ -51,31 +59,49 @@ res.setRecords(list); return R.ok(res); } + + @PostMapping("/goodList") + @ApiOperation(value = "商品列表查询", tags = {"学习端-商品列表"}) + public R<PageInfo<TGoods>> listType(@RequestBody GoodQueryDTO goodQuery) { + List<String> type = goodQuery.getType(); + String keywords = goodQuery.getKeywords(); + // 初始化条件构造器 + QueryWrapper<TGoods> wrapper = new QueryWrapper<>(); + wrapper = keywords != null && "".equals(keywords.trim()) ? wrapper.like("name", keywords) : wrapper; + // 类型匹配 todo + wrapper = type.isEmpty() ? wrapper : wrapper.in(""); + wrapper.eq("isDelete", 0); + return R.ok(goodsService.page(new PageInfo<>(goodQuery.getPageNumber(), goodQuery.getPageSize()), wrapper)); + } + @PostMapping("/addGoodsType") @ApiOperation(value = "添加", tags = {"后台-商品类型管理"}) public R addGoodsType(@RequestBody TGoodsType dto) { goodsTypeService.save(dto); return R.ok("添加成功"); } + @PostMapping("/updateGoodsType") @ApiOperation(value = "修改", tags = {"后台-商品类型管理"}) public R updateGoodsType(@RequestBody TGoodsType dto) { goodsTypeService.updateById(dto); return R.ok("修改成功"); } + @PostMapping("/deleteGoodsType/{id}") @ApiOperation(value = "删除", tags = {"后台-商品类型管理"}) - public R deleteGoodsType(@PathVariable("id")Integer id) { + public R deleteGoodsType(@PathVariable("id") Integer id) { TGoodsType byId = goodsTypeService.getById(id); byId.setIsDelete(1); goodsTypeService.removeById(byId); return R.ok("删除成功"); } + @PostMapping("/listAll") @ApiOperation(value = "列表查询", tags = {"后台-商品管理"}) - public R<PageInfo<TGoods>> listAll(@RequestBody GoodsTypeQuery query){ + public R<PageInfo<TGoods>> listAll(@RequestBody GoodsTypeQuery query) { QueryWrapper<TGoods> wrapper = new QueryWrapper<>(); - if (StringUtils.hasLength(query.getName())){ + if (StringUtils.hasLength(query.getName())) { wrapper.like("name", query.getName()); } wrapper.orderByDesc("id"); @@ -88,12 +114,14 @@ res.setRecords(list); return R.ok(res); } + @PostMapping("/addGoods") @ApiOperation(value = "添加", tags = {"后台-商品管理"}) public R addGoods(@RequestBody TGoods dto) { goodsService.save(dto); return R.ok("添加成功"); } + @PostMapping("/deleteGoods/{id}") @ApiOperation(value = "删除", tags = {"后台-商品管理"}) public R deleteGoods(@PathVariable("id") Integer id) { @@ -101,29 +129,147 @@ goodsService.removeById(byId); return R.ok("删除成功"); } + @PostMapping("/updateGoods") @ApiOperation(value = "修改", tags = {"后台-商品管理"}) public R updateGoods(@RequestBody TGoods dto) { goodsService.updateById(dto); return R.ok("修改成功"); } + @PostMapping("/getGoodsInfo/{id}") @ApiOperation(value = "查看详情", tags = {"后台-商品管理"}) public R<TGoodsVO> getGoodsInfo(@PathVariable("id") Integer id) { TGoodsVO tGoodsVO = new TGoodsVO(); TGoods byId = goodsService.getById(id); - BeanUtils.copyProperties(byId,tGoodsVO); + BeanUtils.copyProperties(byId, tGoodsVO); long goodsId = orderService.count(new QueryWrapper<TOrder>().eq("goodsId", id)); tGoodsVO.setInventory(goodsId); tGoodsVO.setIntegral(byId.getIntegral()); return R.ok(tGoodsVO); } + @PostMapping("/getGoodsTypeList") @ApiOperation(value = "获取商品类型列表", tags = {"后台-商品管理"}) public R<List<TGoodsType>> getGoodsInfo() { - List<TGoodsType> res = goodsTypeService.list(new QueryWrapper<TGoodsType>()); + List<TGoodsType> res = goodsTypeService.list(new QueryWrapper<>()); return R.ok(res); } + /** + * 兑换记录 + */ + @GetMapping("/exchangeRecord") + @ApiOperation(value = "兑换记录", tags = {"兑换记录"}) + public R<List<TOrder>> exchangeRecord() { + return R.ok(orderService.lambdaQuery().eq(TOrder::getUserId, SecurityUtils.getUserId()) + .orderByDesc(TOrder::getCreateTime).list()); + } + + /** + * 获取用户收货地址 + */ + @GetMapping("/shopAddress") + @ApiOperation(value = "获取用户收货地址", tags = {"获取用户收货地址"}) + public R<List<Recipient>> shopAddress() { + return R.ok(recipientService.lambdaQuery().eq(Recipient::getUserId, SecurityUtils.getUserId()).list()); + } + + /** + * 新增收货地址/修改收货地址 + */ + @PostMapping("/addressSaveOrUpdate") + @ApiOperation(value = "新增收货地址/修改收货地址", tags = {"新增收货地址/修改收货地址"}) + public R<String> addressSave(@RequestBody Recipient recipient) { + return R.ok(recipientService.addressSaveOrUpdate(recipient)); + } + + /** + * 删除收货地址 + */ + @GetMapping("/addressDelete") + @ApiOperation(value = "删除收货地址", tags = {"删除收货地址"}) + public R<String> addressDelete(@RequestParam String id) { + return R.ok(recipientService.removeById(id) ? "删除成功!" : "删除失败!"); + } + + /** + * 修改订单收货地址 + * + * @param orderId 订单id + */ + @GetMapping("/updateOrderAddress") + @ApiOperation(value = "修改订单收货地址", tags = {"修改订单收货地址"}) + public R<Boolean> updateOrderAddress(@RequestParam String orderId, @RequestParam String address) { + return R.ok(orderService.lambdaUpdate().set(TOrder::getConsigneeAddress, address) + .eq(TOrder::getId, orderId).eq(TOrder::getState, 1).update()); + } + + /** + * 收货地址省市区三级联动 + */ + @GetMapping("/addressTree") + @ApiOperation(value = "收货地址省市区三级联动", tags = {"收货地址省市区三级联动"}) + public R<List<Region>> addressTree() { + return R.ok(regionService.addressTree()); + } + + /** + * 可兑换商品推荐 + */ + @GetMapping("/goodRecommend") + @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"}) + public R<List<TGoodsVO>> goodRecommend(@RequestParam String userId) { + List<TGoodsVO> res = goodsService.goodRecommend(userId); + return R.ok(res); + } + + /** + * 商品详情 + * + * @param goodId 商品id + */ + @GetMapping("/goodDetail") + @ApiOperation(value = "商品详情", tags = {"商品详情"}) + public R<Map<String, Object>> goodDetail(@RequestParam String goodId) { + Map<String, Object> result = new HashMap<>(8); + // 商品详情 + TGoods goods = goodsService.lambdaQuery().eq(TGoods::getId, goodId).one(); + result.put("goodDetail", goods); + // 商品分类详情 + result.put("goodTypeDetail", goodsTypeService.lambdaQuery().in(TGoodsType::getId, Arrays.asList(goods.getTypeIds().split(","))).list()); + // 已兑换人数 + result.put("number", goods.getBasicCount() + orderService.getGoodBuyNumber(goods.getId())); + // 用户收货地址 + if (SecurityUtils.getUserId() != null) { + result.put("address", recipientService.lambdaQuery() + .eq(Recipient::getUserId, SecurityUtils.getUserId()).eq(Recipient::getIsDefault, 1).one()); + } + return R.ok(result); + } + + /** + * 商城-立即兑换 + */ + @GetMapping("/redeemNow") + @ApiOperation(value = "商城-立即兑换", tags = {"立即兑换"}) + public R<Map<String, Object>> redeemNow(@RequestParam String goodId) { + Recipient recipient = recipientService.lambdaQuery() + .eq(Recipient::getUserId, SecurityUtils.getUserId()).eq(Recipient::getIsDefault, 1).one(); + return R.ok(goodsService.redeemNow(goodId, recipient)); + } + + /** + * 商品兑换 + * + * @param goodExchange 商品信息 + */ + @PostMapping("/goodExchange") + @ApiOperation(value = "商品兑换-确认", tags = {"商品兑换-确认"}) + public R<Object> goodExchange(@RequestBody GoodExchangeDTO goodExchange) { + Recipient recipient = recipientService.getById(goodExchange.getRecipientId()); + return R.ok(goodsService.goodExchange(goodExchange, recipient)); + } + } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Region.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Region.java index cf79817..bfe3cc4 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Region.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/Region.java @@ -4,14 +4,19 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.util.ArrayList; +import java.util.List; + /** -* 行政区域数据 -* @author pzb -* @Date 2022/2/9 10:00 -*/ + * 行政区域数据 + * + * @author pzb + * @Date 2022/2/9 10:00 + */ @Data @TableName("t_region") public class Region { @@ -38,4 +43,12 @@ */ @TableField("parent_id") private Integer parentId; + + /** + * 子集 + */ + @TableField(exist = false) + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List<Region> children = new ArrayList<>(); + } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java new file mode 100644 index 0000000..93a57ea --- /dev/null +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodExchangeDTO.java @@ -0,0 +1,38 @@ +package com.ruoyi.goods.dto; + +import lombok.Data; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-17 9:56 + */ +@Data +public class GoodExchangeDTO { + + /** + * 商品id + */ + private Integer goodId; + + /** + * 备注 + */ + private String remark; + + /** + * 兑换数量 + */ + private Integer number; + + /** + * 订单编号 + */ + private String orderNumber; + + /** + * 收货地址id + */ + private String recipientId; + +} diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodQueryDTO.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodQueryDTO.java new file mode 100644 index 0000000..2f9f970 --- /dev/null +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/dto/GoodQueryDTO.java @@ -0,0 +1,33 @@ +package com.ruoyi.goods.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-16 17:16 + */ +@Data +public class GoodQueryDTO { + + /** + * 商品类型 + */ + @ApiModelProperty("商品类型") + private List<String> type; + + /** + * 关键字 + */ + @ApiModelProperty("关键字") + private String keywords; + + @ApiModelProperty(value = "页码,首页1", required = true) + private Integer pageNumber; + @ApiModelProperty(value = "页条数", required = true) + private Integer pageSize; + +} diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TGoodsMapper.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TGoodsMapper.java index 7089925..bbc73ae 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TGoodsMapper.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TGoodsMapper.java @@ -3,6 +3,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.goods.domain.TGoods; +import com.ruoyi.goods.vo.TGoodsVO; + +import java.util.List; /** * <p> @@ -14,4 +17,12 @@ */ public interface TGoodsMapper extends BaseMapper<TGoods> { + /** + * 可兑换商品推荐 + * + * @param userId 用户id + * @return 推荐商品 + */ + List<TGoodsVO> goodRecommend(String userId); + } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TOrderMapper.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TOrderMapper.java index c268be2..97c0b26 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TOrderMapper.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/mapper/TOrderMapper.java @@ -20,4 +20,11 @@ List<TOrderVO> listAll(@Param("req") OrderQuery query); + /** + * 获取商品购买数量 + * + * @param id 商品id + * @return 购买数量 + */ + Integer getGoodBuyNumber(@Param("goodId") Integer id); } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java index bcc273d..08fc851 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java @@ -14,4 +14,11 @@ */ public interface IRecipientService extends IService<Recipient> { + /** + * 新增收货地址/修改收货地址 + * + * @param recipient 收货地址信息 + * @return 操作结果 + */ + String addressSaveOrUpdate(Recipient recipient); } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRegionService.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRegionService.java index 8e32b7d..a0bc735 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRegionService.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRegionService.java @@ -8,5 +8,11 @@ public interface IRegionService extends IService<Region> { + /** + * 收货地址省市区三级联动 + * + * @return 无限级树 + */ + List<Region> addressTree(); } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java index f7ad029..07d8e3d 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java @@ -2,7 +2,13 @@ import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.goods.domain.Recipient; import com.ruoyi.goods.domain.TGoods; +import com.ruoyi.goods.dto.GoodExchangeDTO; +import com.ruoyi.goods.vo.TGoodsVO; + +import java.util.List; +import java.util.Map; /** * <p> @@ -14,4 +20,29 @@ */ public interface ITGoodsService extends IService<TGoods> { + /** + * 可兑换商品推荐 + * + * @param userId 用户id + * @return 推荐商品 + */ + List<TGoodsVO> goodRecommend(String userId); + + /** + * 立即兑换 + * + * @param goodId 商品id + * @param recipient 默认收货地址 + * @return 立即兑换页面数据 + */ + Map<String, Object> redeemNow(String goodId, Recipient recipient); + + /** + * 商品兑换 + * + * @param goodExchange 商品信息 + * @param recipient 收货地址 + * @return 兑换结果 + */ + Object goodExchange(GoodExchangeDTO goodExchange, Recipient recipient); } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITOrderService.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITOrderService.java index 764bde4..e42ac3b 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITOrderService.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITOrderService.java @@ -20,4 +20,12 @@ List<TOrderVO> listAll(OrderQuery query); + /** + * 获取商品购买数量 + * + * @param id 商品id + * @return 购买数量 + */ + Integer getGoodBuyNumber(Integer id); + } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java index 1903ed7..7c50131 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java @@ -1,10 +1,13 @@ package com.ruoyi.goods.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.goods.domain.Recipient; import com.ruoyi.goods.mapper.RecipientMapper; import com.ruoyi.goods.service.IRecipientService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * <p> @@ -17,4 +20,17 @@ @Service public class RecipientServiceImpl extends ServiceImpl<RecipientMapper, Recipient> implements IRecipientService { + @Override + @Transactional(rollbackFor = Exception.class) + public String addressSaveOrUpdate(Recipient recipient) { + boolean result; + // 主键ID为空,新增收货地址 + if (StringUtils.isEmpty(String.valueOf(recipient.getId()))) { + recipient.setUserId(SecurityUtils.getUserId().intValue()); + result = this.save(recipient); + } else { + result = this.updateById(recipient); + } + return result ? "操作成功!" : "操作失败!"; + } } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java index ba857bc..1432bb9 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java @@ -1,14 +1,68 @@ package com.ruoyi.goods.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.constant.RedisConstants; import com.ruoyi.goods.domain.Region; import com.ruoyi.goods.mapper.RegionMapper; import com.ruoyi.goods.service.IRegionService; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; @Service public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements IRegionService { + @Resource + private RedisTemplate<Object, Object> redisTemplate; + + @Override + public List<Region> addressTree() { + // redis缓存 + Map<Object, Object> regionList = redisTemplate.opsForHash().entries(RedisConstants.ADDRESS_TREE); + // 获取所有地区信息 省市区三级 + List<Region> regions = getReginList(regionList); + // 所有地区 + Map<String, Region> courseTypeMap = regions.stream(). + collect(Collectors.toMap(region -> region.getId().toString() + , region -> region)); + redisTemplate.opsForHash().putAll(RedisConstants.ADDRESS_TREE, courseTypeMap); + redisTemplate.expire(RedisConstants.ADDRESS_TREE, 30, TimeUnit.MINUTES); + // 生成map集合 + Map<Integer, Region> map = regions.stream().collect(Collectors.toMap(Region::getId, region -> region)); + // 存放无限级树 + List<Region> treeData = new ArrayList<>(); + // 遍历地区集合 + regions.forEach(e -> { + if (e.getParentId() == null || e.getParentId().equals(0)) { + treeData.add(e); + } else { + Region region = map.get(e.getParentId()); + region.getChildren().add(e); + } + }); + return treeData; + } + + /** + * 获取redis数据进行封装 + */ + private List<Region> getReginList(Map<Object, Object> regionMap) { + List<Region> regions = new ArrayList<>(); + if (!regionMap.isEmpty()) { + Collection<Object> values = regionMap.values(); + for (Object value : values) { + regions.add((Region) value); + } + } else { + regions = this.list(); + } + return regions; + } } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java index 834cdda..f7658a7 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java @@ -1,10 +1,30 @@ package com.ruoyi.goods.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.RedisConstants; +import com.ruoyi.common.core.exception.GlobalException; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.goods.domain.Recipient; import com.ruoyi.goods.domain.TGoods; +import com.ruoyi.goods.domain.TOrder; +import com.ruoyi.goods.dto.GoodExchangeDTO; import com.ruoyi.goods.mapper.TGoodsMapper; import com.ruoyi.goods.service.ITGoodsService; +import com.ruoyi.goods.service.ITOrderService; +import com.ruoyi.goods.vo.TGoodsVO; +import com.ruoyi.study.api.domain.TUser; +import com.ruoyi.study.api.feignClient.StudyClient; +import org.redisson.api.RSemaphore; +import org.redisson.api.RedissonClient; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * <p> @@ -17,4 +37,82 @@ @Service public class TGoodsServiceImpl extends ServiceImpl<TGoodsMapper, TGoods> implements ITGoodsService { + @Resource + private RedissonClient redissonClient; + @Resource + private StudyClient studyClient; + @Resource + private ITOrderService orderService; + + @Override + public List<TGoodsVO> goodRecommend(String userId) { + return baseMapper.goodRecommend(userId); + } + + @Override + public Map<String, Object> redeemNow(String goodId, Recipient recipient) { + // 商品详情 + TGoods goods = lambdaQuery().eq(TGoods::getId, goodId).one(); + Map<String, Object> result = new HashMap<>(8); + result.put("goodDetail", goods); + // 用户收货地址 + result.put("address", recipient); + // 库存预热,redisson分布式锁 + String key = String.format(RedisConstants.GOOD_STOCK, goods.getId()); + RSemaphore semaphore = redissonClient.getSemaphore(key); + semaphore.trySetPermits(goods.getSurplus()); + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Object goodExchange(GoodExchangeDTO goodExchange, Recipient recipient) { + Integer number = goodExchange.getNumber(); + Integer goodId = goodExchange.getGoodId(); + TGoods good = this.getById(goodId); + if (null == good) { + throw new GlobalException("商品不存在,请稍后重试!"); + } + // 校验用户积分是否足够兑换 + TUser user = studyClient.userInfo().getData(); + int needIntegral = good.getIntegral() * number; + if (user.getIntegral() < needIntegral) { + throw new GlobalException("兑换失败,当前剩余积分不足!"); + } + // redisson分布式锁,防止超卖 + String key = String.format(RedisConstants.GOOD_STOCK, good.getId()); + RSemaphore semaphore = redissonClient.getSemaphore(key); + boolean tried = semaphore.tryAcquire(number); + // 兑换失败,库存不足 + if (!tried) { + throw new GlobalException("当前商品库存不足!"); + } + // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务) + TOrder order = orderInfo(goodExchange, recipient, number, goodId, needIntegral); + if (!orderService.save(order)) { + throw new GlobalException("订单生成失败!"); + } + // 远程调用,生成积分明细 + Boolean boo = studyClient.addIntegralDetail(Constants.BURDEN + needIntegral, Constants.SHOPPING_CONSUME).getData(); + if (!boo) { + throw new GlobalException("生成积分明细失败,请稍后重试!"); + } + return true; + } + + private TOrder orderInfo(GoodExchangeDTO goodExchange, Recipient recipient, Integer number, Integer goodId, int needIntegral) { + TOrder order = new TOrder(); + order.setOrderNumber(goodExchange.getOrderNumber()); + order.setUserId(SecurityUtils.getUserId().intValue()); + order.setInsertTime(new Date()); + order.setGoodsId(goodId); + order.setCount(number); + order.setState(1); + order.setIntegral(needIntegral); + order.setConsigneeName(recipient.getRecipient()); + order.setConsigneePhone(recipient.getRecipientPhone()); + order.setConsigneeAddress(recipient.getAddress()); + order.setDisabled(Boolean.FALSE); + return order; + } } diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TOrderServiceImpl.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TOrderServiceImpl.java index ba918ce..87020ec 100644 --- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TOrderServiceImpl.java +++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TOrderServiceImpl.java @@ -25,4 +25,10 @@ public List<TOrderVO> listAll(OrderQuery query) { return this.baseMapper.listAll(query); } + + @Override + public Integer getGoodBuyNumber(Integer id) { + return baseMapper.getGoodBuyNumber(id); + } + } diff --git a/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/RecipientMapper.xml b/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/RecipientMapper.xml index 5a4750d..601f8d8 100644 --- a/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/RecipientMapper.xml +++ b/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/RecipientMapper.xml @@ -16,9 +16,4 @@ <result column="isDefault" property="isDefault" /> </resultMap> - <!-- 通用查询结果列 --> - <sql id="Base_Column_List"> - id, userId, recipient, recipientPhone, province, provinceCode, city, cityCode, address,isDefault - </sql> - </mapper> diff --git a/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml b/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml index b5874e8..33f079b 100644 --- a/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml +++ b/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml @@ -1,28 +1,45 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.goods.mapper.TGoodsMapper"> - <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.ruoyi.goods.domain.TGoods"> - <id column="id" property="id" /> - <result column="name" property="name" /> - <result column="price" property="price" /> - <result column="total" property="total" /> - <result column="surplus" property="surplus" /> - <result column="userCount" property="userCount" /> - <result column="typeIds" property="typeIds" /> - <result column="coverImg" property="coverImg" /> - <result column="detailImg" property="detailImg" /> - <result column="detail" property="detail" /> - <result column="isDelete" property="isDelete" /> - <result column="type" property="type" /> - <result column="integral" property="integral" /> + <id column="id" property="id"/> + <result column="name" property="name"/> + <result column="price" property="price"/> + <result column="total" property="total"/> + <result column="surplus" property="surplus"/> + <result column="userCount" property="userCount"/> + <result column="typeIds" property="typeIds"/> + <result column="coverImg" property="coverImg"/> + <result column="detailImg" property="detailImg"/> + <result column="detail" property="detail"/> + <result column="isDelete" property="isDelete"/> + <result column="type" property="type"/> + <result column="integral" property="integral"/> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> - id, name, - price, total, surplus, userCount, typeIds, coverImg, detailImg, detail, isDelete, type,integral, + id, + name, + price, + total, + surplus, + userCount, + typeIds, + coverImg, + detailImg, + detail, + isDelete, + type, + integral </sql> + <select id="goodRecommend" resultType="com.ruoyi.goods.vo.TGoodsVO"> + select * + from t_goods g + where g.price <![CDATA[ <= ]]> (select integral from t_user u where u.id = #{userId}) + ORDER BY g.price desc + limit 3 + </select> </mapper> diff --git a/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TOrderMapper.xml b/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TOrderMapper.xml index 0abf2ba..0abe702 100644 --- a/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TOrderMapper.xml +++ b/ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TOrderMapper.xml @@ -44,4 +44,7 @@ order by t1.insertTime desc </select> + <select id="getGoodBuyNumber" resultType="java.lang.Integer"> + SELECT SUM(count) FROM t_order WHERE goodsId = #{goodId} + </select> </mapper> diff --git a/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TPageController.java b/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TPageController.java index 037fd86..00d199b 100644 --- a/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TPageController.java +++ b/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TPageController.java @@ -1,9 +1,16 @@ package com.ruoyi.management.controller; -import org.springframework.web.bind.annotation.RequestMapping; - +import com.ruoyi.common.core.domain.R; +import com.ruoyi.management.domain.TPage; +import com.ruoyi.management.service.ITPageService; +import io.swagger.annotations.ApiOperation; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.annotation.Resource; /** * <p> @@ -17,5 +24,20 @@ @RequestMapping("/tPage") public class TPageController { + @Resource + private ITPageService pageService; + + /** + * 启动页 + * + * @param type 类型 1学习 2家长手机 3家长平板 4注意事项 + */ + @GetMapping("/home") + @ApiOperation(value = "启动页", tags = {"启动页"}) + public R<TPage> home(@RequestParam Integer type) { + return R.ok(pageService.lambdaQuery().eq(TPage::getType, type) + .eq(TPage::getDisabled, 0).one()); + } + } diff --git a/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TProtocolController.java b/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TProtocolController.java index a612baa..4191dbf 100644 --- a/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TProtocolController.java +++ b/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TProtocolController.java @@ -1,9 +1,16 @@ package com.ruoyi.management.controller; -import org.springframework.web.bind.annotation.RequestMapping; - +import com.ruoyi.common.core.domain.R; +import com.ruoyi.management.domain.TProtocol; +import com.ruoyi.management.service.ITProtocolService; +import io.swagger.annotations.ApiOperation; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.annotation.Resource; /** * <p> @@ -17,5 +24,20 @@ @RequestMapping("/tProtocol") public class TProtocolController { + @Resource + private ITProtocolService protocolService; + + /** + * 用户协议/隐私协议/注销协议 + * + * @param type 类型 1用户协议 2隐私协议 3注销协议 + */ + @GetMapping("/home") + @ApiOperation(value = "用户协议/隐私协议/注销协议", tags = {"用户协议/隐私协议/注销协议"}) + public R<TProtocol> home(@RequestParam Integer type) { + return R.ok(protocolService.lambdaQuery().eq(TProtocol::getType, type) + .eq(TProtocol::getDisabled, 0).one()); + } + } diff --git a/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TUserController.java b/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TUserController.java index 3b9d9e4..0f1d1d3 100644 --- a/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TUserController.java +++ b/ruoyi-service/ruoyi-management/src/main/java/com/ruoyi/management/controller/TUserController.java @@ -18,8 +18,10 @@ import com.ruoyi.study.api.vo.VipOrderVO; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -41,6 +43,7 @@ @Autowired private StudyClient studyClient; + @PostMapping("/userList") @ApiOperation(value = "用户列表", tags = {"用户管理"}) public AjaxResult<PageInfo<AppUserVO>> couponReceive(AppUserQuery query) { @@ -111,6 +114,7 @@ return AjaxResult.success(data); } + @PostMapping("/freeze") @ApiOperation(value = "冻结/解冻", tags = {"用户管理"}) public AjaxResult freeze(Integer id) { @@ -118,17 +122,19 @@ if (byId.getState() == 1) { studyClient.freeze(id); return AjaxResult.success("冻结成功"); - }else { + } else { studyClient.freeze(id); return AjaxResult.success("解冻成功"); } } + @PostMapping("/getVipSet") @ApiOperation(value = "获取会员设置", tags = {"用户管理"}) public AjaxResult<List<TVipSet>> getVipSet() { List<TVipSet> list = vipSetService.list(new QueryWrapper<TVipSet>().orderByAsc("amount")); return AjaxResult.success(list); } + @PostMapping("/getVipSet1") @ApiOperation(value = "获取会员设置", tags = {"家长端"}) public R<List<TVipSet>> getVipSet1() { @@ -136,6 +142,7 @@ .orderByAsc("time")); return R.ok(list); } + @PostMapping("/setVipSet") @ApiOperation(value = "保存会员设置", tags = {"用户管理"}) public AjaxResult setVipSet(@RequestBody VipSetVO vo) { @@ -147,6 +154,7 @@ } return AjaxResult.success("保存成功"); } + @PostMapping("/vipOrderList") @ApiOperation(value = "列表查询", tags = {"会员管理"}) public AjaxResult<PageInfo<VipOrderVO>> vipOrderList(AppUserQuery query) { @@ -154,11 +162,13 @@ PageInfo<VipOrderVO> data = studyClient.vipOrderList(query).getData(); return AjaxResult.success(data); } + @PostMapping("/vipBack") @ApiOperation(value = "会员退款", tags = {"会员管理"}) public AjaxResult vipOrderList(Integer id) { studyClient.vipBack(id); return AjaxResult.success(); } + } diff --git a/ruoyi-service/ruoyi-study/pom.xml b/ruoyi-service/ruoyi-study/pom.xml index d096c5b..c779948 100644 --- a/ruoyi-service/ruoyi-study/pom.xml +++ b/ruoyi-service/ruoyi-study/pom.xml @@ -43,6 +43,12 @@ <artifactId>ruoyi-api-management</artifactId> </dependency> + <dependency> + <groupId>com.ruoyi</groupId> + <artifactId>ruoyi-api-goods</artifactId> + <version>3.6.2</version> + </dependency> + diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java index c82ae08..3a3babb 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java @@ -1,19 +1,32 @@ package com.ruoyi.study.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.constant.RedisConstants; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.exception.GlobalException; import com.ruoyi.common.core.web.page.PageInfo; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.service.TokenService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.goods.api.feignClient.GoodsClient; +import com.ruoyi.goods.api.model.TGoodsVO; import com.ruoyi.study.domain.*; import com.ruoyi.study.dto.*; import com.ruoyi.study.service.*; import com.ruoyi.study.vo.*; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; -import java.util.List; +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; /** * <p> @@ -25,6 +38,7 @@ */ @RestController @RequestMapping("/base/study") +@Api(tags = "学习端-主接口") public class TStudyController { @Autowired private ITStudyAnswerService studyAnswerService; @@ -46,23 +60,37 @@ private ITStoryService storyService; @Autowired private ITStudyService studyService; + @Resource + private GoodsClient goodsClient; + @Resource + private ITGameRecordService gameRecordService; + @Resource + private ITUserStudyService userStudyService; + @Resource + private ITIntegralRecordService integralRecordService; + @Resource + private RedisService redisService; + @Resource + private ITUserService userService; + @Resource + private TokenService tokenService; @PostMapping("/storyList") @ApiOperation(value = "配置学习类型选择故事", tags = {"题目管理"}) public R<PageInfo<TStory>> storyList(@RequestBody ChoiceStory query) { PageInfo<TStory> res = new PageInfo<>(query.getPageNumber(), query.getPageSize()); QueryWrapper<TStory> wrapper = new QueryWrapper<>(); - if (StringUtils.hasLength(query.getName())){ - wrapper.like("name",query.getName()); + if (StringUtils.hasLength(query.getName())) { + wrapper.like("name", query.getName()); } - if (StringUtils.hasLength(query.getEnglish())){ - wrapper.like("english",query.getEnglish()); + if (StringUtils.hasLength(query.getEnglish())) { + wrapper.like("english", query.getEnglish()); } - if (StringUtils.hasLength(query.getType())){ - wrapper.like("type",query.getType()); + if (StringUtils.hasLength(query.getType())) { + wrapper.like("type", query.getType()); } - wrapper.eq("state",1); - switch (query.getStoryType()){ + wrapper.eq("state", 1); + switch (query.getStoryType()) { case 2: List<TStory> list = storyService.list(wrapper); res.setRecords(list); @@ -82,6 +110,7 @@ res.setTotal(0); return R.ok(res); } + @PostMapping("/subjectList") @ApiOperation(value = "配置学习类型选择题目", tags = {"题目管理"}) public R<PageInfo<TSubject>> subjectList(@RequestBody ChoiceSubject query) { @@ -90,14 +119,14 @@ if (StringUtils.hasLength(query.getName())){ wrapper.like("name",query.getName()); } - if (StringUtils.hasLength(query.getEnglish())){ - wrapper.like("english",query.getEnglish()); + if (StringUtils.hasLength(query.getEnglish())) { + wrapper.like("english", query.getEnglish()); } - if (StringUtils.hasLength(query.getType())){ - wrapper.like("type",query.getType()); + if (StringUtils.hasLength(query.getType())) { + wrapper.like("type", query.getType()); } - wrapper.eq("state",1); - switch (query.getStudyType()){ + wrapper.eq("state", 1); + switch (query.getStudyType()) { case 1: List<TSubject> list = subjectService.list(wrapper); res.setRecords(list); @@ -131,8 +160,10 @@ res.setTotal(0); return R.ok(res); } + /** * 添加学习配置 + * * @param dto * @return */ @@ -146,12 +177,12 @@ .eq("type", type)); GameDTO game = dto.getGame(); StoryListenDTO storyListen = dto.getStoryListen(); - if (day == 6){ + if (day == 6) { // 先判断有没有配置 TGame studyId = gameService.getOne(new QueryWrapper<TGame>() .eq("studyId", one.getId()) - .eq("week",week)); - if (studyId!=null){ + .eq("week", week)); + if (studyId != null) { studyId.setWeek(dto.getWeek()); studyId.setStudyId(one.getId()); studyId.setCount(game.getCount()); @@ -161,7 +192,7 @@ studyId.setAnswerIntegral(game.getAnswerIntegral()); studyId.setAnswerCount(game.getAnswerCount()); gameService.updateById(studyId); - }else{ + } else { TGame tGame = new TGame(); tGame.setWeek(dto.getWeek()); tGame.setStudyId(one.getId()); @@ -174,12 +205,12 @@ gameService.save(tGame); } - }else if(day == 7){ + } else if (day == 7) { String story = storyListen.getStory(); TStoryListen studyId = storyListenService.getOne(new QueryWrapper<TStoryListen>() .eq("studyId", one.getId()) - .eq("week",week)); - if (studyId!=null){ + .eq("week", week)); + if (studyId != null) { String sort = storyListen.getSort(); String lookStory = storyListen.getLookStory(); String lookSort = storyListen.getLookSort(); @@ -194,7 +225,7 @@ studyId.setLookSort(lookSort); studyId.setStudyId(one.getId()); storyListenService.updateById(studyId); - }else{ + } else { String sort = storyListen.getSort(); String lookStory = storyListen.getLookStory(); String lookSort = storyListen.getLookSort(); @@ -211,12 +242,12 @@ tStoryListen.setStudyId(one.getId()); storyListenService.save(tStoryListen); } - }else{ + } else { // 删除原有数据 studyListenService.remove(new QueryWrapper<TStudyListen>() .eq("studyId", one.getId()) - .eq("week",week) - .eq("day",day)); + .eq("week", week) + .eq("day", day)); List<StudyListenDTO> studyListen = dto.getStudyListen(); for (StudyListenDTO studyListenDTO : studyListen) { TStudyListen tStudyListen = new TStudyListen(); @@ -230,8 +261,8 @@ } studyLookService.remove(new QueryWrapper<TStudyLook>() .eq("studyId", one.getId()) - .eq("week",week) - .eq("day",day)); + .eq("week", week) + .eq("day", day)); List<StudyLookDTO> studyLook = dto.getStudyLook(); for (StudyLookDTO studyLookDTO : studyLook) { TStudyLook tStudyLook = new TStudyLook(); @@ -245,8 +276,8 @@ } studyInductionService.remove(new QueryWrapper<TStudyInduction>() .eq("studyId", one.getId()) - .eq("week",week) - .eq("day",day)); + .eq("week", week) + .eq("day", day)); List<StudyInductionDTO> studyInduction = dto.getStudyInduction(); for (StudyInductionDTO studyInductionDTO : studyInduction) { TStudyInduction tStudyInduction = new TStudyInduction(); @@ -259,8 +290,8 @@ } studyAnswerService.remove(new QueryWrapper<TStudyAnswer>() .eq("studyId", one.getId()) - .eq("week",week) - .eq("day",day)); + .eq("week", week) + .eq("day", day)); List<StudyAnswerDTO> studyAnswer = dto.getStudyAnswer(); for (StudyAnswerDTO studyAnswerDTO : studyAnswer) { TStudyAnswer tStudyAnswer = new TStudyAnswer(); @@ -276,8 +307,8 @@ } studyPairService.remove(new QueryWrapper<TStudyPair>() .eq("studyId", one.getId()) - .eq("week",week) - .eq("day",day)); + .eq("week", week) + .eq("day", day)); List<StudyPairDTO> studyPair = dto.getStudyPair(); for (StudyPairDTO studyPairDTO : studyPair) { TStudyPair tStudyPair = new TStudyPair(); @@ -295,6 +326,7 @@ /** * 添加周目 + * * @param dto * @return */ @@ -308,8 +340,10 @@ studyService.save(tStudy); return R.ok(); } + /** * 学习类型列表查询 + * * @return */ @PostMapping("/getStudyList") @@ -358,8 +392,10 @@ res.add(studyListVO6); return R.ok(res); } + /** * 通过类型、周目、day查询学习配置 + * * @return */ @PostMapping("/getStudySet") @@ -401,7 +437,7 @@ List<TStudyLook> list1 = studyLookService.list(new QueryWrapper<TStudyLook>() .eq("week", week) .eq("day", day) - ); + ); for (TStudyLook tStudyLook : list1) { int index = 0; StringBuilder names = new StringBuilder(); @@ -426,16 +462,16 @@ List<TStudyInduction> list2 = studyInductionService.list(new QueryWrapper<TStudyInduction>() .eq("week", week) .eq("day", day) - ); + ); for (TStudyInduction tStudyInduction : list2) { StringBuilder names = new StringBuilder(); StudyInductionVO studyInductionVO = new StudyInductionVO(); for (String s : tStudyInduction.getSubject().split(",")) { String replace = s.replace("-", ""); - if (s.contains("-")){ + if (s.contains("-")) { TSubject byId = subjectService.getById(replace); names.append("-").append(byId.getName()).append(","); - }else{ + } else { TSubject byId = subjectService.getById(s); names.append(byId.getName()).append(","); } @@ -452,12 +488,12 @@ for (TStudyAnswer tStudyAnswer : list3) { StringBuilder names = new StringBuilder(); StudyAnswerVO studyAnswerVO = new StudyAnswerVO(); - if (tStudyAnswer.getIsAnswer() == 1){ + if (tStudyAnswer.getIsAnswer() == 1) { TSubject byId = subjectService.getById(tStudyAnswer.getSubject()); names.append("-").append(byId.getName()).append(","); TSubject byId1 = subjectService.getById(tStudyAnswer.getAnswerSubject()); names.append("-").append(byId1.getName()).append(","); - }else{ + } else { TSubject byId = subjectService.getById(tStudyAnswer.getSubject()); names.append(byId.getName()).append(","); TSubject byId1 = subjectService.getById(tStudyAnswer.getAnswerSubject()); @@ -472,7 +508,7 @@ List<TStudyPair> list4 = studyPairService.list(new QueryWrapper<TStudyPair>() .eq("week", week) .eq("day", day) - ); + ); for (TStudyPair tStudyPair : list4) { StringBuilder names = new StringBuilder(); StudyPairVO studyPairVO = new StudyPairVO(); @@ -528,30 +564,30 @@ storyVOS.add(storyVO); } int temp = 0; - if (!list.isEmpty()){ + if (!list.isEmpty()) { temp = list.get(0).getStudyId(); } - if (!list1.isEmpty()){ + if (!list1.isEmpty()) { temp = list1.get(0).getStudyId(); } - if (!list2.isEmpty()){ + if (!list2.isEmpty()) { temp = list2.get(0).getStudyId(); } - if (!list3.isEmpty()){ + if (!list3.isEmpty()) { temp = list3.get(0).getStudyId(); } - if (!list4.isEmpty()){ + if (!list4.isEmpty()) { temp = list4.get(0).getStudyId(); } - if (!list5.isEmpty()){ + if (!list5.isEmpty()) { temp = list5.get(0).getStudyId(); } - if (!list6.isEmpty()){ + if (!list6.isEmpty()) { temp = list6.get(0).getStudyId(); } - if (temp == 0){ + if (temp == 0) { res.setTitle(""); - }else{ + } else { res.setTitle(studyService.getById(temp).getTitle()); } res.setAnswer(answerVOS); @@ -563,5 +599,376 @@ res.setStory(storyVOS); return R.ok(res); } + + /** + * 查询周目列表 + * + * @param type 所属类型 + * @param quarter 季度 + */ + @GetMapping("/weekList") + @ApiOperation(value = "周目列表", tags = {"周目列表"}) + public R<List<StudyWeekDTO>> weekList(@RequestParam(defaultValue = "1") Integer type, @RequestParam Integer quarter) { + List<StudyWeekDTO> result = studyService.weekList(type, quarter); + return R.ok(result); + } + + /** + * 首次页面加载时调用,获取学习进度及学习时长等信息 + * + * @param week 周目 + * @param day 所属day + */ + @GetMapping("/studySchedule") + @ApiOperation(value = "获取用户学习进度", tags = {"获取用户学习进度"}) + public R<TUserStudy> studySchedule(Integer week, Integer day) { + TUserStudy result = studyService.studySchedule(String.valueOf(SecurityUtils.getUserId()), week, day); + return R.ok(result); + } + + /** + * 可兑换商品推荐 + */ + @GetMapping("/goodRecommend") + @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"}) + public R<List<TGoodsVO>> studySchedule() { + return goodsClient.goodRecommend(String.valueOf(SecurityUtils.getUserId())); + } + + /** + * 退出学习,记录学习进度、当日学习时长... + */ + @PostMapping("/exitLearning") + @ApiOperation(value = "退出学习(记录学习进度等信息)", tags = {"退出学习(记录学习进度等信息)"}) + public R<Boolean> exitLearning(@RequestBody TUserStudy userStudy) { + // 学习时长处理 + return R.ok(userStudyService.updateById(userStudy)); + } + + /** + * 自主学习1-听音选图 + * + * @param week 周目 + * @param day 所属day + */ + @GetMapping("/listenSelectPicture") + @ApiOperation(value = "自主学习1-听音选图", tags = {"自主学习1-听音选图"}) + public R<Map<String, Object>> listenSelectPicture(@RequestParam Integer week, @RequestParam Integer day) { + // 判断当前登录用户是否为 会员 + Boolean isVip = userService.isVip(); + List<TStudyListen> studyListens = studyListenService.lambdaQuery().eq(TStudyListen::getWeek, week) + .eq(TStudyListen::getDay, day).eq(TStudyListen::getDisabled, 0).list(); + return R.ok(studyService.listenSelectPicture(week, day, studyListens)); + } + + /** + * 自主学习2-看图选音 + * + * @param week 周目 + * @param day 所属day + */ + @GetMapping("/pictureSelectVoice") + @ApiOperation(value = "自主学习2-看图选音", tags = {"自主学习2-看图选音"}) + public R<Map<String, Object>> pictureSelectVoice(@RequestParam Integer week, @RequestParam Integer day) { + // 判断当前登录用户是否为 会员 + Boolean isVip = userService.isVip(); + LambdaQueryChainWrapper<TStudyLook> wrapper = studyLookService.lambdaQuery().eq(TStudyLook::getWeek, week) + .eq(TStudyLook::getDay, day).eq(TStudyLook::getDisabled, 0); + // 非会员只能查看非会员题目,会员可以查看所有题目 + if (!isVip) { + wrapper.eq(TStudyLook::getIsVip, 0); + } + List<TStudyLook> lookList = studyLookService.lambdaQuery().eq(TStudyLook::getWeek, week) + .eq(TStudyLook::getDay, day).eq(TStudyLook::getDisabled, 0).list(); + return R.ok(studyService.pictureSelectVoice(week, day, lookList)); + } + + /** + * 自主学习3-归纳排除 + * + * @param week 周目 + * @param day 所属day + */ + @GetMapping("/induceExclude") + @ApiOperation(value = "自主学习3-归纳排除", tags = {"自主学习3-归纳排除"}) + public R<Map<String, Object>> induceExclude(@RequestParam Integer week, @RequestParam Integer day) { + // 判断当前登录用户是否为 会员 + Boolean isVip = userService.isVip(); + LambdaQueryChainWrapper<TStudyInduction> wrapper = studyInductionService.lambdaQuery().eq(TStudyInduction::getWeek, week) + .eq(TStudyInduction::getDay, day).eq(TStudyInduction::getDisabled, 0); + // 非会员只能查看非会员题目,会员可以查看所有题目 + if (!isVip) { + wrapper.eq(TStudyInduction::getIsVip, 0); + } + List<TStudyInduction> inductionList = wrapper.list(); + return R.ok(studyService.induceExclude(week, day, inductionList)); + } + + /** + * 自主学习4-有问有答 + * + * @param week 周目 + * @param day 所属day + */ + @GetMapping("/questionsAndAnswers") + @ApiOperation(value = "自主学习4-有问有答", tags = {"自主学习4-有问有答"}) + public R<Map<String, Object>> questionsAndAnswers(@RequestParam Integer week, @RequestParam Integer day) { + // 判断当前登录用户是否为 会员 + Boolean isVip = userService.isVip(); + LambdaQueryChainWrapper<TStudyAnswer> wrapper = studyAnswerService.lambdaQuery().eq(TStudyAnswer::getWeek, week) + .eq(TStudyAnswer::getDay, day).eq(TStudyAnswer::getDisabled, 0); + // 非会员只能查看非会员题目,会员可以查看所有题目 + if (!isVip) { + wrapper.eq(TStudyAnswer::getIsVip, 0); + } + List<TStudyAnswer> answerList = wrapper.list(); + return R.ok(studyService.questionsAndAnswers(week, day, answerList)); + } + + /** + * 自主学习5-音图相配 + * + * @param week 周目 + * @param day 所属day + */ + @GetMapping("/pictureMateVoice") + @ApiOperation(value = "自主学习5-音图相配", tags = {"自主学习5-音图相配"}) + public R<Map<String, Object>> pictureMateVoice(@RequestParam Integer week, @RequestParam Integer day) { + // 判断当前登录用户是否为 会员 todo + TStudyPair pair = studyPairService.lambdaQuery().eq(TStudyPair::getWeek, week) + .eq(TStudyPair::getDay, day).eq(TStudyPair::getDisabled, 0).one(); + return R.ok(studyService.pictureMateVoice(week, day, pair)); + } + + /** + * 自主游戏1-超级听力 + * + * @param difficulty 难度(0入门、1中级、2困难) + * @param week 所属周目 + */ + @GetMapping("/gameHearing") + @ApiOperation(value = "自主游戏1-超级听力", tags = {"自主游戏1-超级听力(difficulty: 0入门、1中级、2高级)"}) + public R<Map<String, Object>> gameHearing(@RequestParam Integer difficulty, @RequestParam Integer week) { + Map<String, Object> result = new HashMap<>(8); + TGame game = gameService.lambdaQuery().eq(TGame::getWeek, week) + .eq(TGame::getDisabled, 0).one(); + game.setIntegral(game.getIntegral().split(",")[difficulty]); + game.setTime(game.getTime().split(",")[difficulty]); + result.put("game", game); + // 检验是否完成难度 + studyService.checkDifficulty(difficulty, week, game); + List<String> subjectId = getSubjectId(week); + // 判断周目下题目是否足够 + if (subjectId.size() < game.getCount()) { + throw new GlobalException("当前周目下day1 - day5题目不足!"); + } + // 根据游戏设置数量获取图片及语音 + List<String> subjectData = new ArrayList<>(); + Random random = new Random(); + // 获取列表大小 + int dataSize = subjectId.size(); + // 生成随机索引并获取数据 + for (int i = 0; i < game.getCount(); i++) { + // 生成随机索引 + int randomIndex = random.nextInt(dataSize); + // 获取对应的数据并加入结果列表 + subjectData.add(subjectId.get(randomIndex)); + } + result.put("subject", subjectService.lambdaQuery().in(TSubject::getId, subjectData).eq(TSubject::getState, 1).list()); + return R.ok(result); + } + + /** + * 自主游戏2-超级记忆 + * + * @param difficulty 难度(0入门、1中级、2困难) + * @param week 所属周目 + */ + @GetMapping("/gameMemory") + @ApiOperation(value = "自主游戏2-超级记忆", tags = {"自主游戏2-超级记忆(difficulty: 0入门、1中级、2高级)"}) + public R<Map<String, Object>> gameMemory(@RequestParam Integer difficulty, @RequestParam Integer week) { + Map<String, Object> result = new HashMap<>(8); + TGame game = gameService.lambdaQuery().eq(TGame::getWeek, week).eq(TGame::getDisabled, 0).one(); + result.put("game", game); + // 检验是否完成难度 + studyService.checkDifficulty(difficulty, week, game); + List<String> subjectId = getSubjectId(week); + // 判断周目下题目是否足够 + if (subjectId.size() < game.getCount()) { + throw new GlobalException("当前周目下day1 - day5题目不足!"); + } + // 根据游戏设置数量获取图片及语音 + List<String> subjectData = new ArrayList<>(); + Random random = new Random(); + // 获取列表大小 + int dataSize = subjectId.size(); + // 生成随机索引并获取数据 + for (int i = 0; i < game.getCount(); i++) { + // 生成随机索引 + int randomIndex = random.nextInt(dataSize); + // 获取对应的数据并加入结果列表 + subjectData.add(subjectId.get(randomIndex)); + } + result.put("subject", subjectService.lambdaQuery().in(TSubject::getId, subjectData).eq(TSubject::getState, 1).list()); + return R.ok(result); + } + + /** + * 自主游戏完成 + * 记录游戏测试成绩 + * + * @param completeStudy 学习信息 + */ + @PostMapping("/gameAchievement") + @ApiOperation(value = "完成游戏-记录游戏测试成绩", tags = {"完成游戏-记录游戏测试成绩"}) + public R<?> gameAchievement(@RequestBody CompleteGameDTO completeStudy) { + TGame game = gameService.getById(completeStudy.getGameId()); + // 游戏测试记录 + Boolean add = gameRecordService.add(completeStudy); + // 添加积分明细记录 + add = add && integralRecordService.add(game.getIntegral(), completeStudy.getMethod()); + // 用户账户添加积分 + return R.ok(add); + } + + private List<String> getSubjectId(Integer week) { + // 当前week下day1 - day5所有题目 + List<String> subjectId = redisService.getCacheList(RedisConstants.HEARING_TREE); + if (null == subjectId || subjectId.isEmpty()) { + List<String> listenSubject = studyListenService.lambdaQuery().eq(TStudyListen::getWeek, week) + .eq(TStudyListen::getDisabled, 0).list().stream().map(TStudyListen::getSubject).collect(Collectors.toList()); + List<String> inductionSubject = studyInductionService.lambdaQuery().eq(TStudyInduction::getWeek, week) + .eq(TStudyInduction::getDisabled, 0).list().stream().map(TStudyInduction::getSubject).collect(Collectors.toList()); + List<String> lookSubject = studyLookService.lambdaQuery().eq(TStudyLook::getWeek, week) + .eq(TStudyLook::getDisabled, 0).list().stream().map(TStudyLook::getSubject).collect(Collectors.toList()); + List<String> pairSubject = studyPairService.lambdaQuery().eq(TStudyPair::getWeek, week) + .eq(TStudyPair::getDisabled, 0).list().stream().map(TStudyPair::getSubject).collect(Collectors.toList()); + listenSubject.addAll(inductionSubject); + listenSubject.addAll(lookSubject); + listenSubject.addAll(pairSubject); + // 获取具体subject信息 + subjectId = new ArrayList<>(); + for (String subject : listenSubject) { + subjectId.addAll(Arrays.asList(subject.split(","))); + } + redisService.setCacheList(RedisConstants.HEARING_TREE, subjectId); + } + return subjectId; + } + + /** + * 自主故事1-看图配音 + * + * @param week 周目 + */ + @GetMapping("/lookPictureDbu") + @ApiOperation(value = "自主故事1-看图配音", tags = {"自主故事1-看图配音"}) + public R<Map<String, Object>> lookPictureDbu(@RequestParam Integer week) { + // 看图配音信息 + TStoryListen listen = storyListenService.lambdaQuery().eq(TStoryListen::getWeek, week).one(); + // 获取对应图片语音 + List<String> list = Arrays.asList(listen.getLookStory().split(",")); + Map<String, Object> result = new HashMap<>(8); + result.put("listen", listen); + result.put("info", subjectService.lambdaQuery().in(TSubject::getId, list).list()); + return R.ok(result); + } + + /** + * 自主故事2-框架记忆 + * + * @param week 周目 + */ + @GetMapping("/frameworkMemory") + @ApiOperation(value = "自主故事2-框架记忆", tags = {"自主故事2-框架记忆"}) + public R<Map<String, Object>> frameworkMemory(@RequestParam Integer week) { + // 看图配音信息 + TStoryListen listen = storyListenService.lambdaQuery().eq(TStoryListen::getWeek, week).one(); + // 获取对应图片语音 + List<String> list = Arrays.asList(listen.getStory().split(",")); + Map<String, Object> result = new HashMap<>(8); + result.put("listen", listen); + result.put("info", subjectService.lambdaQuery().in(TSubject::getId, list).list()); + return R.ok(result); + } + + /** + * 学习完成,生成学习记录,积分明细记录 + * + * @param completeStudy 完成学习信息 + */ + @PostMapping("/completeLearning") + @ApiOperation(value = "完成学习", tags = {"完成学习"}) + public R<Boolean> completeLearning(@RequestBody CompleteStudyDTO completeStudy) { + // 登录用户id + Long userId = SecurityUtils.getUserId(); + // 获取user详细信息,改变积分 + TUser user = userService.getById(userId); + user.setIntegral(user.getIntegral() + completeStudy.getIntegral()); + boolean update = userService.updateById(user); + // 生成积分明细记录 + TIntegralRecord integralRecord = new TIntegralRecord(); + integralRecord.setIntegral(String.valueOf(completeStudy.getIntegral())); + integralRecord.setMethod(completeStudy.getMethod()); + integralRecord.setUserId(SecurityUtils.getUserId().intValue()); + return R.ok(update && integralRecordService.save(integralRecord)); + } + + /** + * 完成故事类型 + */ + @GetMapping("/completeStory") + @ApiOperation(value = "完成故事学习", tags = {"完成故事学习"}) + public R<?> completeStory(@RequestParam Integer integral, @RequestParam Integer storyId, + @RequestParam @ApiParam("完成答题/完成听故事") String method) { + // 添加积分明细记录 + Boolean add = integralRecordService.add(String.valueOf(integral), method); + // 用户信息 + Long userId = SecurityUtils.getUserId(); + TUser user = userService.lambdaQuery().eq(TUser::getId, userId).one(); + // 返回结果 + user.setIntegral(user.getIntegral() + integral); + return R.ok(add && userService.updateById(user)); + } + + @GetMapping("/studyRecord") + @ApiOperation(value = "个人中心-学习记录", tags = {"个人中心-学习记录"}) + public R<Map<String, Object>> studyRecord() { + Long userId = SecurityUtils.getUserId(); + Map<String, Object> result = new HashMap<>(8); + // 学习记录 + result.put("record", userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId) + .eq(TUserStudy::getDisabled, 0).one()); + // 游戏测试成绩 + result.put("gameAchievement", gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId) + .eq(TGameRecord::getDisabled, 0).list()); + return R.ok(result); + } + + @GetMapping("/integralDetail") + @ApiOperation(value = "个人中心-积分明细", tags = {"个人中心-积分明细"}) + public R<IPage<TIntegralRecord>> integralDetail(String time, + @RequestParam("pageNum") Integer pageNum, + @RequestParam("pageSize") Integer pageSize) { + return R.ok(integralRecordService.integralDetail(new Page<>(pageNum, pageSize), SecurityUtils.getUserId(), time)); + } + + /** + * 生成积分明细-用于远程调用 + * + * @param integral 积分变动信息 + * @param method 变动源 + */ + @GetMapping("/addIntegralDetail") + @ApiOperation(value = "添加-积分明细", tags = {"添加-积分明细"}) + public R<Boolean> addIntegralDetail(@RequestParam("integral") String integral, @RequestParam("method") String method) { + TIntegralRecord integralRecord = new TIntegralRecord(); + integralRecord.setIntegral(integral); + integralRecord.setMethod(method); + integralRecord.setUserId(SecurityUtils.getUserId().intValue()); + integralRecord.setDisabled(Boolean.FALSE); + return R.ok(integralRecordService.save(integralRecord)); + } + } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java index 9065f53..0f9bbac 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java @@ -3,8 +3,8 @@ import com.alipay.api.AlipayApiException; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.common.core.constant.RedisConstants; import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.core.utils.JwtUtils; import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.redis.service.RedisService; @@ -21,25 +21,22 @@ import com.ruoyi.study.domain.TVipOrder; import com.ruoyi.study.dto.AppUserQuery; import com.ruoyi.study.dto.UserInfoQuery; +import com.ruoyi.study.request.RegisterPhoneRequest; import com.ruoyi.study.service.ITUserService; import com.ruoyi.study.service.IVipOrderService; import com.ruoyi.study.utils.PayMoneyUtil; import com.ruoyi.study.utils.UUIDUtil; import com.ruoyi.study.vo.*; -import com.ruoyi.system.api.domain.SysRole; -import com.ruoyi.system.api.domain.SysUser; -import com.ruoyi.system.api.model.LoginUser; import com.ruoyi.system.api.model.LoginUserParent; -import io.jsonwebtoken.Claims; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; -import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; @@ -66,12 +63,14 @@ private ManagementClient managementClient; @Autowired private TokenService tokenService; + @Resource + private RedisService redisService; @PostMapping("/vipInfo") @ApiOperation(value = "会员中心-获取会员说明、当前登录用户是否为会员、会员购买规格", tags = {"家长端-个人中心"}) public AjaxResult<List<VipInfoVO>> vipInfo() { - if (tokenService.getLoginUser1() == null){ - return AjaxResult.tokenError("登录失效",new Object()); + if (tokenService.getLoginUser1() == null) { + return AjaxResult.tokenError("登录失效", new Object()); } List<VipInfoVO> vipInfoVOS = new ArrayList<>(); List<TVipSet> data = managementClient.getVipSet1().getData(); @@ -82,13 +81,13 @@ Integer userid = tokenService.getLoginUser1().getUserid(); TUser byId = userService.getById(userid); // 先判断vipEndTime - if (byId.getVipEndTime() == null){ + if (byId.getVipEndTime() == null) { vipInfoVO.setIsVip(0); - }else{ + } else { // 判断会员到期时间是否大于当前时间 - if (byId.getVipEndTime().getTime() > new Date().getTime()){ + if (byId.getVipEndTime().getTime() > new Date().getTime()) { vipInfoVO.setIsVip(1); - }else{ + } else { vipInfoVO.setIsVip(0); } } @@ -98,6 +97,7 @@ } return AjaxResult.ok(vipInfoVOS); } + @Autowired private PayMoneyUtil payMoneyUtil; @@ -108,16 +108,16 @@ @ApiImplicitParam(name = "payType", value = "支付类型 1=微信 2=支付宝", required = true), @ApiImplicitParam(name = "id", value = "会员规格id", required = true), }) - public AjaxResult order(Integer payType,Integer id) throws Exception { - if (tokenService.getLoginUser1() == null){ - return AjaxResult.tokenError("登录失效",new Object()); + public AjaxResult order(Integer payType, Integer id) throws Exception { + if (tokenService.getLoginUser1() == null) { + return AjaxResult.tokenError("登录失效", new Object()); } Integer userid = tokenService.getLoginUser1().getUserid(); TVipOrder tVipOrder = new TVipOrder(); List<TVipSet> data = managementClient.getVipSet1().getData(); Integer time = 0; for (TVipSet datum : data) { - if (datum.getId() == id){ + if (datum.getId() == id) { tVipOrder.setMoney(datum.getAmount()); time = datum.getTime(); } @@ -126,11 +126,11 @@ tVipOrder.setUserId(userid); tVipOrder.setPayType(payType); tVipOrder.setCount(time); - switch (payType){ + switch (payType) { case 1: return payMoneyUtil.weixinpay ("购买会员", "", - id+"_"+tVipOrder.getId() + "_"+ + id + "_" + tVipOrder.getId() + "_" + UUIDUtil.getRandomCode(8), tVipOrder.getMoney().toString(), "/base/wxPayBuyVip", "APP", ""); @@ -139,13 +139,14 @@ ("购买会员", "购买会员下单支付", "", - id+"_"+tVipOrder.getId()+"_"+ + id + "_" + tVipOrder.getId() + "_" + UUIDUtil.getRandomCode(8), tVipOrder.getMoney().toString(), "/base/aliPayBuyVip"); } return AjaxResult.success(); } + @ResponseBody @PostMapping("/base/aliPayBuyVip") public void addVipPaymentAliCallback(HttpServletRequest request, HttpServletResponse response) { @@ -157,9 +158,9 @@ // 会员规格id String s = out_trade_no.split("_")[0]; Integer integer = Integer.valueOf(s); - Integer time = 0; + Integer time = 0; for (TVipSet datum : managementClient.getVipSet1().getData()) { - if (datum.getId() == integer){ + if (datum.getId() == integer) { time = datum.getTime(); } } @@ -174,7 +175,7 @@ TUser byId1 = userService.getById(byId.getUserId()); - if (byId1.getVipPayTime() == null){ + if (byId1.getVipPayTime() == null) { // 是否是首次充值会员 byId1.setVipPayTime(new Date()); Calendar calendar = Calendar.getInstance(); @@ -183,16 +184,16 @@ Date dateAfterOneMonth = calendar.getTime(); byId.setTime(dateAfterOneMonth); byId1.setVipEndTime(dateAfterOneMonth); - }else{ + } else { // 不是首次 判断vipEndTime 是否到期 如果没有 加指定月份时间 如果到期了 将会员到期时间从当前增加指定月份 - if (byId1.getVipEndTime().getTime() < new Date().getTime()){ + if (byId1.getVipEndTime().getTime() < new Date().getTime()) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.MONTH, time); Date dateAfterOneMonth = calendar.getTime(); byId.setTime(dateAfterOneMonth); byId1.setVipEndTime(dateAfterOneMonth); - }else{ + } else { Calendar calendar = Calendar.getInstance(); calendar.setTime(byId1.getVipEndTime()); calendar.add(Calendar.MONTH, time); @@ -216,6 +217,7 @@ e.printStackTrace(); } } + @ResponseBody @PostMapping("/base/wxPayBuyVip") public void wxPayBuyPackage(HttpServletRequest request, HttpServletResponse response) { @@ -230,9 +232,9 @@ // 会员规格id String s = out_trade_no.split("_")[0]; Integer integer = Integer.valueOf(s); - Integer time = 0; + Integer time = 0; for (TVipSet datum : managementClient.getVipSet1().getData()) { - if (datum.getId() == integer){ + if (datum.getId() == integer) { time = datum.getTime(); } } @@ -247,7 +249,7 @@ TUser byId1 = userService.getById(byId.getUserId()); - if (byId1.getVipPayTime() == null){ + if (byId1.getVipPayTime() == null) { // 是否是首次充值会员 byId1.setVipPayTime(new Date()); Calendar calendar = Calendar.getInstance(); @@ -256,16 +258,16 @@ Date dateAfterOneMonth = calendar.getTime(); byId.setTime(dateAfterOneMonth); byId1.setVipEndTime(dateAfterOneMonth); - }else{ + } else { // 不是首次 判断vipEndTime 是否到期 如果没有 加指定月份时间 如果到期了 将会员到期时间从当前增加指定月份 - if (byId1.getVipEndTime().getTime() < new Date().getTime()){ + if (byId1.getVipEndTime().getTime() < new Date().getTime()) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.MONTH, time); Date dateAfterOneMonth = calendar.getTime(); byId.setTime(dateAfterOneMonth); byId1.setVipEndTime(dateAfterOneMonth); - }else{ + } else { Calendar calendar = Calendar.getInstance(); calendar.setTime(byId1.getVipEndTime()); calendar.add(Calendar.MONTH, time); @@ -287,59 +289,55 @@ e.printStackTrace(); } } + @PostMapping("/getPage") @ApiOperation(value = "获取注意事项", tags = {"家长端-注意事项"}) public AjaxResult<String> getPage() { List<TPage> data = managementClient.getPage1().getData(); for (TPage datum : data) { - if (datum.getType() == 4){ - return AjaxResult.success(datum.getImg()); + if (datum.getType() == 4) { + return AjaxResult.success(datum); } } return AjaxResult.success(); } + @PostMapping("/useGuide") @ApiOperation(value = "使用指南", tags = {"家长端-使用指南"}) public AjaxResult<PageInfo<TUseGuide>> useGuide(@RequestBody UseGuideQuery query) { PageInfo<TUseGuide> data = managementClient.useGuide1(query).getData(); return AjaxResult.success(data); } + @PostMapping("/feedBack") @ApiOperation(value = "反馈", tags = {"家长端-意见反馈"}) public AjaxResult feedBack(@RequestBody TFeedback dto) { - if (tokenService.getLoginUser1() == null){ - return AjaxResult.tokenError("登录失效",new Object()); + if (tokenService.getLoginUser1() == null) { + return AjaxResult.tokenError("登录失效", new Object()); } LoginUserParent loginUser1 = tokenService.getLoginUser1(); dto.setUserId(loginUser1.getUserid()); managementClient.addFeedBack(dto); return AjaxResult.success("反馈成功"); } + @PostMapping("/parentLogin") @ApiOperation(value = "登录", tags = {"家长端-登录"}) @ApiImplicitParams({ @ApiImplicitParam(value = "手机号", name = "phone", dataType = "string", required = true), @ApiImplicitParam(value = "验证码", name = "phoneCode", dataType = "string", required = true) }) - public AjaxResult login(String phone, String phoneCode) - { + public AjaxResult login(String phone, String phoneCode) { TUser tUser1 = userService.getOne(new QueryWrapper<TUser>() .ne("state", 3) - .eq("phone",phone)); - if (tUser1 != null){ - if (tUser1.getState() == 2){ + .eq("phone", phone)); + if (tUser1 != null) { + if (tUser1.getState() == 2) { return AjaxResult.error("登录失败,您的账号已被冻结!"); } - }else{ + } else { // todo 验证码校验 - tUser1 = new TUser(); - // 注册 - tUser1.setName(phone); - tUser1.setAccount(phone); - tUser1.setState(1); - tUser1.setInsertTime(new Date()); - tUser1.setCreateTime(new Date()); - tUser1.setPhone(phone); + tUser1 = getUser(phone); userService.save(tUser1); } LoginUserParent loginUserParent = new LoginUserParent(); @@ -348,11 +346,79 @@ loginUserParent.setPhone(tUser1.getPhone()); loginUserParent.setLoginTime(new Date().getTime()); HashMap<String, Object> map = new HashMap<>(); - map.put("token",tokenService.createToken1(loginUserParent)); + map.put("token", tokenService.createToken1(loginUserParent)); // 获取登录token return AjaxResult.success(map); } + /** + * 学生端登录 + * + * @param phoneRequest 手机号及手机验证码 + */ + @PostMapping("/studyLogin") + @ApiOperation(value = "学习端-登录", tags = {"学习端-登录"}) + public AjaxResult studyLogin(@RequestBody @Validated RegisterPhoneRequest phoneRequest) { + String phone = phoneRequest.getPhone(); + String phoneCode = phoneRequest.getPhoneCode(); + TUser user = userService.getOne(new QueryWrapper<TUser>() + .ne("state", 3) + .eq("phone", phone)); + if (user != null) { + if (user.getState() == 2) { + return AjaxResult.error("登录失败,您的账号已被冻结!"); + } + } else { + // 手机验证码校验 + Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone); + if (null == redisPhoneCode) { + return AjaxResult.error("登录失败,手机验证码已过期!"); + } else { + // redis 验证码的value 为 code:时间戳 + String rCodeAndTime = String.valueOf(redisPhoneCode); + String rCode = rCodeAndTime.split(":")[0]; + if (!rCode.equalsIgnoreCase(phoneCode)) { + return AjaxResult.error("登录失败,手机验证码输入有误!"); + } else { + user = getUser(phone); + userService.save(user); + } + } + } + // 生成登录用户信息 + LoginUserParent loginUserParent = new LoginUserParent(); + loginUserParent.setName(user.getName()); + loginUserParent.setUserid(user.getId()); + loginUserParent.setPhone(user.getPhone()); + loginUserParent.setLoginTime(System.currentTimeMillis()); + HashMap<String, Object> map = new HashMap<>(); + map.put("token", tokenService.createTokenStudy(loginUserParent)); + // 获取登录token + return AjaxResult.success(map); + } + + private TUser getUser(String phone) { + TUser user = new TUser(); + // 注册 + user.setName(phone); + user.setAccount(phone); + user.setState(1); + user.setInsertTime(new Date()); + user.setCreateTime(new Date()); + user.setPhone(phone); + return user; + } + + /** + * 家长端 学习端都可用 + * + * @param phone 手机号 + */ + @GetMapping("/sendPhoneCode") + @ApiOperation(value = "发送手机验证码", tags = {"家长端/学习端-发送手机验证码"}) + public AjaxResult sendPhoneCode(@RequestParam String phone) { + return userService.phoneCode(phone) ? AjaxResult.success() : AjaxResult.error(); + } @PostMapping("/deleteUser") @ApiOperation(value = "注销当前帐号", tags = {"家长端-个人中心"}) @@ -360,8 +426,8 @@ @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), }) public AjaxResult deleteUser() { - if (tokenService.getLoginUser1() == null){ - return AjaxResult.tokenError("登录失效"); + if (tokenService.getLoginUser1() == null) { + return AjaxResult.tokenError("登录失效"); } Integer userid = tokenService.getLoginUser1().getUserid(); TUser tUser = userService.getById(userid); @@ -372,24 +438,25 @@ userService.removeById(tUser); return AjaxResult.success("注销成功"); } + @PostMapping("/logout") @ApiOperation(value = "退出登录", tags = {"家长端-个人中心"}) @ApiImplicitParams({ @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), }) public AjaxResult logout(HttpServletRequest request) { - if (tokenService.getLoginUser1() == null){ + if (tokenService.getLoginUser1() == null) { return AjaxResult.tokenError("登录失效"); } String token = SecurityUtils.getToken(request); - if (com.ruoyi.common.core.utils.StringUtils.isNotEmpty(token)) - { + if (com.ruoyi.common.core.utils.StringUtils.isNotEmpty(token)) { // 删除用户缓存记录 AuthUtil.logoutByToken1(token); } // todo 清除token return AjaxResult.success("退出登录成功"); } + @PostMapping("/updateUserInfo") @ApiOperation(value = "修改个人资料", tags = {"家长端-个人中心"}) @ApiImplicitParams({ @@ -398,83 +465,36 @@ @ApiImplicitParam(name = "phone", value = "电话 改什么就只传什么"), @ApiImplicitParam(name = "headImg", value = "头像 改什么就只传什么"), }) - public AjaxResult updateUserInfo(String name, String phone,String headImg) { - if (tokenService.getLoginUser1() == null){ - return AjaxResult.tokenError("登录失效",new Object()); - } + public AjaxResult updateUserInfo(String name, String phone, String headImg) { // todo 获取用户id Integer userid = tokenService.getLoginUser1().getUserid(); TUser byId = userService.getById(userid); - if (StringUtils.hasLength(name)){ + if (StringUtils.hasLength(name)) { byId.setName(name); } - if (StringUtils.hasLength(phone)){ + if (StringUtils.hasLength(phone)) { // 先判断手机号是否和当前用户手机号一致 // if (byId == null){ // return AjaxResult.tokenError("登录失效"); // } - if (phone.equals(byId.getPhone())){ + if (phone.equals(byId.getPhone())) { return AjaxResult.error("更换的手机号不能和原手机号相同"); } List<TUser> list = userService.list(new QueryWrapper<TUser>() .eq("phone", phone) .ne("state", 3)); - if (list.size() > 0){ - return AjaxResult.error("更换的手机号已被使用",new Object()); + if (list.size() > 0) { + return AjaxResult.error("更换的手机号已被使用", new Object()); } byId.setPhone(phone); } - if (StringUtils.hasLength(headImg)){ + if (StringUtils.hasLength(headImg)) { byId.setHeadImg(headImg); } userService.saveOrUpdate(byId); return AjaxResult.success("修改成功"); - } - @ResponseBody - @PostMapping("/base/wxRefund") - public void cancelMySiteCallback(HttpServletRequest request, HttpServletResponse response) { - try { - Map<String, String> map = payMoneyUtil.wxRefundCallback(request); - if (null != map) { - String code = map.get("out_refund_no"); - String refund_id = map.get("refund_id"); - String result = map.get("result"); - TVipOrder one = vipOrderService.getOne(new QueryWrapper<TVipOrder>() - .eq("outTradeNo", code) - .eq("payState", 3)); - one.setBackTime(new Date()); - vipOrderService.updateById(one); - Integer userId = one.getUserId(); - TUser byId1 = userService.getById(userId); - // 判断用户是不是第一次充值 - List<TVipOrder> list = vipOrderService.list(new QueryWrapper<TVipOrder>() - .eq("userId", userId) - .eq("payState", 2) - .orderByDesc("createTime")); - int size = list.size(); - if (size == 0){ - // 证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空 - byId1.setVipEndTime(null); - byId1.setVipPayTime(null); - userService.updateById(byId1); - }else{ - // 最近的一次充值会员时间 - TVipOrder tVipOrder = list.get(0); - // 将会员到期时间回退到上一次 - byId1.setVipEndTime(tVipOrder.getTime()); - userService.updateById(byId1); - } - - PrintWriter out = response.getWriter(); - out.write(result); - out.flush(); - out.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } } @PostMapping("/vipBack/{id}") @ApiOperation(value = "会员退款", tags = {"管理后台-会员退款"}) @@ -488,8 +508,39 @@ case 1: // 微信退款 Map<String, String> stringStringMap = payMoneyUtil.wxRefund(transactionId, outTradeNo, byId.getMoney().toString(), byId.getMoney().toString(), "/base/wxRefund"); - if (null == stringStringMap) { - return R.fail("取消退款异常"); + if (stringStringMap.get("code").equals("SUCCESS")){ + byId.setPayState(3); + byId.setBackTime(new Date()); + vipOrderService.updateById(byId); + // 用户的vip剩余时间减少 + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + calendar.add(Calendar.MONTH, -byId.getCount()); + Date dateAfterOneMonth = calendar.getTime(); + Integer userId = byId.getUserId(); + TUser byId1 = userService.getById(userId); + // 判断用户是不是第一次充值 + List<TVipOrder> list = vipOrderService.list(new QueryWrapper<TVipOrder>() + .eq("userId", userId) + .eq("payState", 2) + .orderByDesc("createTime")); + int size = list.size(); + if (size == 0) { + // 证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空 + byId1.setVipEndTime(null); + byId1.setVipPayTime(null); + userService.updateById(byId1); + } else { + // 最近的一次充值会员时间 + TVipOrder tVipOrder = list.get(0); + // 将会员到期时间回退到上一次 + byId1.setVipEndTime(tVipOrder.getTime()); + userService.updateById(byId1); + } + + return R.ok(); + }else{ + return R.fail(stringStringMap.get("msg")); } String result_code = stringStringMap.get("result_code"); if (!"SUCCESS".equals(result_code)) { @@ -523,12 +574,12 @@ .eq("payState", 2) .orderByDesc("createTime")); int size = list.size(); - if (size == 0){ + if (size == 0) { // 证明这是用户第一次充值会员 将首次充值会员时间和会员到期时间清空 byId1.setVipEndTime(null); byId1.setVipPayTime(null); userService.updateById(byId1); - }else{ + } else { // 最近的一次充值会员时间 TVipOrder tVipOrder = list.get(0); // 将会员到期时间回退到上一次 @@ -536,21 +587,25 @@ userService.updateById(byId1); } return R.ok(); + } else { + return R.fail(stringStringMap1.get("msg")); + } } return R.ok(); } + @PostMapping("/userList") @ApiOperation(value = "用户列表", tags = {"管理后台-用户管理"}) public R<PageInfo<AppUserVO>> couponReceive(@RequestBody AppUserQuery query) { PageInfo<AppUserVO> res = new PageInfo<>(query.getPageNumber(), query.getPageSize()); - List<AppUserVO> list = userService.listAll(query); + List<AppUserVO> list = userService.listAll(query); for (AppUserVO appUserVO : list) { - if (appUserVO.getVipEndTime() == null){ + if (appUserVO.getVipEndTime() == null) { appUserVO.setIsVip(0); - }else{ - if (appUserVO.getVipEndTime().getTime() > System.currentTimeMillis()){ + } else { + if (appUserVO.getVipEndTime().getTime() > System.currentTimeMillis()) { appUserVO.setIsVip(1); - }else{ + } else { appUserVO.setIsVip(0); } } @@ -574,16 +629,16 @@ Date insertTime = byId.getInsertTime(); Date vipPayTime = byId.getVipPayTime(); Date vipEndTime = byId.getVipEndTime(); - if (vipEndTime == null){ + if (vipEndTime == null) { res.setIsVip(0); - }else{ - if (vipEndTime.getTime() > System.currentTimeMillis()){ + } else { + if (vipEndTime.getTime() > System.currentTimeMillis()) { res.setIsVip(1); - }else{ + } else { res.setIsVip(0); } } - if (vipPayTime!=null){ + if (vipPayTime != null) { res.setVipPayTime(format.format(vipPayTime)); } res.setState(byId.getState()); @@ -605,15 +660,16 @@ res.setGameRecords(list); return R.ok(res); } + @PostMapping("/freeze/{id}") @ApiOperation(value = "冻结/解冻", tags = {"管理后台-用户管理"}) - public R freeze(@PathVariable("id") Integer id) { + public R freeze(@PathVariable("id") Integer id) { TUser byId = userService.getById(id); if (byId.getState() == 1) { byId.setState(2); userService.updateById(byId); return R.ok("冻结成功"); - }else { + } else { byId.setState(1); userService.updateById(byId); return R.ok("解冻成功"); @@ -625,7 +681,7 @@ @ApiOperation(value = "列表查询", tags = {"管理后台-会员管理"}) public R<PageInfo<VipOrderVO>> vipOrderList(@RequestBody AppUserQuery query) { PageInfo<VipOrderVO> res = new PageInfo<>(query.getPageNumber(), query.getPageSize()); - List<VipOrderVO> list = vipOrderService.listAll(query); + List<VipOrderVO> list = vipOrderService.listAll(query); res.setRecords(list); res.setTotal(list.size()); return R.ok(res); diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TGameRecord.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TGameRecord.java index 36f321a..4b8493d 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TGameRecord.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TGameRecord.java @@ -30,20 +30,35 @@ * 用户id */ @ApiModelProperty(value = "用户id") - private Integer userId;/** + private Integer userId; /** + * /** * 正确率 */ @ApiModelProperty(value = "正确率") - private Integer accuracy;/** + private Integer accuracy; + /** * 游戏名称 */ @ApiModelProperty(value = "游戏名称") - private String gameName;/** + private String gameName; + /** * 用时时间 秒 */ @ApiModelProperty(value = "用时时间 秒") private Integer useTime; + /** + * 游戏Id + */ + @ApiModelProperty(value = "游戏Id") + private Integer gameId; + + /** + * 游戏难度(0入门、1中级、2高级) + */ + @ApiModelProperty(value = "游戏难度(0入门、1中级、2高级)") + private Integer gameDifficulty; + } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java index c1989ef..42db5a1 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java @@ -39,5 +39,12 @@ */ private Integer userId; - + /** + * 前端用,返回积分变动类型 + * + * @return 变动类型中文字符串 + */ + public String getType() { + return integral.startsWith("-") ? "减少" : "增加"; + } } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteGameDTO.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteGameDTO.java new file mode 100644 index 0000000..a1b554a --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteGameDTO.java @@ -0,0 +1,50 @@ +package com.ruoyi.study.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-20 14:04 + */ +@Data +public class CompleteGameDTO { + + /** + * 游戏难度 + */ + @ApiModelProperty("游戏难度") + private Integer difficulty; + + /** + * 游戏id + */ + @ApiModelProperty("游戏id") + private Integer gameId; + + /** + * 用时时间 秒 + */ + @ApiModelProperty("用时时间 秒") + private Integer useTime; + + /** + * 游戏名称 + */ + @ApiModelProperty("游戏名称") + private String gameName; + + /** + * 正确率 + */ + @ApiModelProperty("正确率") + private Integer accuracy; + + /** + * 完成听故事、完成游戏、完成答题、完成每日学习、商城消费 + */ + @ApiModelProperty("完成听故事、完成游戏、完成答题、完成每日学习、商城消费") + private String method; + +} diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteStudyDTO.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteStudyDTO.java new file mode 100644 index 0000000..62dfa50 --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteStudyDTO.java @@ -0,0 +1,26 @@ +package com.ruoyi.study.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-20 14:04 + */ +@Data +public class CompleteStudyDTO { + + /** + * 积分数量 + */ + @ApiModelProperty("积分数量") + private Integer integral; + + /** + * 完成听故事、完成游戏、完成答题、完成每日学习、商城消费 + */ + @ApiModelProperty("完成听故事、完成游戏、完成答题、完成每日学习、商城消费") + private String method; + +} diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java new file mode 100644 index 0000000..3dd7944 --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java @@ -0,0 +1,28 @@ +package com.ruoyi.study.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author HJL + */ +@EqualsAndHashCode(callSuper = true) +@Data +@ApiModel(value = "选择周目列表DTO") +public class StudyWeekDTO extends StudyDTO { + + @ApiModelProperty("完成后可获积分数") + private Integer totalIntegral; + + @ApiModelProperty("所属季度") + private Integer quarter; + + @ApiModelProperty("本周主题") + private String title; + + @ApiModelProperty("study表Id") + private String id; + +} diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/TGoodsVO.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/TGoodsVO.java new file mode 100644 index 0000000..1098e88 --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/TGoodsVO.java @@ -0,0 +1,233 @@ +package com.ruoyi.study.dto; + + +import com.ruoyi.common.core.web.domain.BaseModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * <p> + * 商品表 + * </p> + * + * @author 无关风月 + * @since 2024-04-26 + */ +@Data +public class TGoodsVO extends BaseModel { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "剩余数量") + private Long inventory; + /** + * 主键id + */ + private Integer id; + /** + * 商品名称 + */ + @ApiModelProperty(value = "商品名称") + private String name; + /** + * 所需积分 + */ + @ApiModelProperty(value = "所需积分") + private String integral; + /** + * 商品原价 + */ + @ApiModelProperty(value = "商品原价") + private BigDecimal price; + /** + * 商品总数 + */ + @ApiModelProperty(value = "商品总数") + private Integer total; + /** + * 剩余数量 + */ + @ApiModelProperty(value = "剩余数量") + private Integer surplus; + /** + * 单个用户可兑换数量 + */ + @ApiModelProperty(value = "单个用户可兑换数量") + private Integer userCount; + /** + * 商品类型id + */ + @ApiModelProperty(value = "商品类型id") + private Integer typeId; + /** + * 商品封面图 + */ + @ApiModelProperty(value = "商品封面图") + private String coverImg; + /** + * 商品详情图片 多张逗号隔开 + */ + @ApiModelProperty(value = "商品详情图片 多张逗号隔开") + private String detailImg; + /** + * 商品详情 + */ + @ApiModelProperty(value = "商品详情") + private String detail; + /** + * 插入时间 + */ + @ApiModelProperty(value = "插入时间") + private Date insertTime; + /** + * 是否删除 0否1是 + */ + @ApiModelProperty(value = "是否删除 0否1是") + private Integer isDelete; + /** + * 兑换类型 1.0商城只有积分兑换 保留字段 + */ + @ApiModelProperty(value = "前端忽略 兑换类型 1.0商城只有积分兑换 保留字段 ") + private Integer type; + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getintegral() { + return +integral; + } + + public void setintegral(String +integral) { + this. +integral = +integral; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + public Integer getSurplus() { + return surplus; + } + + public void setSurplus(Integer surplus) { + this.surplus = surplus; + } + + public Integer getUserCount() { + return userCount; + } + + public void setUserCount(Integer userCount) { + this.userCount = userCount; + } + + public Integer getTypeId() { + return typeId; + } + + public void setTypeId(Integer typeId) { + this.typeId = typeId; + } + + public String getCoverImg() { + return coverImg; + } + + public void setCoverImg(String coverImg) { + this.coverImg = coverImg; + } + + public String getDetailImg() { + return detailImg; + } + + public void setDetailImg(String detailImg) { + this.detailImg = detailImg; + } + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } + + public Date getInsertTime() { + return insertTime; + } + + public void setInsertTime(Date insertTime) { + this.insertTime = insertTime; + } + + public Integer getIsDelete() { + return isDelete; + } + + public void setIsDelete(Integer isDelete) { + this.isDelete = isDelete; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + @Override + public String toString() { + return "TGoods{" + + ", id=" + id + + ", name=" + name + + ", integral=" + +integral + + ", price=" + price + + ", total=" + total + + ", surplus=" + surplus + + ", userCount=" + userCount + + ", typeId=" + typeId + + ", coverImg=" + coverImg + + ", detailImg=" + detailImg + + ", detail=" + detail + + ", insertTime=" + insertTime + + ", isDelete=" + isDelete + + ", type=" + type + + "}"; + } +} diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TIntegralRecordMapper.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TIntegralRecordMapper.java index ee66b7b..3be585d 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TIntegralRecordMapper.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TIntegralRecordMapper.java @@ -1,8 +1,10 @@ package com.ruoyi.study.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.study.domain.TGameRecord; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.study.domain.TIntegralRecord; +import org.apache.ibatis.annotations.Param; /** * <p> @@ -14,4 +16,13 @@ */ public interface TIntegralRecordMapper extends BaseMapper<TIntegralRecord> { + /** + * 用户积分明细 + * + * @param page 分页 + * @param userId 用户id + * @param time yyyy-mm格式时间 + * @return 分页列表 + */ + IPage<TIntegralRecord> integralDetail(@Param("userId") Long userId, @Param("time") String time, Page<TIntegralRecord> page); } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStudyMapper.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStudyMapper.java index 85d84fc..61a4f8a 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStudyMapper.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStudyMapper.java @@ -2,6 +2,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.study.domain.TStudy; +import com.ruoyi.study.dto.StudyWeekDTO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * <p> @@ -13,4 +17,12 @@ */ public interface TStudyMapper extends BaseMapper<TStudy> { + /** + * 查询周目列表 + * + * @param type 所属类型 + * @param quarter 季度 + * @return 列表 + */ + List<StudyWeekDTO> weekList(@Param("type") Integer type,@Param("quarter") Integer quarter); } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/request/RegisterPhoneRequest.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/request/RegisterPhoneRequest.java new file mode 100644 index 0000000..793cda8 --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/request/RegisterPhoneRequest.java @@ -0,0 +1,22 @@ +package com.ruoyi.study.request; + +import com.ruoyi.common.core.constant.Constants; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-17 14:57 + */ +@Data +public class RegisterPhoneRequest { + + @Pattern(regexp = Constants.PHONE, message = "手机号不合法,请重试!") + private String phone; + @NotBlank(message = "验证码不能为空!") + private String phoneCode; + +} diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameRecordService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameRecordService.java index 141ca9e..6935cd7 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameRecordService.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameRecordService.java @@ -1,8 +1,8 @@ package com.ruoyi.study.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.study.domain.TGame; import com.ruoyi.study.domain.TGameRecord; +import com.ruoyi.study.dto.CompleteGameDTO; /** * <p> @@ -14,4 +14,11 @@ */ public interface ITGameRecordService extends IService<TGameRecord> { + /** + * 生成游戏记录 + * + * @param gameAchievement 游戏信息 + * @return 操作结果 + */ + Boolean add(CompleteGameDTO gameAchievement); } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITIntegralRecordService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITIntegralRecordService.java index b2d4b7b..3b07b34 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITIntegralRecordService.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITIntegralRecordService.java @@ -1,7 +1,8 @@ package com.ruoyi.study.service; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.study.domain.TGameRecord; import com.ruoyi.study.domain.TIntegralRecord; /** @@ -14,4 +15,22 @@ */ public interface ITIntegralRecordService extends IService<TIntegralRecord> { + /** + * 用户积分明细 + * + * @param page 分页 + * @param userId 用户id + * @param time yyyy-mm格式时间 + * @return 分页列表 + */ + IPage<TIntegralRecord> integralDetail(Page<TIntegralRecord> page, Long userId, String time); + + /** + * 生成积分明细 + * + * @param integral 积分 (增加积分+ 、减少积分-) + * @param method 积分来源 + * @return 操作结果 + */ + Boolean add(String integral, String method); } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java index 66a8b27..81afdb0 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java @@ -1,7 +1,11 @@ package com.ruoyi.study.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.study.domain.TStudy; +import com.ruoyi.study.domain.*; +import com.ruoyi.study.dto.StudyWeekDTO; + +import java.util.List; +import java.util.Map; /** * <p> @@ -13,4 +17,82 @@ */ public interface ITStudyService extends IService<TStudy> { + /** + * 查询周目列表 + * + * @param type 所属类型 + * @param quarter 季度 + * @return 列表 + */ + List<StudyWeekDTO> weekList(Integer type, Integer quarter); + + /** + * 获取学习进度及学习时长等信息 + * + * @param userId 用户id + * @param week 周目 + * @param day 所属day + * @return 学习信息 + */ + TUserStudy studySchedule(String userId, Integer week, Integer day); + + /** + * 自主学习1-听音选图 + * + * @param week 周目 + * @param day 所属day + * @param studyListens 数据集合 + * @return 单个题组下所包含的所有图片及语音 + */ + Map<String, Object> listenSelectPicture(Integer week, Integer day, List<TStudyListen> studyListens); + + /** + * 自主游戏1-超级听力 + * + * @param difficulty 难度(0入门、1中级、2高级) + * @param week 所属周目 + * @param game 游戏信息 + */ + void checkDifficulty(Integer difficulty, Integer week, TGame game); + + /** + * 自主学习2-看图选音 + * + * @param week 周目 + * @param day 所属day + * @param lookList 数据集合 + * @return 单个题组下所包含的所有图片及语音 + */ + Map<String, Object> pictureSelectVoice(Integer week, Integer day, List<TStudyLook> lookList); + + /** + * 自主学习3-归纳排除 + * + * @param week 周目 + * @param day 所属day + * @param inductionList 归纳排除 + * @return 题目信息 + */ + Map<String, Object> induceExclude(Integer week, Integer day, List<TStudyInduction> inductionList); + + /** + * 自主学习4-有问有答 + * + * @param week 周目 + * @param day 所属day + * @param answerList 有问有答 + * @return 题目信息 + */ + Map<String, Object> questionsAndAnswers(Integer week, Integer day, List<TStudyAnswer> answerList); + + /** + * 自主学习5-音图相配 + * + * @param week 周目 + * @param day 所属day + * @param pair 音图相配 + * @return 题目信息 + */ + Map<String, Object> pictureMateVoice(Integer week, Integer day, TStudyPair pair); + } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserService.java index b78562c..d001aef 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserService.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserService.java @@ -20,4 +20,18 @@ List<AppUserVO> listAll(AppUserQuery query); + /** + * 发送手机验证码 + * + * @param phone 手机号信息 + * @return 验证码发送结果 + */ + Boolean phoneCode(String phone); + + /** + * 判断当前登录用户是否为vip + * + * @return 判断结果 + */ + Boolean isVip(); } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java index bb199e6..edfba55 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java @@ -1,7 +1,6 @@ package com.ruoyi.study.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.ruoyi.study.domain.TGame; import com.ruoyi.study.domain.TUserStudy; /** @@ -14,4 +13,20 @@ */ public interface ITUserStudyService extends IService<TUserStudy> { + /** + * 获取学习进度及学习时长等信息 + * + * @param userId 用户id + * @param week 周目 + * @param day 所属day + * @return 学习信息 + */ + TUserStudy studySchedule(String userId, Integer week, Integer day); + + /** + * 根据条件清空用户学习时长 + * + * @param time 今日/本周/本月 + */ + void resettingStudyRecord(String time); } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameRecordServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameRecordServiceImpl.java index adfd048..8d92964 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameRecordServiceImpl.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameRecordServiceImpl.java @@ -1,13 +1,13 @@ package com.ruoyi.study.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.study.domain.TGame; +import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.study.domain.TGameRecord; -import com.ruoyi.study.mapper.TGameMapper; +import com.ruoyi.study.dto.CompleteGameDTO; import com.ruoyi.study.mapper.TGameRecordMapper; import com.ruoyi.study.service.ITGameRecordService; -import com.ruoyi.study.service.ITGameService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * <p> @@ -20,4 +20,16 @@ @Service public class TGameRecordServiceImpl extends ServiceImpl<TGameRecordMapper, TGameRecord> implements ITGameRecordService { + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean add(CompleteGameDTO gameAchievement) { + TGameRecord data = new TGameRecord(); + data.setUserId(SecurityUtils.getUserId().intValue()); + data.setAccuracy(gameAchievement.getAccuracy()); + data.setGameName(gameAchievement.getGameName()); + data.setUseTime(gameAchievement.getUseTime()); + data.setGameId(gameAchievement.getGameId()); + data.setGameDifficulty(gameAchievement.getDifficulty()); + return this.save(data); + } } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TIntegralRecordServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TIntegralRecordServiceImpl.java index e2dd428..8e04157 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TIntegralRecordServiceImpl.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TIntegralRecordServiceImpl.java @@ -1,13 +1,14 @@ package com.ruoyi.study.service.impl; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.study.domain.TGameRecord; +import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.study.domain.TIntegralRecord; -import com.ruoyi.study.mapper.TGameRecordMapper; import com.ruoyi.study.mapper.TIntegralRecordMapper; -import com.ruoyi.study.service.ITGameRecordService; import com.ruoyi.study.service.ITIntegralRecordService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * <p> @@ -20,4 +21,18 @@ @Service public class TIntegralRecordServiceImpl extends ServiceImpl<TIntegralRecordMapper, TIntegralRecord> implements ITIntegralRecordService { + @Override + public IPage<TIntegralRecord> integralDetail(Page<TIntegralRecord> page, Long userId, String time) { + return baseMapper.integralDetail(userId, time, page); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean add(String integral, String method) { + TIntegralRecord integralRecord = new TIntegralRecord(); + integralRecord.setIntegral(integral); + integralRecord.setMethod(method); + integralRecord.setUserId(SecurityUtils.getUserId().intValue()); + return this.save(integralRecord); + } } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java index 5891770..c7c51cf 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java @@ -1,10 +1,17 @@ package com.ruoyi.study.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.study.domain.TStudy; +import com.ruoyi.common.core.exception.GlobalException; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.study.domain.*; +import com.ruoyi.study.dto.StudyWeekDTO; import com.ruoyi.study.mapper.TStudyMapper; -import com.ruoyi.study.service.ITStudyService; +import com.ruoyi.study.service.*; import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; /** * <p> @@ -17,4 +24,113 @@ @Service public class TStudyServiceImpl extends ServiceImpl<TStudyMapper, TStudy> implements ITStudyService { + @Resource + private ITUserStudyService userStudyService; + @Resource + private ITStudyListenService studyListenService; + @Resource + private ITSubjectService subjectService; + @Resource + private ITGameRecordService gameRecordService; + + private final static Map<String, Integer> GAME_DIFFICULTY_MAP = new HashMap<>(); + + static { + GAME_DIFFICULTY_MAP.put("1", 0); + GAME_DIFFICULTY_MAP.put("2", 1); + } + + @Override + public List<StudyWeekDTO> weekList(Integer type, Integer quarter) { + return baseMapper.weekList(type, quarter); + } + + @Override + public TUserStudy studySchedule(String userId, Integer week, Integer day) { + return userStudyService.studySchedule(userId, week, day); + } + + @Override + public void checkDifficulty(Integer difficulty, Integer week, TGame game) { + // 判断用户是否完成上一个等级 + Integer level = GAME_DIFFICULTY_MAP.get(String.valueOf(difficulty)); + if (null == level) { + throw new GlobalException("游戏等级异常,请重试!"); + } + // 获取用户游戏进度 + Long userId = SecurityUtils.getUserId(); + List<TGameRecord> list = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId).eq(TGameRecord::getGameId, game.getId()).list(); + boolean contains = list.stream().map(TGameRecord::getGameDifficulty).collect(Collectors.toList()).contains(level); + if (!contains) { + throw new GlobalException("请先完成上一难度再挑战"); + } + } + + @Override + public Map<String, Object> listenSelectPicture(Integer week, Integer day, List<TStudyListen> studyListens) { + // 随机获取一组题 + Random rand = new Random(); + TStudyListen data = studyListens.get(rand.nextInt(studyListens.size())); + List<TSubject> subjectList = getSubjects(data.getSubject().split(",")); + Map<String, Object> result = new HashMap<>(8); + result.put("data", data); + result.put("subject", subjectList); + return result; + } + + @Override + public Map<String, Object> pictureSelectVoice(Integer week, Integer day, List<TStudyLook> lookList) { + // 随机获取一组题 + Random rand = new Random(); + TStudyLook data = lookList.get(rand.nextInt(lookList.size())); + List<TSubject> subjectList = getSubjects(data.getSubject().split(",")); + Map<String, Object> result = new HashMap<>(8); + result.put("data", data); + result.put("subject", subjectList); + return result; + } + + @Override + public Map<String, Object> induceExclude(Integer week, Integer day, List<TStudyInduction> inductionList) { + // 随机获取一组题 + Random rand = new Random(); + TStudyInduction data = inductionList.get(rand.nextInt(inductionList.size())); + List<TSubject> subjectList = getSubjects(data.getSubject().split(",")); + Map<String, Object> result = new HashMap<>(8); + result.put("data", data); + result.put("subject", subjectList); + return result; + } + + @Override + public Map<String, Object> questionsAndAnswers(Integer week, Integer day, List<TStudyAnswer> answerList) { + // 随机获取一组题 + Random rand = new Random(); + TStudyAnswer data = answerList.get(rand.nextInt(answerList.size())); + // 获取问题题目 和 回答题目 + Map<String, Object> result = new HashMap<>(8); + result.put("data", data); + // todo 有问有答 + return result; + } + + @Override + public Map<String, Object> pictureMateVoice(Integer week, Integer day, TStudyPair pair) { + List<TSubject> subjectList = getSubjects(pair.getSubject().split(",")); + Map<String, Object> result = new HashMap<>(8); + result.put("data", pair); + result.put("subject", subjectList); + return result; + } + + /** + * 根据参数id查询图片及语音 + * + * @param ids 多个id + * @return 图片及语音集合 + */ + private List<TSubject> getSubjects(String[] ids) { + return subjectService.lambdaQuery().in(TSubject::getId, Arrays.asList(ids)).list(); + } + } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java index 0fcce24..54ab466 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java @@ -1,14 +1,23 @@ package com.ruoyi.study.service.impl; +import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.constant.RedisConstants; +import com.ruoyi.common.core.exception.GlobalException; +import com.ruoyi.common.security.service.TokenService; import com.ruoyi.study.domain.TUser; import com.ruoyi.study.dto.AppUserQuery; import com.ruoyi.study.mapper.TUserMapper; import com.ruoyi.study.service.ITUserService; import com.ruoyi.study.vo.AppUserVO; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.util.Date; import java.util.List; +import java.util.concurrent.TimeUnit; /** * <p> @@ -21,8 +30,60 @@ @Service public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements ITUserService { + @Resource + private RedisTemplate<String, Object> redisTemplate; + @Resource + private TokenService tokenService; + @Override public List<AppUserVO> listAll(AppUserQuery query) { return this.baseMapper.listAll(query); } + + @Override + public Boolean phoneCode(String phone) { + // 生成随机 6位数字 验证码 + String phoneCode = RandomUtil.randomNumbers(6); + // todo 手机验证码暂时 123456 + phoneCode = "123456"; + // 判断redis中是否存在手机验证码 + Object phoneCodeRedis = redisTemplate.opsForValue().get(RedisConstants.PHONE_CODE + phone); + if (phoneCodeRedis == null) { + // 将手机验证码 key: reg:用户输入的手机号码 value: 随机验证码:时间戳 + phoneCodeRedis = phoneCode; + } else { + // redis有验证码,获取redis中value的时间戳,判断是否过期 + long oldTime = Long.parseLong(String.valueOf(phoneCodeRedis).split(":")[1]); + // 没有超过1分钟的重发时间 + if (System.currentTimeMillis() - oldTime < (long) Constants.SIXTY * Constants.ONE_THOUSAND) { + throw new GlobalException("操作频繁,稍后重试!!!"); + } else { + phoneCode = String.valueOf(phoneCodeRedis).split(":")[0]; + } + } + /* + * 保存信息到redis + * key为 --> phone_code:手机号码 (phone_code表示该业务为 验证码登录) + * value为 --> 随机验证码:时间戳 (时间戳用于计算是否超过1分钟的重发时间) + */ + redisTemplate.opsForValue().set(RedisConstants.PHONE_CODE + phone, phoneCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES); + String sendMessage = "验证码发送成功,您的验证码为:" + phoneCode + ",该验证码三分钟内有效,请及时完成登陆"; + // todo 发送此消息 + System.out.println(sendMessage); + return true; + } + + @Override + public Boolean isVip() { + TUser user = lambdaQuery().eq(TUser::getId, tokenService.getLoginUserStudy().getUserid()) + .eq(TUser::getDisabled, 0).one(); + // 是否为vip 逻辑 + if (null == user) { + return false; + } + // vip过期时间,字段为空也表示 当前用户不是vip + Date vipEndTime = user.getVipEndTime(); + return null != vipEndTime && System.currentTimeMillis() <= vipEndTime.getTime(); + } + } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java index f6019c3..0abadbb 100644 --- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java @@ -1,13 +1,14 @@ package com.ruoyi.study.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.study.domain.TGame; +import com.ruoyi.common.core.constant.Constants; import com.ruoyi.study.domain.TUserStudy; -import com.ruoyi.study.mapper.TGameMapper; import com.ruoyi.study.mapper.TUserStudyMapper; -import com.ruoyi.study.service.ITGameService; import com.ruoyi.study.service.ITUserStudyService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; /** * <p> @@ -20,4 +21,37 @@ @Service public class TUserStudyServiceImpl extends ServiceImpl<TUserStudyMapper, TUserStudy> implements ITUserStudyService { + @Override + public TUserStudy studySchedule(String userId, Integer week, Integer day) { + return lambdaQuery().eq(TUserStudy::getUserId, userId) + .eq(TUserStudy::getDay, day).eq(TUserStudy::getWeek, week) + .eq(TUserStudy::getDisabled, 0).one(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void resettingStudyRecord(String time) { + List<TUserStudy> list = lambdaQuery().eq(TUserStudy::getDisabled, 0).list(); + switch (time) { + case Constants.DAY: + list.forEach(data -> data.setTodayStudy(0)); + break; + case Constants.WEEK: + list.forEach(data -> data.setWeekStudy(0)); + break; + case Constants.MONTH: + list.forEach(data -> data.setMonthStudy(0)); + break; + default: + } + int number = 0; + boolean update = this.updateBatchById(list); + while (!update) { + if (number >= 3) { + break; + } + update = this.updateBatchById(list); + number++; + } + } } diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/task/StudyRecordTimedTask.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/task/StudyRecordTimedTask.java new file mode 100644 index 0000000..9d01d99 --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/task/StudyRecordTimedTask.java @@ -0,0 +1,44 @@ +package com.ruoyi.study.task; + +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.study.service.ITUserStudyService; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @author HJL + * @version 1.0 + * @since 2024-05-20 17:21 + */ +@Component +public class StudyRecordTimedTask { + @Resource + private ITUserStudyService userStudyService; + + /** + * 每日凌晨执行,重置学习记录中 今日学习时长 + */ + @Scheduled(cron = "0 0 0 * * ?") + public void resettingTodayStudyRecord() { + userStudyService.resettingStudyRecord(Constants.DAY); + } + + /** + * 每周周一执行,重置学习记录中 本周学习时长 + */ + @Scheduled(cron = "0 0 0 * * 1") + public void resettingWeekStudyRecord() { + userStudyService.resettingStudyRecord(Constants.WEEK); + } + + /** + * 每月一号执行,重置学习记录中 本月学习时长 + */ + @Scheduled(cron = "0 0 0 1 * *") + public void resettingMonthStudyRecord() { + userStudyService.resettingStudyRecord(Constants.MONTH); + } + +} diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/utils/SendMsgUtils.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/utils/SendMsgUtils.java new file mode 100644 index 0000000..407276e --- /dev/null +++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/utils/SendMsgUtils.java @@ -0,0 +1,42 @@ +package com.ruoyi.study.utils; + +/** + * 发送手机验证码工具类 + * + * @author HJL + * @version 1.0 + * @since 2024-05-17 14:31 + */ +public class SendMsgUtils { + + public static final String UID = "EUhello"; + public static final String KEY = "6D05DE2FF1294C81CEF25E0862448D11"; + + public static String sendMessage(String smsMob, String smsText) { +// PostMethod post = new PostMethod("https://utf8api.smschinese.cn/"); +// try { +// HttpClient client = new HttpClient(); +// post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码 +// NameValuePair[] data = {new NameValuePair("Uid", UID), new NameValuePair("Key", KEY), new NameValuePair("smsMob", smsMob), new NameValuePair("smsText", smsText)}; +// post.setRequestBody(data); +// client.executeMethod(post); +// Header[] headers = post.getResponseHeaders(); +// int statusCode = post.getStatusCode(); +// System.out.println("statusCode:" + statusCode); //HTTP状态码 +// +// for (Header h : headers) { +// System.out.println(h.toString()); +// } +// String result = new String(post.getResponseBodyAsString().getBytes("utf-8")); +// System.out.println(result); //打印返回消息状态 +// return result; +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// // 关流 +// post.releaseConnection(); +// } + return null; + } + +} diff --git a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml index c6d7f75..c5d91f4 100644 --- a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml +++ b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml @@ -2,6 +2,16 @@ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.study.mapper.TIntegralRecordMapper"> - - + <select id="integralDetail" resultType="com.ruoyi.study.domain.TIntegralRecord"> + SELECT * + FROM t_integral_record + <where> + <if test="time != null and time != ''"> + DATE_FORMAT(createTime, '%Y-%m') = #{time} + </if> + <if test="userId != null and userId != ''"> + and userId = #{userId} + </if> + </where> + </select> </mapper> diff --git a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml index c58b5c0..8767c40 100644 --- a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml +++ b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml @@ -19,4 +19,21 @@ id, week, day, listen, type, integral, sort, title </sql> + <select id="weekList" resultType="com.ruoyi.study.dto.StudyWeekDTO"> + SELECT COALESCE(SUM(sa.integral), 0) + COALESCE(SUM(si.integral), 0) + COALESCE(SUM(st.integral), 0) + + COALESCE(SUM(sk.integral), 0) + COALESCE(SUM(sp.integral), 0) + COALESCE(SUM(sl.integral), 0) + + COALESCE(SUM(g.integral), 0) AS totalIntegral, + s.week, + s.title, + s.quarter,s.id + FROM t_study s + LEFT JOIN t_study_answer sa ON s.id = sa.studyId + LEFT JOIN t_study_induction si ON s.id = si.studyId + LEFT JOIN t_study_listen st ON s.id = st.studyId + LEFT JOIN t_study_look sk ON s.id = sk.studyId + LEFT JOIN t_study_pair sp ON s.id = sp.studyId + LEFT JOIN t_story_listen sl ON s.id = sl.studyId + LEFT JOIN t_game g ON s.id = g.studyId + GROUP BY s.week, s.title, s.quarter,s.id; + </select> </mapper> -- Gitblit v1.7.1