Commit 4f03635fcd71ed032ecb5e41ccfd5838223b1140
1 parent
a04a3a27
签到:签到后增加用户积分、经验
Showing
14 changed files
with
112 additions
and
67 deletions
sql/mysql/ruoyi-vue-pro.sql
| ... | ... | @@ -788,7 +788,7 @@ CREATE TABLE `member_level_record` ( |
| 788 | 788 | `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号', |
| 789 | 789 | `level_id` bigint NOT NULL DEFAULT 0 COMMENT '等级编号', |
| 790 | 790 | `level` int NOT NULL DEFAULT 0 COMMENT '会员等级', |
| 791 | - `discount_percent` tinyint NOT NULL DEFAULT 100 COMMENT '享受折扣', | |
| 791 | + `discount_percent` int NOT NULL DEFAULT 100 COMMENT '享受折扣', | |
| 792 | 792 | `experience` int NOT NULL DEFAULT 0 COMMENT '升级经验', |
| 793 | 793 | `user_experience` int NOT NULL DEFAULT 0 COMMENT '会员此时的经验', |
| 794 | 794 | `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备注', |
| ... | ... | @@ -888,7 +888,8 @@ DROP TABLE IF EXISTS `member_sign_in_config`; |
| 888 | 888 | CREATE TABLE `member_sign_in_config` ( |
| 889 | 889 | `id` int NOT NULL AUTO_INCREMENT COMMENT '编号', |
| 890 | 890 | `day` int NOT NULL COMMENT '第几天', |
| 891 | - `point` int NOT NULL COMMENT '奖励积分', | |
| 891 | + `point` int NOT NULL DEFAULT 0 COMMENT '奖励积分', | |
| 892 | + `experience` int NOT NULL DEFAULT 0 COMMENT '奖励经验', | |
| 892 | 893 | `status` tinyint NOT NULL COMMENT '状态', |
| 893 | 894 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', |
| 894 | 895 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| ... | ... | @@ -903,18 +904,18 @@ CREATE TABLE `member_sign_in_config` ( |
| 903 | 904 | -- Records of member_sign_in_config |
| 904 | 905 | -- ---------------------------- |
| 905 | 906 | BEGIN; |
| 906 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 1, 10, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 907 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 2, 20, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 908 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 7, 1001, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 909 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 6, 12121, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 910 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 2, 12, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 911 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 10, 0, '1', '2023-08-20 19:20:42', '1', '2023-08-20 19:20:56', b'0', 1); | |
| 912 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 7, 22, 0, '1', '2023-08-20 19:20:48', '1', '2023-08-20 19:20:48', b'0', 1); | |
| 913 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 2, 3, 0, '1', '2023-08-21 20:22:44', '1', '2023-08-21 20:22:44', b'0', 1); | |
| 914 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 3, 4, 0, '1', '2023-08-21 20:22:48', '1', '2023-08-21 20:22:48', b'0', 1); | |
| 915 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 4, 5, 0, '1', '2023-08-21 20:22:51', '1', '2023-08-21 20:22:51', b'0', 1); | |
| 916 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 5, 6, 0, '1', '2023-08-21 20:22:56', '1', '2023-08-21 20:22:56', b'0', 1); | |
| 917 | -INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 6, 7, 0, '1', '2023-08-21 20:22:59', '1', '2023-08-21 20:22:59', b'0', 1); | |
| 907 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 1, 10, 10, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 908 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, 2, 20, 20, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 909 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, 7, 1001, 1001, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 910 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, 6, 12121, 12121, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 911 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 3, 12, 12, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); | |
| 912 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 10, 10, 0, '1', '2023-08-20 19:20:42', '1', '2023-08-20 19:20:56', b'0', 1); | |
| 913 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 7, 22, 22, 0, '1', '2023-08-20 19:20:48', '1', '2023-08-20 19:20:48', b'0', 1); | |
| 914 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 2, 3, 3, 0, '1', '2023-08-21 20:22:44', '1', '2023-08-21 20:22:44', b'0', 1); | |
| 915 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 3, 4, 4, 0, '1', '2023-08-21 20:22:48', '1', '2023-08-21 20:22:48', b'0', 1); | |
| 916 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 4, 5, 5, 0, '1', '2023-08-21 20:22:51', '1', '2023-08-21 20:22:51', b'0', 1); | |
| 917 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 5, 6, 6, 0, '1', '2023-08-21 20:22:56', '1', '2023-08-21 20:22:56', b'0', 1); | |
| 918 | +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `experience`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 6, 7, 7, 0, '1', '2023-08-21 20:22:59', '1', '2023-08-21 20:22:59', b'0', 1); | |
| 918 | 919 | COMMIT; |
| 919 | 920 | |
| 920 | 921 | -- ---------------------------- |
| ... | ... | @@ -925,7 +926,8 @@ CREATE TABLE `member_sign_in_record` ( |
| 925 | 926 | `id` bigint NOT NULL AUTO_INCREMENT COMMENT '签到自增id', |
| 926 | 927 | `user_id` int NULL DEFAULT NULL COMMENT '签到用户', |
| 927 | 928 | `day` int NULL DEFAULT NULL COMMENT '第几天签到', |
| 928 | - `point` int NULL DEFAULT NULL COMMENT '签到的分数', | |
| 929 | + `point` int NOT NULL DEFAULT 0 COMMENT '签到的积分', | |
| 930 | + `experience` int NOT NULL DEFAULT 0 COMMENT '签到的经验', | |
| 929 | 931 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', |
| 930 | 932 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| 931 | 933 | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', |
| ... | ... | @@ -935,6 +937,8 @@ CREATE TABLE `member_sign_in_record` ( |
| 935 | 937 | PRIMARY KEY (`id`) USING BTREE |
| 936 | 938 | ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '签到记录'; |
| 937 | 939 | |
| 940 | +CREATE INDEX user_id_index ON member_sign_in_record (user_id); | |
| 941 | + | |
| 938 | 942 | -- ---------------------------- |
| 939 | 943 | -- Records of member_sign_in_record |
| 940 | 944 | -- ---------------------------- | ... | ... |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
| ... | ... | @@ -38,6 +38,7 @@ public interface ErrorCodeConstants { |
| 38 | 38 | //========== 签到配置 1-004-009-000 ========== |
| 39 | 39 | ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在"); |
| 40 | 40 | ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在"); |
| 41 | + ErrorCode SIGN_IN_CONFIG_AWARD_EMPTY = new ErrorCode(1_004_009_002, "签到奖励积分和经验不能同时为空"); | |
| 41 | 42 | |
| 42 | 43 | //========== 签到配置 1-004-010-000 ========== |
| 43 | 44 | ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000,"今日已签到,请勿重复签到"); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/config/MemberSignInConfigBaseVO.java
| ... | ... | @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; |
| 6 | 6 | import lombok.Data; |
| 7 | 7 | |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | +import javax.validation.constraints.PositiveOrZero; | |
| 9 | 10 | |
| 10 | 11 | /** |
| 11 | 12 | * 签到规则 Base VO,提供给添加、修改、详细的子 VO 使用 |
| ... | ... | @@ -20,8 +21,14 @@ public class MemberSignInConfigBaseVO { |
| 20 | 21 | |
| 21 | 22 | @Schema(description = "奖励积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| 22 | 23 | @NotNull(message = "奖励积分不能为空") |
| 24 | + @PositiveOrZero(message = "奖励积分不能小于 0") | |
| 23 | 25 | private Integer point; |
| 24 | 26 | |
| 27 | + @Schema(description = "奖励经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 28 | + @NotNull(message = "奖励经验不能为空") | |
| 29 | + @PositiveOrZero(message = "奖励经验不能小于 0") | |
| 30 | + private Integer experience; | |
| 31 | + | |
| 25 | 32 | @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 26 | 33 | @NotNull(message = "状态不能为空") |
| 27 | 34 | @InEnum(CommonStatusEnum.class) | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/vo/record/MemberSignInRecordRespVO.java
| ... | ... | @@ -21,7 +21,7 @@ public class MemberSignInRecordRespVO { |
| 21 | 21 | @Schema(description = "第几天签到", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 22 | 22 | private Integer day; |
| 23 | 23 | |
| 24 | - @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 24 | + @Schema(description = "签到的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 25 | 25 | private Integer point; |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java
| 1 | 1 | package cn.iocoder.yudao.module.member.controller.app.signin; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | -import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; | |
| 5 | -import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | |
| 6 | 4 | import cn.iocoder.yudao.module.member.service.signin.MemberSignInRecordService; |
| 7 | 5 | import io.swagger.v3.oas.annotations.Operation; |
| 8 | 6 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 9 | 7 | import org.springframework.web.bind.annotation.GetMapping; |
| 10 | -import org.springframework.web.bind.annotation.PostMapping; | |
| 11 | 8 | import org.springframework.web.bind.annotation.RequestMapping; |
| 12 | 9 | import org.springframework.web.bind.annotation.RestController; |
| 13 | 10 | |
| ... | ... | @@ -29,17 +26,8 @@ public class AppMemberSignInController { |
| 29 | 26 | // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 getSignInRecordSummary 里哈。 |
| 30 | 27 | @Operation(summary = "个人签到信息") |
| 31 | 28 | @GetMapping("/get-summary") |
| 32 | - public CommonResult getUserSummary(){ | |
| 29 | + public CommonResult getUserSummary() { | |
| 33 | 30 | return success(signInRecordService.getSignInRecordSummary(getLoginUserId())); |
| 34 | 31 | } |
| 35 | 32 | |
| 36 | - // TODO @xiaqing:泛型: | |
| 37 | - // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 createSignInRecord 里哈。 | |
| 38 | - @Operation(summary = "会员签到") | |
| 39 | - @PostMapping("/create") | |
| 40 | - public CommonResult create(){ | |
| 41 | - MemberSignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId()); | |
| 42 | - return success(MemberSignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO)); | |
| 43 | - } | |
| 44 | - | |
| 45 | 33 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java
| ... | ... | @@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; |
| 18 | 18 | import org.springframework.web.bind.annotation.RestController; |
| 19 | 19 | |
| 20 | 20 | import javax.annotation.Resource; |
| 21 | -import java.time.LocalDateTime; | |
| 22 | 21 | |
| 23 | 22 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 24 | 23 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| ... | ... | @@ -50,16 +49,12 @@ public class AppMemberSignInRecordController { |
| 50 | 49 | return success(respVO); |
| 51 | 50 | } |
| 52 | 51 | |
| 53 | - // TODO 芋艿:临时 mock => UserSignController.info | |
| 54 | 52 | @PostMapping("/create") |
| 55 | 53 | @Operation(summary = "签到") |
| 56 | 54 | @PreAuthenticated |
| 57 | 55 | public CommonResult<AppMemberSignInRecordRespVO> createSignInRecord() { |
| 58 | - AppMemberSignInRecordRespVO respVO = new AppMemberSignInRecordRespVO() | |
| 59 | - .setPoint(10) | |
| 60 | - .setDay(10) | |
| 61 | - .setCreateTime(LocalDateTime.now()); | |
| 62 | - return success(respVO); | |
| 56 | + MemberSignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId()); | |
| 57 | + return success(MemberSignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO)); | |
| 63 | 58 | } |
| 64 | 59 | |
| 65 | 60 | @GetMapping("/page") | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java
| ... | ... | @@ -12,9 +12,12 @@ public class AppMemberSignInRecordRespVO { |
| 12 | 12 | @Schema(description = "第几天签到", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 13 | 13 | private Integer day; |
| 14 | 14 | |
| 15 | - @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 15 | + @Schema(description = "签到的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 16 | 16 | private Integer point; |
| 17 | 17 | |
| 18 | + @Schema(description = "签到的经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 19 | + private Integer experience; | |
| 20 | + | |
| 18 | 21 | @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 19 | 22 | private LocalDateTime createTime; |
| 20 | 23 | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/record/AppMemberSignInRecordRespVO.java
| ... | ... | @@ -15,6 +15,9 @@ public class AppMemberSignInRecordRespVO { |
| 15 | 15 | @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| 16 | 16 | private Integer point; |
| 17 | 17 | |
| 18 | + @Schema(description = "签到的经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | |
| 19 | + private Integer experience; | |
| 20 | + | |
| 18 | 21 | @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 19 | 22 | private LocalDateTime createTime; |
| 20 | 23 | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInConfigDO.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/signin/MemberSignInRecordDO.java
| ... | ... | @@ -35,10 +35,12 @@ public class MemberSignInRecordDO extends BaseDO { |
| 35 | 35 | */ |
| 36 | 36 | private Integer day; |
| 37 | 37 | /** |
| 38 | - * 签到的分数 | |
| 38 | + * 签到的积分 | |
| 39 | 39 | */ |
| 40 | 40 | private Integer point; |
| 41 | - | |
| 42 | - // TODO 疯狂:签到的经验 | |
| 41 | + /** | |
| 42 | + * 签到的经验 | |
| 43 | + */ | |
| 44 | + private Integer experience; | |
| 43 | 45 | |
| 44 | 46 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java
| ... | ... | @@ -239,7 +239,8 @@ public class MemberLevelServiceImpl implements MemberLevelService { |
| 239 | 239 | |
| 240 | 240 | // 1. 创建经验记录 |
| 241 | 241 | MemberUserDO user = memberUserService.getUser(userId); |
| 242 | - int userExperience = NumberUtil.max(user.getExperience() + experience, 0); // 防止扣出负数 | |
| 242 | + Integer userExperience = ObjUtil.defaultIfNull(user.getExperience(), 0); | |
| 243 | + userExperience = NumberUtil.max(userExperience + experience, 0); // 防止扣出负数 | |
| 243 | 244 | MemberLevelRecordDO levelRecord = new MemberLevelRecordDO() |
| 244 | 245 | .setUserId(user.getId()) |
| 245 | 246 | .setExperience(experience) | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java
| ... | ... | @@ -66,6 +66,9 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { |
| 66 | 66 | @Override |
| 67 | 67 | @Transactional(rollbackFor = Exception.class) |
| 68 | 68 | public void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId) { |
| 69 | + if (point == 0) { | |
| 70 | + return; | |
| 71 | + } | |
| 69 | 72 | // 1. 校验用户积分余额 |
| 70 | 73 | MemberUserDO user = memberUserService.getUser(userId); |
| 71 | 74 | Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0); | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java
| ... | ... | @@ -11,10 +11,10 @@ import org.springframework.validation.annotation.Validated; |
| 11 | 11 | import javax.annotation.Resource; |
| 12 | 12 | import java.util.Comparator; |
| 13 | 13 | import java.util.List; |
| 14 | +import java.util.Objects; | |
| 14 | 15 | |
| 15 | 16 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 16 | -import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_EXISTS; | |
| 17 | -import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_NOT_EXISTS; | |
| 17 | +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; | |
| 18 | 18 | |
| 19 | 19 | /** |
| 20 | 20 | * 签到规则 Service 实现类 |
| ... | ... | @@ -30,6 +30,8 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService |
| 30 | 30 | |
| 31 | 31 | @Override |
| 32 | 32 | public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) { |
| 33 | + // 校验奖励积分、奖励经验 | |
| 34 | + validatePointAndExperience(createReqVO.getPoint(), createReqVO.getExperience()); | |
| 33 | 35 | // 判断是否重复插入签到天数 |
| 34 | 36 | validateSignInConfigDayDuplicate(createReqVO.getDay(), null); |
| 35 | 37 | |
| ... | ... | @@ -42,6 +44,8 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService |
| 42 | 44 | |
| 43 | 45 | @Override |
| 44 | 46 | public void updateSignInConfig(MemberSignInConfigUpdateReqVO updateReqVO) { |
| 47 | + // 校验奖励积分、奖励经验 | |
| 48 | + validatePointAndExperience(updateReqVO.getPoint(), updateReqVO.getExperience()); | |
| 45 | 49 | // 校验存在 |
| 46 | 50 | validateSignInConfigExists(updateReqVO.getId()); |
| 47 | 51 | // 判断是否重复插入签到天数 |
| ... | ... | @@ -70,7 +74,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService |
| 70 | 74 | * 校验 day 是否重复 |
| 71 | 75 | * |
| 72 | 76 | * @param day 天 |
| 73 | - * @param id 编号,只有更新的时候会传递 | |
| 77 | + * @param id 编号,只有更新的时候会传递 | |
| 74 | 78 | */ |
| 75 | 79 | private void validateSignInConfigDayDuplicate(Integer day, Long id) { |
| 76 | 80 | MemberSignInConfigDO config = memberSignInConfigMapper.selectByDay(day); |
| ... | ... | @@ -84,13 +88,20 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService |
| 84 | 88 | } |
| 85 | 89 | } |
| 86 | 90 | |
| 91 | + private void validatePointAndExperience(Integer point, Integer experience) { | |
| 92 | + // 奖励积分、经验 至少要配置一个,否则没有意义 | |
| 93 | + if (Objects.equals(point, 0) && Objects.equals(experience, 0)) { | |
| 94 | + throw exception(SIGN_IN_CONFIG_AWARD_EMPTY); | |
| 95 | + } | |
| 96 | + } | |
| 97 | + | |
| 87 | 98 | @Override |
| 88 | 99 | public MemberSignInConfigDO getSignInConfig(Long id) { |
| 89 | 100 | return memberSignInConfigMapper.selectById(id); |
| 90 | 101 | } |
| 91 | 102 | |
| 92 | 103 | @Override |
| 93 | - public List <MemberSignInConfigDO> getSignInConfigList() { | |
| 104 | + public List<MemberSignInConfigDO> getSignInConfigList() { | |
| 94 | 105 | List<MemberSignInConfigDO> list = memberSignInConfigMapper.selectList(); |
| 95 | 106 | list.sort(Comparator.comparing(MemberSignInConfigDO::getDay)); |
| 96 | 107 | return list; | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.signin; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 6 | 7 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 7 | 8 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 8 | 9 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| ... | ... | @@ -13,8 +14,13 @@ import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO |
| 13 | 14 | import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInConfigMapper; |
| 14 | 15 | import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper; |
| 15 | 16 | import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants; |
| 17 | +import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | |
| 18 | +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | |
| 19 | +import cn.iocoder.yudao.module.member.service.level.MemberLevelService; | |
| 20 | +import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; | |
| 16 | 21 | import org.apache.commons.lang3.StringUtils; |
| 17 | 22 | import org.springframework.stereotype.Service; |
| 23 | +import org.springframework.transaction.annotation.Transactional; | |
| 18 | 24 | import org.springframework.util.CollectionUtils; |
| 19 | 25 | import org.springframework.validation.annotation.Validated; |
| 20 | 26 | |
| ... | ... | @@ -40,20 +46,24 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService |
| 40 | 46 | private MemberSignInRecordMapper signInRecordMapper; |
| 41 | 47 | @Resource |
| 42 | 48 | private MemberSignInConfigMapper signInConfigMapper; |
| 49 | + @Resource | |
| 50 | + private MemberPointRecordService pointRecordService; | |
| 51 | + @Resource | |
| 52 | + private MemberLevelService memberLevelService; | |
| 43 | 53 | |
| 44 | 54 | @Resource |
| 45 | 55 | private MemberUserApi memberUserApi; |
| 46 | 56 | |
| 47 | 57 | @Override |
| 48 | 58 | public AppMemberSignInSummaryRespVO getSignInRecordSummary(Long userId) { |
| 49 | - AppMemberSignInSummaryRespVO vo = new AppMemberSignInSummaryRespVO(); | |
| 59 | + AppMemberSignInSummaryRespVO vo = new AppMemberSignInSummaryRespVO(); | |
| 50 | 60 | vo.setTotalDay(0); |
| 51 | 61 | vo.setContinuousDay(0); |
| 52 | 62 | vo.setTodaySignIn(false); |
| 53 | 63 | //获取用户签到的记录,按照天数倒序获取 |
| 54 | - List <MemberSignInRecordDO> signInRecordDOList = signInRecordMapper.selectListByUserId(userId); | |
| 64 | + List<MemberSignInRecordDO> signInRecordDOList = signInRecordMapper.selectListByUserId(userId); | |
| 55 | 65 | // TODO @xiaqing:if 空的时候,直接 return;这样括号少,逻辑更简洁; |
| 56 | - if(!CollectionUtils.isEmpty(signInRecordDOList)){ | |
| 66 | + if (!CollectionUtils.isEmpty(signInRecordDOList)) { | |
| 57 | 67 | //设置总签到天数 |
| 58 | 68 | vo.setTotalDay(signInRecordDOList.size()); // TODO @xiaqing:是不是不用读取 signInRecordDOList 所有的,而是 count下,然后另外再读取一条最后一条; |
| 59 | 69 | //判断当天是否有签到复用校验方法 |
| ... | ... | @@ -61,11 +71,11 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService |
| 61 | 71 | try { |
| 62 | 72 | validSignDay(signInRecordDOList.get(0)); |
| 63 | 73 | vo.setTodaySignIn(false); |
| 64 | - }catch (Exception e){ | |
| 74 | + } catch (Exception e) { | |
| 65 | 75 | vo.setTodaySignIn(true); |
| 66 | 76 | } |
| 67 | 77 | //如果当天签到了则说明连续签到天数有意义,否则直接用默认值0 |
| 68 | - if(vo.getTodaySignIn()){ | |
| 78 | + if (vo.getTodaySignIn()) { | |
| 69 | 79 | //下方计算连续签到从2天开始,此处直接设置一天连续签到 |
| 70 | 80 | vo.setContinuousDay(1); |
| 71 | 81 | //判断连续签到天数 |
| ... | ... | @@ -73,10 +83,10 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService |
| 73 | 83 | for (int i = 1; i < signInRecordDOList.size(); i++) { |
| 74 | 84 | //前一天减1等于当前天数则说明连续,继续循环 |
| 75 | 85 | LocalDate cur = signInRecordDOList.get(i).getCreateTime().toLocalDate(); |
| 76 | - LocalDate pre = signInRecordDOList.get(i-1).getCreateTime().toLocalDate(); | |
| 77 | - if(1==daysBetween(cur,pre)){ | |
| 78 | - vo.setContinuousDay(i+1); | |
| 79 | - }else{ | |
| 86 | + LocalDate pre = signInRecordDOList.get(i - 1).getCreateTime().toLocalDate(); | |
| 87 | + if (1 == daysBetween(cur, pre)) { | |
| 88 | + vo.setContinuousDay(i + 1); | |
| 89 | + } else { | |
| 80 | 90 | break; |
| 81 | 91 | } |
| 82 | 92 | } |
| ... | ... | @@ -87,16 +97,16 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService |
| 87 | 97 | return vo; |
| 88 | 98 | } |
| 89 | 99 | |
| 90 | - private long daysBetween(LocalDate date1,LocalDate date2){ | |
| 100 | + private long daysBetween(LocalDate date1, LocalDate date2) { | |
| 91 | 101 | return ChronoUnit.DAYS.between(date1, date2); |
| 92 | 102 | } |
| 93 | 103 | |
| 94 | 104 | @Override |
| 95 | - public PageResult <MemberSignInRecordDO> getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { | |
| 105 | + public PageResult<MemberSignInRecordDO> getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { | |
| 96 | 106 | // 根据用户昵称查询出用户ids |
| 97 | - Set <Long> userIds = null; | |
| 107 | + Set<Long> userIds = null; | |
| 98 | 108 | if (StringUtils.isNotBlank(pageReqVO.getNickname())) { |
| 99 | - List <MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); | |
| 109 | + List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); | |
| 100 | 110 | // 如果查询用户结果为空直接返回无需继续查询 |
| 101 | 111 | if (CollectionUtils.isEmpty(users)) { |
| 102 | 112 | return PageResult.empty(); |
| ... | ... | @@ -113,50 +123,63 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService |
| 113 | 123 | } |
| 114 | 124 | |
| 115 | 125 | @Override |
| 126 | + @Transactional(rollbackFor = Exception.class) | |
| 116 | 127 | public MemberSignInRecordDO createSignRecord(Long userId) { |
| 117 | 128 | // 获取当前用户签到的最大天数 |
| 118 | 129 | // TODO @xiaqing:db 操作,dou封装到 mapper 中; |
| 119 | 130 | // TODO @xiaqing:maxSignDay,是不是变量叫 lastRecord 会更容易理解哈; |
| 120 | - MemberSignInRecordDO maxSignDay = signInRecordMapper.selectOne(new LambdaQueryWrapperX <MemberSignInRecordDO>() | |
| 131 | + MemberSignInRecordDO maxSignDay = signInRecordMapper.selectOne(new LambdaQueryWrapperX<MemberSignInRecordDO>() | |
| 121 | 132 | .eq(MemberSignInRecordDO::getUserId, userId) |
| 122 | 133 | .orderByDesc(MemberSignInRecordDO::getDay) |
| 123 | 134 | .last("limit 1")); |
| 124 | 135 | // 判断是否重复签到 |
| 125 | 136 | validSignDay(maxSignDay); |
| 126 | 137 | |
| 127 | - // TODO @xiaqing:可以使用 // 进行注释 | |
| 128 | - /**1.查询出当前签到的天数**/ | |
| 138 | + // 1. 查询出当前签到的天数 | |
| 129 | 139 | MemberSignInRecordDO sign = new MemberSignInRecordDO().setUserId(userId); // TODO @xiaqing:应该使用 record 变量,会更合适 |
| 130 | 140 | sign.setDay(1); // 设置签到初始化天数 |
| 131 | - sign.setPoint(0); // 设置签到分数默认为 0 | |
| 141 | + sign.setPoint(0); // 设置签到积分默认为 0 | |
| 142 | + sign.setExperience(0); // 设置签到经验默认为 0 | |
| 132 | 143 | // 如果不为空则修改当前签到对应的天数 |
| 133 | 144 | // TODO @xiaqing:应该是要判断连续哈,就是昨天; |
| 134 | 145 | if (maxSignDay != null) { |
| 135 | 146 | sign.setDay(maxSignDay.getDay() + 1); |
| 136 | 147 | } |
| 137 | - /**2.获取签到对应的分数**/ | |
| 148 | + // 2. 获取签到对应的积分数 | |
| 138 | 149 | // 获取所有的签到规则,按照天数排序,只获取启用的 TODO @xiaqing:不要使用 signInConfigMapper 直接查询,而是要通过 SigninConfigService; |
| 139 | - List <MemberSignInConfigDO> configDOList = signInConfigMapper.selectList(new LambdaQueryWrapperX <MemberSignInConfigDO>() | |
| 150 | + List<MemberSignInConfigDO> configDOList = signInConfigMapper.selectList(new LambdaQueryWrapperX<MemberSignInConfigDO>() | |
| 140 | 151 | .eq(MemberSignInConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) |
| 141 | 152 | .orderByAsc(MemberSignInConfigDO::getDay)); |
| 142 | - // 如果签到的天数大于最大启用的规则天数,直接给最大签到的分数 | |
| 153 | + // 如果签到的天数大于最大启用的规则天数,直接给最大签到的积分数 | |
| 143 | 154 | // TODO @xiaqing:超过最大配置的天数,应该直接重置到第一天哈; |
| 144 | 155 | MemberSignInConfigDO lastConfig = configDOList.get(configDOList.size() - 1); |
| 145 | 156 | if (sign.getDay() > lastConfig.getDay()) { |
| 146 | 157 | sign.setPoint(lastConfig.getPoint()); |
| 158 | + sign.setExperience(lastConfig.getExperience()); | |
| 147 | 159 | } else { |
| 148 | 160 | configDOList.forEach(el -> { |
| 149 | - // 循环匹配对应天数,设置对应分数 | |
| 161 | + // 循环匹配对应天数,设置对应积分数 | |
| 150 | 162 | // TODO @xiaqing:使用 equals;另外,这种不应该去遍历比较,从可读性来说,应该 CollUtil.findOne() |
| 151 | 163 | if (el.getDay() == sign.getDay()) { |
| 152 | 164 | sign.setPoint(el.getPoint()); |
| 165 | + sign.setExperience(el.getExperience()); | |
| 153 | 166 | } |
| 154 | 167 | |
| 155 | 168 | }); |
| 156 | 169 | } |
| 157 | 170 | |
| 158 | - // 3. 插入当前签到获取的分数 | |
| 171 | + // 3. 插入签到记录 | |
| 159 | 172 | signInRecordMapper.insert(sign); |
| 173 | + | |
| 174 | + // 4. 增加积分 | |
| 175 | + if (!ObjectUtils.equalsAny(sign.getPoint(), null, 0)) { | |
| 176 | + pointRecordService.createPointRecord(userId, sign.getPoint(), MemberPointBizTypeEnum.SIGN, String.valueOf(sign.getId())); | |
| 177 | + } | |
| 178 | + // 5. 增加经验 | |
| 179 | + if (!ObjectUtils.equalsAny(sign.getPoint(), null, 0)) { | |
| 180 | + memberLevelService.addExperience(userId, sign.getExperience(), MemberExperienceBizTypeEnum.SIGN_IN, String.valueOf(sign.getId())); | |
| 181 | + } | |
| 182 | + | |
| 160 | 183 | return sign; |
| 161 | 184 | } |
| 162 | 185 | ... | ... |