mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 17:21:53 +08:00
Merge remote-tracking branch 'origin/feature/mall_product' into member_dev
This commit is contained in:
commit
2895ae3ddb
@ -1,98 +0,0 @@
|
||||
-- 会员表增加字段
|
||||
alter table member_user add column experience int not null default 0 comment '经验';
|
||||
alter table member_user add column level_id bigint comment '等级编号';
|
||||
|
||||
-- 增加3张表
|
||||
create table member_level
|
||||
(
|
||||
id bigint auto_increment comment '编号' primary key,
|
||||
name varchar(30) default '' not null comment '等级名称',
|
||||
experience int default 0 not null comment '升级经验',
|
||||
level int default 0 not null comment '等级',
|
||||
discount_percent tinyint default 100 not null comment '享受折扣',
|
||||
icon varchar(255) default '' not null comment '等级图标',
|
||||
background_url varchar(255) default '' not null comment '等级背景图',
|
||||
status tinyint default 0 not null comment '状态',
|
||||
creator varchar(64) default '' null comment '创建者',
|
||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
updater varchar(64) default '' null comment '更新者',
|
||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
deleted bit default b'0' not null comment '是否删除',
|
||||
tenant_id bigint default 0 not null comment '租户编号'
|
||||
)
|
||||
comment '会员等级';
|
||||
|
||||
create table member_level_record
|
||||
(
|
||||
id bigint auto_increment comment '编号' primary key,
|
||||
user_id bigint default 0 not null comment '用户编号',
|
||||
level_id bigint default 0 not null comment '等级编号',
|
||||
level int default 0 not null comment '会员等级',
|
||||
discount_percent tinyint default 100 not null comment '享受折扣',
|
||||
experience int default 0 not null comment '升级经验',
|
||||
user_experience int default 0 not null comment '会员此时的经验',
|
||||
remark varchar(255) default '' not null comment '备注',
|
||||
description varchar(255) default '' not null comment '描述',
|
||||
creator varchar(64) default '' null comment '创建者',
|
||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
updater varchar(64) default '' null comment '更新者',
|
||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
deleted bit default b'0' not null comment '是否删除',
|
||||
tenant_id bigint default 0 not null comment '租户编号'
|
||||
)
|
||||
comment '会员等级记录';
|
||||
|
||||
create index idx_user_id on member_level_record (user_id) comment '会员等级记录-用户编号';
|
||||
|
||||
create table member_experience_record
|
||||
(
|
||||
id bigint auto_increment comment '编号' primary key,
|
||||
user_id bigint default 0 not null comment '用户编号',
|
||||
biz_id varchar(64) default '' not null comment '业务编号',
|
||||
biz_type tinyint default 0 not null comment '业务类型',
|
||||
title varchar(30) default '' not null comment '标题',
|
||||
experience int default 0 not null comment '经验',
|
||||
total_experience int default 0 not null comment '变更后的经验',
|
||||
description varchar(512) default '' not null comment '描述',
|
||||
creator varchar(64) default '' null comment '创建者',
|
||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
updater varchar(64) default '' null comment '更新者',
|
||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
deleted bit default b'0' not null comment '是否删除',
|
||||
tenant_id bigint default 0 not null comment '租户编号'
|
||||
)
|
||||
comment '会员经验记录';
|
||||
|
||||
create index idx_user_id on member_experience_record (user_id) comment '会员经验记录-用户编号';
|
||||
create index idx_user_biz_type on member_experience_record (user_id, biz_type) comment '会员经验记录-用户业务类型';
|
||||
|
||||
-- 增加字典
|
||||
insert system_dict_type(name, type) values ('会员经验业务类型', 'member_experience_biz_type');
|
||||
insert system_dict_data(dict_type, label, value, sort) values ('member_experience_biz_type', '管理员调整', '0', 0);
|
||||
insert system_dict_data(dict_type, label, value, sort) values ('member_experience_biz_type', '邀新奖励', '1', 1);
|
||||
insert system_dict_data(dict_type, label, value, sort) values ('member_experience_biz_type', '下单奖励', '2', 2);
|
||||
insert system_dict_data(dict_type, label, value, sort) values ('member_experience_biz_type', '退单扣除', '3', 3);
|
||||
insert system_dict_data(dict_type, label, value, sort) values ('member_experience_biz_type', '签到奖励', '4', 4);
|
||||
insert system_dict_data(dict_type, label, value, sort) values ('member_experience_biz_type', '抽奖奖励', '5', 5);
|
||||
|
||||
-- 菜单 SQL
|
||||
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
|
||||
VALUES ('会员等级', '', 2, 3, 2262, 'level', '', 'member/level/index', 0, 'MemberLevel');
|
||||
|
||||
-- 按钮父菜单ID
|
||||
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||
SELECT @parentId := LAST_INSERT_ID();
|
||||
|
||||
-- 按钮 SQL
|
||||
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('会员等级查询', 'member:level:query', 3, 1, @parentId, '', '', '', 0);
|
||||
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('会员等级创建', 'member:level:create', 3, 2, @parentId, '', '', '', 0);
|
||||
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('会员等级更新', 'member:level:update', 3, 3, @parentId, '', '', '', 0);
|
||||
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('会员等级删除', 'member:level:delete', 3, 4, @parentId, '', '', '', 0);
|
||||
|
||||
-- 会员用户管理: 增加按钮权限
|
||||
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
|
||||
VALUES ('用户等级修改', 'member:user:update-level', 3, 5, 2309, '', '', '', 0);
|
@ -0,0 +1,157 @@
|
||||
package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.domain.AlipayTradePayModel;
|
||||
import com.alipay.api.request.AlipayTradePayRequest;
|
||||
import com.alipay.api.response.AlipayTradePayResponse;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.InjectMocks;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED;
|
||||
import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link AlipayBarPayClient} 单元测试
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
public class AlipayBarPayClientTest extends AbstractAlipayClientTest {
|
||||
|
||||
@InjectMocks
|
||||
private AlipayBarPayClient client = new AlipayBarPayClient(randomLongId(), config);
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
setClient(client);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝条码支付,非免密码支付下单成功")
|
||||
public void test_unified_order_success() throws AlipayApiException {
|
||||
String outTradeNo = randomString();
|
||||
String notifyUrl = randomURL();
|
||||
Integer price = randomInteger();
|
||||
String authCode = randomString();
|
||||
// 准备返回对象
|
||||
AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> o.setSubCode(""));
|
||||
|
||||
// mock
|
||||
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePayRequest>) request -> {
|
||||
assertInstanceOf(AlipayTradePayModel.class, request.getBizModel());
|
||||
assertEquals(notifyUrl, request.getNotifyUrl());
|
||||
AlipayTradePayModel model = (AlipayTradePayModel) request.getBizModel();
|
||||
assertEquals(outTradeNo, model.getOutTradeNo());
|
||||
assertEquals(String.valueOf(price / 100.0), model.getTotalAmount());
|
||||
assertEquals(authCode, model.getAuthCode());
|
||||
return true;
|
||||
}))).thenReturn(response);
|
||||
// 准备请求参数
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
|
||||
// 设置条码
|
||||
Map<String, String> extraParam = new HashMap<>();
|
||||
extraParam.put("auth_code", authCode);
|
||||
reqDTO.setChannelExtras(extraParam);
|
||||
// 下单请求
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
// 断言
|
||||
assertEquals(WAITING.getStatus(), resp.getStatus());
|
||||
assertEquals(PayOrderDisplayModeEnum.BAR_CODE.getMode(), resp.getDisplayMode());
|
||||
assertEquals(outTradeNo, resp.getOutTradeNo());
|
||||
assertEquals("", resp.getDisplayContent());
|
||||
assertSame(response, resp.getRawData());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝条码支付,免密码支付下单成功")
|
||||
public void test_unified_order_code_10000_success() throws AlipayApiException {
|
||||
String outTradeNo = randomString();
|
||||
String channelNo = randomString();
|
||||
String channelUserId = randomString();
|
||||
Date payTime = randomDate();
|
||||
// 准备返回对象
|
||||
AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> {
|
||||
o.setSubCode("");
|
||||
o.setCode("10000");
|
||||
o.setOutTradeNo(outTradeNo);
|
||||
o.setTradeNo(channelNo);
|
||||
o.setBuyerUserId(channelUserId);
|
||||
o.setGmtPayment(payTime);
|
||||
});
|
||||
// mock
|
||||
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePayRequest>) request -> true)))
|
||||
.thenReturn(response);
|
||||
// 准备请求参数
|
||||
String authCode = randomString();
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
|
||||
// 设置条码
|
||||
Map<String, String> extraParam = new HashMap<>();
|
||||
extraParam.put("auth_code", authCode);
|
||||
reqDTO.setChannelExtras(extraParam);
|
||||
// 下单请求
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
// 断言
|
||||
assertEquals(PayOrderStatusRespEnum.SUCCESS.getStatus(), resp.getStatus());
|
||||
assertEquals(outTradeNo, resp.getOutTradeNo());
|
||||
assertEquals(channelNo, resp.getChannelOrderNo());
|
||||
assertEquals(channelUserId, resp.getChannelUserId());
|
||||
assertEquals(LocalDateTimeUtil.of(payTime), resp.getSuccessTime());
|
||||
assertSame(response, resp.getRawData());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝条码支付,没有传条码")
|
||||
public void test_unified_order_empty_auth_code() {
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
// 断言
|
||||
assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝条码支付,渠道返回失败")
|
||||
public void test_unified_order_channel_failed() throws AlipayApiException {
|
||||
// 准备响应对象
|
||||
String subCode = randomString();
|
||||
String subMsg = randomString();
|
||||
AlipayTradePayResponse response = randomPojo(AlipayTradePayResponse.class, o -> {
|
||||
o.setSubCode(subCode);
|
||||
o.setSubMsg(subMsg);
|
||||
});
|
||||
// mock
|
||||
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradePayRequest>) request -> true)))
|
||||
.thenReturn(response);
|
||||
// 准备请求参数
|
||||
String authCode = randomString();
|
||||
String outTradeNo = randomString();
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger());
|
||||
// 设置条码
|
||||
Map<String, String> extraParam = new HashMap<>();
|
||||
extraParam.put("auth_code", authCode);
|
||||
reqDTO.setChannelExtras(extraParam);
|
||||
// 下单请求
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
// 断言
|
||||
assertEquals(CLOSED.getStatus(), resp.getStatus());
|
||||
assertEquals(subCode, resp.getChannelErrorCode());
|
||||
assertEquals(subMsg, resp.getChannelErrorMsg());
|
||||
assertSame(response, resp.getRawData());
|
||||
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link AlipayPcPayClient} 单元测试
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
public class AlipayPcPayClientTest extends AbstractAlipayClientTest {
|
||||
@ -41,15 +43,13 @@ public class AlipayPcPayClientTest extends AbstractAlipayClientTest {
|
||||
public void test_unified_order_url_display_mode_success() throws AlipayApiException {
|
||||
// 准备返回对象
|
||||
String notifyUrl = randomURL();
|
||||
Integer price = randomInteger();
|
||||
AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> {
|
||||
o.setSubCode("");
|
||||
});
|
||||
AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> o.setSubCode(""));
|
||||
// mock
|
||||
when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradePagePayRequest>) request -> true),
|
||||
eq(Method.GET.name()))).thenReturn(response);
|
||||
// 准备请求参数
|
||||
String outTradeNo = randomString();
|
||||
Integer price = randomInteger();
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
|
||||
// 设置 displayMode 为 null.
|
||||
reqDTO.setDisplayMode(null);
|
||||
@ -67,15 +67,13 @@ public class AlipayPcPayClientTest extends AbstractAlipayClientTest {
|
||||
public void test_unified_order_form_display_mode_success() throws AlipayApiException {
|
||||
// 准备返回对象
|
||||
String notifyUrl = randomURL();
|
||||
Integer price = randomInteger();
|
||||
AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> {
|
||||
o.setSubCode("");
|
||||
});
|
||||
AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> o.setSubCode(""));
|
||||
// mock
|
||||
when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher<AlipayTradePagePayRequest>) request -> true),
|
||||
eq(Method.POST.name()))).thenReturn(response);
|
||||
// 准备请求参数
|
||||
String outTradeNo = randomString();
|
||||
Integer price = randomInteger();
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price);
|
||||
reqDTO.setDisplayMode(PayOrderDisplayModeEnum.FORM.getMode());
|
||||
|
||||
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.api.level;
|
||||
import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
|
||||
|
||||
/**
|
||||
* 会员等级 API接口
|
||||
* 会员等级 API 接口
|
||||
*
|
||||
* @author owen
|
||||
*/
|
||||
@ -17,5 +17,6 @@ public interface MemberLevelApi {
|
||||
* @param bizType 业务类型 {@link MemberExperienceBizTypeEnum}
|
||||
* @param bizId 业务编号
|
||||
*/
|
||||
void plusExperience(Long userId, Integer experience, Integer bizType, String bizId);
|
||||
void addExperience(Long userId, Integer experience, Integer bizType, String bizId);
|
||||
|
||||
}
|
||||
|
@ -48,8 +48,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode LEVEL_EXPERIENCE_MAX = new ErrorCode(1004011004, "升级经验必须小于下一个等级[{}]设置的升级经验[{}]");
|
||||
ErrorCode LEVEL_HAS_USER = new ErrorCode(1004011005, "用户等级下存在用户,无法删除");
|
||||
|
||||
ErrorCode LEVEL_LOG_NOT_EXISTS = new ErrorCode(1004011100, "用户等级记录不存在");
|
||||
ErrorCode EXPERIENCE_LOG_NOT_EXISTS = new ErrorCode(1004011200, "用户经验记录不存在");
|
||||
ErrorCode EXPERIENCE_BIZ_NOT_SUPPORT = new ErrorCode(1004011201, "用户经验业务类型不支持");
|
||||
|
||||
//========== 用户分组 1004012000 ==========
|
||||
|
@ -11,18 +11,20 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MemberExperienceBizTypeEnum {
|
||||
|
||||
/**
|
||||
* 管理员调整、邀请新用户、下单、退单、签到、抽奖
|
||||
*/
|
||||
ADMIN(0, "管理员调整","管理员调整获得{}经验"),
|
||||
INVITE_REGISTER(1, "邀新奖励","邀请好友获得{}经验"),
|
||||
ORDER(2, "下单奖励", "下单获得{}经验"),
|
||||
REFUND(3, "退单扣除","退单获得{}经验"),
|
||||
SIGN_IN(4, "签到奖励","签到获得{}经验"),
|
||||
LOTTERY(5, "抽奖奖励","抽奖获得{}经验"),
|
||||
ADMIN(0, "管理员调整","管理员调整获得 {} 经验"),
|
||||
INVITE_REGISTER(1, "邀新奖励","邀请好友获得 {} 经验"),
|
||||
ORDER(2, "下单奖励", "下单获得 {} 经验"),
|
||||
REFUND(3, "退单扣除","退单获得 {} 经验"),
|
||||
SIGN_IN(4, "签到奖励","签到获得 {} 经验"),
|
||||
LOTTERY(5, "抽奖奖励","抽奖获得 {} 经验"),
|
||||
;
|
||||
|
||||
private final int value;
|
||||
private final int type;
|
||||
private final String title;
|
||||
private final String desc;
|
||||
private final String description;
|
||||
|
||||
}
|
||||
|
@ -24,12 +24,15 @@ public class MemberLevelApiImpl implements MemberLevelApi {
|
||||
@Resource
|
||||
private MemberLevelService memberLevelService;
|
||||
|
||||
public void plusExperience(Long userId, Integer experience, Integer bizType, String bizId) {
|
||||
MemberExperienceBizTypeEnum bizTypeEnum = EnumUtil.getBy(MemberExperienceBizTypeEnum.class, e -> Objects.equals(bizType, e.getValue()));
|
||||
@Override
|
||||
public void addExperience(Long userId, Integer experience, Integer bizType, String bizId) {
|
||||
// TODO @疯狂:可以在 MemberExperienceBizTypeEnum 增加一个方法,获得哈。
|
||||
MemberExperienceBizTypeEnum bizTypeEnum = EnumUtil.getBy(MemberExperienceBizTypeEnum.class,
|
||||
e -> Objects.equals(bizType, e.getType()));
|
||||
if (bizTypeEnum == null) {
|
||||
throw exception(EXPERIENCE_BIZ_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
memberLevelService.addExperience(userId, experience, bizTypeEnum, bizId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class MemberExperienceRecordController {
|
||||
@Operation(summary = "获得会员经验记录")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('member:experience-record:query')")
|
||||
public CommonResult<MemberExperienceRecordRespVO> getExperienceLog(@RequestParam("id") Long id) {
|
||||
public CommonResult<MemberExperienceRecordRespVO> getExperienceRecord(@RequestParam("id") Long id) {
|
||||
MemberExperienceRecordDO experienceLog = experienceLogService.getExperienceRecord(id);
|
||||
return success(MemberExperienceRecordConvert.INSTANCE.convert(experienceLog));
|
||||
}
|
||||
@ -43,7 +43,8 @@ public class MemberExperienceRecordController {
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得会员经验记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('member:experience-record:query')")
|
||||
public CommonResult<PageResult<MemberExperienceRecordRespVO>> getExperienceLogPage(@Valid MemberExperienceRecordPageReqVO pageVO) {
|
||||
public CommonResult<PageResult<MemberExperienceRecordRespVO>> getExperienceRecordPage(
|
||||
@Valid MemberExperienceRecordPageReqVO pageVO) {
|
||||
PageResult<MemberExperienceRecordDO> pageResult = experienceLogService.getExperienceRecordPage(pageVO);
|
||||
return success(MemberExperienceRecordConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class MemberLevelRecordController {
|
||||
@Operation(summary = "获得会员等级记录")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('member:level-record:query')")
|
||||
public CommonResult<MemberLevelRecordRespVO> getLevelLog(@RequestParam("id") Long id) {
|
||||
public CommonResult<MemberLevelRecordRespVO> getLevelRecord(@RequestParam("id") Long id) {
|
||||
MemberLevelRecordDO levelLog = levelLogService.getLevelRecord(id);
|
||||
return success(MemberLevelRecordConvert.INSTANCE.convert(levelLog));
|
||||
}
|
||||
@ -43,8 +43,10 @@ public class MemberLevelRecordController {
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得会员等级记录分页")
|
||||
@PreAuthorize("@ss.hasPermission('member:level-record:query')")
|
||||
public CommonResult<PageResult<MemberLevelRecordRespVO>> getLevelLogPage(@Valid MemberLevelRecordPageReqVO pageVO) {
|
||||
public CommonResult<PageResult<MemberLevelRecordRespVO>> getLevelRecordPage(
|
||||
@Valid MemberLevelRecordPageReqVO pageVO) {
|
||||
PageResult<MemberLevelRecordDO> pageResult = levelLogService.getLevelRecordPage(pageVO);
|
||||
return success(MemberLevelRecordConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
@Schema(description = "管理后台 - 会员等级分页 Request VO")
|
||||
@Schema(description = "管理后台 - 会员等级列表筛选 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class MemberLevelListReqVO {
|
||||
|
@ -25,10 +25,14 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Tag(name = "管理后台 - 会员用户")
|
||||
@RestController
|
||||
@ -79,26 +83,19 @@ public class MemberUserController {
|
||||
return success(PageResult.empty());
|
||||
}
|
||||
|
||||
Set<Long> groupIds = new HashSet<>(pageResult.getList().size());
|
||||
|
||||
// 处理用户标签返显
|
||||
Set<Long> tagIds = pageResult.getList().stream()
|
||||
.peek(m -> {
|
||||
if (m.getGroupId() != null) {
|
||||
groupIds.add(m.getGroupId());
|
||||
}
|
||||
})
|
||||
.map(MemberUserDO::getTagIds)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toSet());
|
||||
List<MemberTagDO> tags = memberTagService.getTagList(tagIds);
|
||||
|
||||
// 处理用户级别返显
|
||||
List<MemberLevelDO> levels = memberLevelService.getEnableLevelList();
|
||||
List<MemberLevelDO> levels = memberLevelService.getLevelList(
|
||||
convertSet(pageResult.getList(), MemberUserDO::getLevelId));
|
||||
// 处理用户分组返显
|
||||
List<MemberGroupDO> groups = memberGroupService.getGroupList(groupIds);
|
||||
|
||||
List<MemberGroupDO> groups = memberGroupService.getGroupList(
|
||||
convertSet(pageResult.getList(), MemberUserDO::getGroupId));
|
||||
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels, groups));
|
||||
}
|
||||
|
||||
|
@ -42,12 +42,10 @@ public interface MemberUserConvert {
|
||||
List<MemberLevelDO> levels,
|
||||
List<MemberGroupDO> groups) {
|
||||
PageResult<MemberUserRespVO> result = convertPage(pageResult);
|
||||
|
||||
// 处理关联数据
|
||||
Map<Long, String> tagMap = convertMap(tags, MemberTagDO::getId, MemberTagDO::getName);
|
||||
Map<Long, String> levelMap = convertMap(levels, MemberLevelDO::getId, MemberLevelDO::getName);
|
||||
Map<Long, String> groupMap = convertMap(groups, MemberGroupDO::getId, MemberGroupDO::getName);
|
||||
|
||||
// 填充关联数据
|
||||
for (MemberUserRespVO vo : result.getList()) {
|
||||
vo.setTagNames(convertList(vo.getTagIds(), tagMap::get));
|
||||
@ -56,4 +54,5 @@ public interface MemberUserConvert {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ public class MemberGroupServiceImpl implements MemberGroupService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @疯狂:不要直接调用 memberUserMapper,需要对方 service 提供方法
|
||||
void validateGroupHasUser(Long id) {
|
||||
Long count = memberUserMapper.selectCountByGroupId(id);
|
||||
if (count > 0) {
|
||||
|
@ -26,7 +26,6 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord
|
||||
@Resource
|
||||
private MemberExperienceRecordMapper experienceLogMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public MemberExperienceRecordDO getExperienceRecord(Long id) {
|
||||
return experienceLogMapper.selectById(id);
|
||||
@ -45,12 +44,11 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord
|
||||
@Override
|
||||
public void createExperienceRecord(Long userId, Integer experience, Integer totalExperience,
|
||||
MemberExperienceBizTypeEnum bizType, String bizId) {
|
||||
String description = StrUtil.format(bizType.getDesc(), experience);
|
||||
MemberExperienceRecordDO recordDO = MemberExperienceRecordConvert.INSTANCE.convert(userId,
|
||||
experience, totalExperience,
|
||||
bizId, bizType.getValue(), bizType.getTitle(),
|
||||
description);
|
||||
experienceLogMapper.insert(recordDO);
|
||||
String description = StrUtil.format(bizType.getDescription(), experience);
|
||||
MemberExperienceRecordDO record = MemberExperienceRecordConvert.INSTANCE.convert(
|
||||
userId, experience, totalExperience,
|
||||
bizId, bizType.getType(), bizType.getTitle(), description);
|
||||
experienceLogMapper.insert(record);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,9 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员等级记录 Service 接口
|
||||
*
|
||||
@ -22,14 +19,6 @@ public interface MemberLevelRecordService {
|
||||
*/
|
||||
MemberLevelRecordDO getLevelRecord(Long id);
|
||||
|
||||
/**
|
||||
* 获得会员等级记录列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 会员等级记录列表
|
||||
*/
|
||||
List<MemberLevelRecordDO> getLevelRecordList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得会员等级记录分页
|
||||
*
|
||||
@ -44,4 +33,5 @@ public interface MemberLevelRecordService {
|
||||
* @param levelRecord 会员等级记录
|
||||
*/
|
||||
void createLevelRecord(MemberLevelRecordDO levelRecord);
|
||||
|
||||
}
|
||||
|
@ -8,11 +8,6 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.LEVEL_LOG_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 会员等级记录 Service 实现类
|
||||
@ -26,22 +21,11 @@ public class MemberLevelRecordServiceImpl implements MemberLevelRecordService {
|
||||
@Resource
|
||||
private MemberLevelRecordMapper levelLogMapper;
|
||||
|
||||
private void validateLevelLogExists(Long id) {
|
||||
if (levelLogMapper.selectById(id) == null) {
|
||||
throw exception(LEVEL_LOG_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberLevelRecordDO getLevelRecord(Long id) {
|
||||
return levelLogMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MemberLevelRecordDO> getLevelRecordList(Collection<Long> ids) {
|
||||
return levelLogMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<MemberLevelRecordDO> getLevelRecordPage(MemberLevelRecordPageReqVO pageReqVO) {
|
||||
return levelLogMapper.selectPage(pageReqVO);
|
||||
|
@ -65,7 +65,6 @@ public interface MemberLevelService {
|
||||
*/
|
||||
List<MemberLevelDO> getLevelList(MemberLevelListReqVO listReqVO);
|
||||
|
||||
|
||||
/**
|
||||
* 获得指定状态的会员等级列表
|
||||
*
|
||||
@ -74,7 +73,6 @@ public interface MemberLevelService {
|
||||
*/
|
||||
List<MemberLevelDO> getLevelListByStatus(Integer status);
|
||||
|
||||
|
||||
/**
|
||||
* 获得开启状态的会员等级列表
|
||||
*
|
||||
@ -100,4 +98,5 @@ public interface MemberLevelService {
|
||||
* @param bizId 业务编号
|
||||
*/
|
||||
void addExperience(Long userId, Integer experience, MemberExperienceBizTypeEnum bizType, String bizId);
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@ -153,11 +154,12 @@ public class MemberLevelServiceImpl implements MemberLevelService {
|
||||
validateExperienceOutRange(list, id, level, experience);
|
||||
}
|
||||
|
||||
// TODO 有 Service 提供接口哈,不直接调用对方的 memberUserMapper
|
||||
@VisibleForTesting
|
||||
void validateLevelHasUser(Long id) {
|
||||
Long count = memberUserMapper.selectCountByLevelId(id);
|
||||
if (count > 0) {
|
||||
throw exception(GROUP_HAS_USER);
|
||||
throw exception(LEVEL_HAS_USER);
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +170,9 @@ public class MemberLevelServiceImpl implements MemberLevelService {
|
||||
|
||||
@Override
|
||||
public List<MemberLevelDO> getLevelList(Collection<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return levelMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@ -184,7 +189,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateUserLevel(MemberUserUpdateLevelReqVO updateReqVO) {
|
||||
MemberUserDO user = memberUserMapper.selectById(updateReqVO.getId());
|
||||
MemberUserDO user = memberUserService.getUser(updateReqVO.getId());
|
||||
if (user == null) {
|
||||
throw exception(USER_NOT_EXISTS);
|
||||
}
|
||||
@ -193,6 +198,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录等级变动
|
||||
MemberLevelRecordDO levelRecord = new MemberLevelRecordDO()
|
||||
.setUserId(user.getId())
|
||||
.setRemark(updateReqVO.getReason());
|
||||
@ -211,17 +217,16 @@ public class MemberLevelServiceImpl implements MemberLevelService {
|
||||
levelRecord.setUserExperience(memberLevel.getExperience());
|
||||
levelRecord.setDescription("管理员调整为:" + memberLevel.getName());
|
||||
}
|
||||
|
||||
// 记录等级变动
|
||||
memberLevelRecordService.createLevelRecord(levelRecord);
|
||||
|
||||
// 记录会员经验变动
|
||||
memberExperienceRecordService.createExperienceRecord(user.getId(),
|
||||
levelRecord.getExperience(), levelRecord.getUserExperience(),
|
||||
MemberExperienceBizTypeEnum.ADMIN, MemberExperienceBizTypeEnum.ADMIN.getValue() + "");
|
||||
MemberExperienceBizTypeEnum.ADMIN, String.valueOf(MemberExperienceBizTypeEnum.ADMIN.getType()));
|
||||
|
||||
// 更新会员表上的等级编号、经验值
|
||||
memberUserService.updateLevelIdAndExperience(user.getId(), updateReqVO.getLevelId(), levelRecord.getUserExperience());
|
||||
memberUserService.updateUserLevel(user.getId(), updateReqVO.getLevelId(),
|
||||
levelRecord.getUserExperience());
|
||||
|
||||
// 给会员发送等级变动消息
|
||||
notifyMemberLevelChange(user.getId(), memberLevel);
|
||||
@ -259,7 +264,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
|
||||
}
|
||||
|
||||
// 更新会员表上的等级编号、经验值
|
||||
memberUserService.updateLevelIdAndExperience(user.getId(), levelRecord.getLevelId(), userExperience);
|
||||
memberUserService.updateUserLevel(user.getId(), levelRecord.getLevelId(), userExperience);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,5 +133,6 @@ public interface MemberUserService {
|
||||
* @param levelId 用户等级
|
||||
* @param experience 用户经验
|
||||
*/
|
||||
void updateLevelIdAndExperience(Long id, Long levelId, Integer experience);
|
||||
void updateUserLevel(Long id, Long levelId, Integer experience);
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.member.service.user;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
@ -229,11 +230,9 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLevelIdAndExperience(Long id, Long levelId, Integer experience) {
|
||||
if (levelId == null) {
|
||||
public void updateUserLevel(Long id, Long levelId, Integer experience) {
|
||||
// 0 代表无等级:防止UpdateById时,会被过滤掉的问题
|
||||
levelId = 0L;
|
||||
}
|
||||
levelId = ObjectUtil.defaultIfNull(levelId, 0L);
|
||||
memberUserMapper.updateById(new MemberUserDO()
|
||||
.setId(id)
|
||||
.setLevelId(levelId).setExperience(experience)
|
||||
|
Loading…
Reference in New Issue
Block a user