feat: 新增邀请功能和消费记录
- 新增 Consume 和 Commission 表及相关服务 - 实现消费记录保存和提成计算 - 添加邀请码生成和收益展示功能 -重构 Invitation 相关代码,支持获取邀请列表和收益信息feature/comment
parent
79bfa1a981
commit
6ea08e3b1c
|
@ -4,19 +4,18 @@ import com.mcwl.common.core.domain.AjaxResult;
|
||||||
import com.mcwl.common.core.domain.entity.SysUser;
|
import com.mcwl.common.core.domain.entity.SysUser;
|
||||||
import com.mcwl.memberCenter.domain.MemberConsume;
|
import com.mcwl.memberCenter.domain.MemberConsume;
|
||||||
import com.mcwl.memberCenter.domain.Member;
|
import com.mcwl.memberCenter.domain.Member;
|
||||||
import com.mcwl.memberCenter.domain.MemberLevel;
|
|
||||||
import com.mcwl.memberCenter.service.MemberBenefitService;
|
import com.mcwl.memberCenter.service.MemberBenefitService;
|
||||||
import com.mcwl.memberCenter.service.MemberLevelService;
|
import com.mcwl.memberCenter.domain.dto.RechargePointsDto;
|
||||||
import com.mcwl.web.controller.memberCenter.pojo.dto.RechargePointsDto;
|
import com.mcwl.memberCenter.domain.dto.UserMemberDto;
|
||||||
import com.mcwl.web.controller.memberCenter.pojo.dto.UserMemberDto;
|
|
||||||
import com.mcwl.memberCenter.service.MemberConsumeService;
|
import com.mcwl.memberCenter.service.MemberConsumeService;
|
||||||
import com.mcwl.memberCenter.service.MemberService;
|
import com.mcwl.memberCenter.service.MemberService;
|
||||||
import com.mcwl.system.service.ISysUserService;
|
import com.mcwl.system.service.ISysUserService;
|
||||||
import com.mcwl.web.controller.memberCenter.pojo.vo.PointsVO;
|
import com.mcwl.memberCenter.domain.vo.PointsVO;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("member")
|
@RequestMapping("member")
|
||||||
|
@ -41,19 +40,19 @@ public class MemberController {
|
||||||
@PostMapping("createMember")
|
@PostMapping("createMember")
|
||||||
public AjaxResult createMemberCenter(@RequestBody UserMemberDto userMemberDto) {
|
public AjaxResult createMemberCenter(@RequestBody UserMemberDto userMemberDto) {
|
||||||
Long userId = userMemberDto.getUserId();
|
Long userId = userMemberDto.getUserId();
|
||||||
if (userId == null) {
|
if (!Optional.ofNullable(userId).isPresent()) {
|
||||||
return AjaxResult.warn("用户未登录");
|
return AjaxResult.warn("用户未登录");
|
||||||
}
|
}
|
||||||
Long memberLevelId = userMemberDto.getMemberLevelId();
|
Long memberLevelId = userMemberDto.getMemberLevelId();
|
||||||
if (memberLevelId == null) {
|
if (!Optional.ofNullable(memberLevelId).isPresent()) {
|
||||||
return AjaxResult.warn("会员等级未选择");
|
return AjaxResult.warn("会员等级未选择");
|
||||||
}
|
}
|
||||||
String paymentMethod = userMemberDto.getPaymentMethod();
|
String paymentMethod = userMemberDto.getPaymentMethod();
|
||||||
if (paymentMethod == null) {
|
if (!Optional.ofNullable(paymentMethod).isPresent()) {
|
||||||
return AjaxResult.warn("支付方式错误,请重新支付");
|
return AjaxResult.warn("支付方式错误,请重新支付");
|
||||||
}
|
}
|
||||||
Member member = memberService.createUserMember(userId, memberLevelId, paymentMethod);
|
Member member = memberService.createUserMember(userId, memberLevelId, paymentMethod);
|
||||||
if (member == null) {
|
if (!Optional.ofNullable(member).isPresent()) {
|
||||||
return AjaxResult.warn("创建会员失败");
|
return AjaxResult.warn("创建会员失败");
|
||||||
}
|
}
|
||||||
return AjaxResult.success(member);
|
return AjaxResult.success(member);
|
||||||
|
@ -67,17 +66,17 @@ public class MemberController {
|
||||||
*/
|
*/
|
||||||
@GetMapping("getPoints/{id}")
|
@GetMapping("getPoints/{id}")
|
||||||
public AjaxResult getPoints(@PathVariable("id") Long userId) {
|
public AjaxResult getPoints(@PathVariable("id") Long userId) {
|
||||||
if (userId == null) {
|
if (!Optional.ofNullable(userId).isPresent()) {
|
||||||
return AjaxResult.warn("用户未登录");
|
return AjaxResult.warn("用户未登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
SysUser sysUser = sysUserService.selectUserById(userId);
|
SysUser sysUser = sysUserService.selectUserById(userId);
|
||||||
if (sysUser == null) {
|
if (!Optional.ofNullable(sysUser).isPresent()) {
|
||||||
return AjaxResult.warn("用户不存在");
|
return AjaxResult.warn("用户不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
Member member = memberService.getUseUserMemberByUserId(userId);
|
Member member = memberService.getUseUserMemberByUserId(userId);
|
||||||
if (member == null) {
|
if (!Optional.ofNullable(member).isPresent()) {
|
||||||
return AjaxResult.warn("用户未开通会员");
|
return AjaxResult.warn("用户未开通会员");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.mcwl.memberCenter.domain.MemberBenefit;
|
||||||
import com.mcwl.memberCenter.domain.MemberLevel;
|
import com.mcwl.memberCenter.domain.MemberLevel;
|
||||||
import com.mcwl.memberCenter.service.MemberBenefitService;
|
import com.mcwl.memberCenter.service.MemberBenefitService;
|
||||||
import com.mcwl.memberCenter.service.MemberLevelService;
|
import com.mcwl.memberCenter.service.MemberLevelService;
|
||||||
import com.mcwl.web.controller.memberCenter.pojo.vo.MemberBenefitVO;
|
import com.mcwl.memberCenter.domain.vo.MemberBenefitVO;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
|
@ -1,22 +1,30 @@
|
||||||
package com.mcwl.web.controller.myInvitation;
|
package com.mcwl.web.controller.myInvitation;
|
||||||
|
|
||||||
|
|
||||||
import com.mcwl.common.annotation.Anonymous;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import com.mcwl.common.domain.IdsParam;
|
import com.mcwl.myInvitation.domain.Consume;
|
||||||
|
import com.mcwl.myInvitation.service.ConsumeService;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.ConsumeDto;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消费记录
|
||||||
|
*/
|
||||||
@RestController()
|
@RestController()
|
||||||
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/consume")
|
@RequestMapping("/consume")
|
||||||
public class ConsumeController {
|
public class ConsumeController {
|
||||||
|
|
||||||
@PostMapping()
|
private final ConsumeService consumeService;
|
||||||
@Anonymous
|
|
||||||
public void removeByIds(@RequestBody IdsParam ids){
|
|
||||||
System.out.println(ids);
|
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public void consume(@RequestBody ConsumeDto consumeDto) {
|
||||||
|
|
||||||
|
Consume consume = new Consume();
|
||||||
|
BeanUtil.copyProperties(consumeDto, consume);
|
||||||
|
consumeService.saveConsume(consume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,27 @@
|
||||||
package com.mcwl.web.controller.myInvitation;
|
package com.mcwl.web.controller.myInvitation;
|
||||||
|
|
||||||
|
|
||||||
import com.mcwl.common.annotation.Anonymous;
|
|
||||||
import com.mcwl.common.core.domain.AjaxResult;
|
import com.mcwl.common.core.domain.AjaxResult;
|
||||||
import com.mcwl.common.utils.SecurityUtils;
|
import com.mcwl.common.utils.SecurityUtils;
|
||||||
import com.mcwl.myInvitation.domain.Invitation;
|
import com.mcwl.myInvitation.domain.Invitation;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplayDto;
|
||||||
import com.mcwl.myInvitation.service.InvitationService;
|
import com.mcwl.myInvitation.service.InvitationService;
|
||||||
|
import com.mcwl.myInvitation.domain.vo.EarningsDisplayVO;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static com.mcwl.common.core.domain.AjaxResult.success;
|
import static com.mcwl.common.core.domain.AjaxResult.success;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邀请管理
|
||||||
|
*/
|
||||||
@RestController()
|
@RestController()
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/invitation")
|
@RequestMapping("/invitation")
|
||||||
|
@ -23,6 +30,11 @@ public class InvitationController {
|
||||||
private final InvitationService invitationService;
|
private final InvitationService invitationService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取邀请码
|
||||||
|
* @return 邀请码
|
||||||
|
*/
|
||||||
@GetMapping("/getInvitationCode")
|
@GetMapping("/getInvitationCode")
|
||||||
public AjaxResult getInvitationCode() {
|
public AjaxResult getInvitationCode() {
|
||||||
// 获取当前用户
|
// 获取当前用户
|
||||||
|
@ -31,19 +43,53 @@ public class InvitationController {
|
||||||
return AjaxResult.warn("用户未登录");
|
return AjaxResult.warn("用户未登录");
|
||||||
}
|
}
|
||||||
String invitationCode = invitationService.getInvitationCode(userId);
|
String invitationCode = invitationService.getInvitationCode(userId);
|
||||||
|
if (invitationCode == null) {
|
||||||
|
return AjaxResult.warn("获取邀请码失败");
|
||||||
|
}
|
||||||
return success("操作成功", invitationCode);
|
return success("操作成功", invitationCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list")
|
|
||||||
public AjaxResult list() {
|
/**
|
||||||
List<Invitation> list = invitationService.list();
|
* 获取邀请列表
|
||||||
|
* @param userId 用户id
|
||||||
|
* @return 邀请列表
|
||||||
|
*/
|
||||||
|
|
||||||
|
@GetMapping("/list/{userId}")
|
||||||
|
public AjaxResult list(@PathVariable Long userId) {
|
||||||
|
List<Invitation> list = invitationService.lambdaQuery()
|
||||||
|
.eq(Invitation::getUserId, userId)
|
||||||
|
.list();
|
||||||
return success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/getById")
|
|
||||||
public AjaxResult getById(Long id) {
|
/**
|
||||||
Invitation invitation = invitationService.getById(id);
|
* 邀请人收益展示
|
||||||
return success(invitation);
|
*/
|
||||||
|
@GetMapping("earningsDisplay")
|
||||||
|
public AjaxResult earningsDisplay() {
|
||||||
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
if (!Optional.ofNullable(userId).isPresent()) {
|
||||||
|
return AjaxResult.warn("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
EarningsDisplayVO earningsDisplayVO = new EarningsDisplayVO();
|
||||||
|
|
||||||
|
// 获取邀请人收益
|
||||||
|
Double totalAmount = invitationService.getTotalAmount(userId);
|
||||||
|
|
||||||
|
// 获取我的团员
|
||||||
|
List<EarningsDisplayDto> earningsDisplay = invitationService.getEarningsDisplay(userId);
|
||||||
|
if (earningsDisplay == null || earningsDisplay.isEmpty()) {
|
||||||
|
return AjaxResult.warn("暂无收益");
|
||||||
|
}
|
||||||
|
|
||||||
|
earningsDisplayVO.setTotalAmount(totalAmount);
|
||||||
|
earningsDisplayVO.setEarningsDisplayList(earningsDisplay);
|
||||||
|
|
||||||
|
return success(earningsDisplayVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,6 @@ public class MemberCenterTest {
|
||||||
userMemberTask.updateSubscriptionStatusTask();
|
userMemberTask.updateSubscriptionStatusTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void emptyPointsRemindTaskTst() {
|
|
||||||
|
|
||||||
userMemberTask.emptyPointsRemindTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void memberServiceTest() {
|
public void memberServiceTest() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: Jwt工具类
|
* Jwt工具类
|
||||||
* @author DongZl
|
* @author DongZl
|
||||||
*/
|
*/
|
||||||
public class JwtUtils {
|
public class JwtUtils {
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
<version>3.8.8</version>
|
<version>3.8.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
memberCenter会员中心
|
||||||
|
</description>
|
||||||
|
|
||||||
<artifactId>mcwl-memberCenter</artifactId>
|
<artifactId>mcwl-memberCenter</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -12,7 +12,9 @@ import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分消费者
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@ -20,6 +22,9 @@ public class EmptyPointsRemindConsumer {
|
||||||
|
|
||||||
private final MemberService memberService;
|
private final MemberService memberService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分清零提醒
|
||||||
|
*/
|
||||||
@RabbitListener(queues = QueueConstants.EMPTY_POINTS_REMIND_QUEUE, ackMode = "MANUAL")
|
@RabbitListener(queues = QueueConstants.EMPTY_POINTS_REMIND_QUEUE, ackMode = "MANUAL")
|
||||||
public void emptyPointsRemind(Member Member, Channel channel, Message message) {
|
public void emptyPointsRemind(Member Member, Channel channel, Message message) {
|
||||||
try {
|
try {
|
||||||
|
@ -37,20 +42,4 @@ public class EmptyPointsRemindConsumer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RabbitListener(queues = QueueConstants.MEMBER_BILLING_QUEUE, ackMode = "MANUAL")
|
|
||||||
public void memberBillingQueue(Member member, Channel channel, Message message) {
|
|
||||||
try {
|
|
||||||
// TODO 发送短信提醒用户会员账单,如果支付成功,更新last_payment_date,并重新计算end_date(start_date + 1个月)
|
|
||||||
log.info("获取到会员账单的数据:{}", member);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("处理会员账单消息时出错: {}", e.getMessage(), e);
|
|
||||||
try {
|
|
||||||
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
log.error("消息确认失败: {}", ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.mcwl.memberCenter.consumer;
|
||||||
|
|
||||||
|
import com.mcwl.common.constant.QueueConstants;
|
||||||
|
import com.mcwl.memberCenter.domain.Member;
|
||||||
|
import com.rabbitmq.client.Channel;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员账单消费者
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MemberBillingConsumer {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员账单
|
||||||
|
*/
|
||||||
|
@RabbitListener(queues = QueueConstants.MEMBER_BILLING_QUEUE, ackMode = "MANUAL")
|
||||||
|
public void memberBillingQueue(Member member, Channel channel, Message message) {
|
||||||
|
try {
|
||||||
|
// TODO 发送短信提醒用户会员账单,如果支付成功,更新last_payment_date,并重新计算end_date(start_date + 1个月)
|
||||||
|
log.info("获取到会员账单的数据:{}", member);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理会员账单消息时出错: {}", e.getMessage(), e);
|
||||||
|
try {
|
||||||
|
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
log.error("消息确认失败: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,9 @@ import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@TableName("mem_member")
|
@TableName("mem_member")
|
||||||
|
|
|
@ -7,6 +7,9 @@ import com.mcwl.memberCenter.enums.MemberBenefitTypeEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员权益表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@TableName("mem_member_benefit")
|
@TableName("mem_member_benefit")
|
||||||
|
|
|
@ -8,6 +8,9 @@ import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员消费表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@TableName("mem_member_consume")
|
@TableName("mem_member_consume")
|
||||||
|
|
|
@ -7,6 +7,9 @@ import com.mcwl.memberCenter.enums.MemberPeriodicEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员等级表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@TableName("mem_member_level")
|
@TableName("mem_member_level")
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.mcwl.memberCenter.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员优惠活动关联表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@TableName("mem_member_promotion")
|
||||||
|
public class MemberPromotion {
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.mcwl.memberCenter.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.mcwl.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 促销活动表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@TableName("mem_promotion")
|
||||||
|
public class Promotion extends BaseEntity {
|
||||||
|
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String activityName;
|
||||||
|
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
// 活动类型 活动类型,如“限时折扣”、“额外积分”
|
||||||
|
private String activityType;
|
||||||
|
|
||||||
|
// 折扣/积分奖励 根据活动类型,这里可以是折扣率(如0.8代表8折)
|
||||||
|
private Double activityValue;
|
||||||
|
|
||||||
|
// 活动的详细描述
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
// 适用会员等级 可选字段,用于指定哪些会员等级可以享受此活动(可以用逗号分隔的会员等级ID)
|
||||||
|
private String memberLevelId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.mcwl.web.controller.memberCenter.pojo.dto;
|
package com.mcwl.memberCenter.domain.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.mcwl.web.controller.memberCenter.pojo.dto;
|
package com.mcwl.memberCenter.domain.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.mcwl.web.controller.memberCenter.pojo.vo;
|
package com.mcwl.memberCenter.domain.vo;
|
||||||
|
|
||||||
import com.mcwl.memberCenter.domain.MemberBenefit;
|
import com.mcwl.memberCenter.domain.MemberBenefit;
|
||||||
import com.mcwl.memberCenter.domain.MemberLevel;
|
import com.mcwl.memberCenter.domain.MemberLevel;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.mcwl.web.controller.memberCenter.pojo.vo;
|
package com.mcwl.memberCenter.domain.vo;
|
||||||
|
|
||||||
import com.mcwl.memberCenter.domain.MemberConsume;
|
import com.mcwl.memberCenter.domain.MemberConsume;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -5,6 +5,9 @@ import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员权益类型枚举
|
||||||
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum MemberBenefitTypeEnum {
|
public enum MemberBenefitTypeEnum {
|
||||||
|
|
|
@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员状态枚举
|
||||||
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum MemberEnum {
|
public enum MemberEnum {
|
||||||
|
|
|
@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员周期枚举
|
||||||
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum MemberPeriodicEnum {
|
public enum MemberPeriodicEnum {
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
<version>3.8.8</version>
|
<version>3.8.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
myInvitation我的邀请
|
||||||
|
</description>
|
||||||
|
|
||||||
<artifactId>mcwl-myInvitation</artifactId>
|
<artifactId>mcwl-myInvitation</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -32,6 +36,11 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mcwl</groupId>
|
||||||
|
<artifactId>mcwl-system</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
|
|
@ -4,21 +4,22 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.mcwl.common.core.domain.BaseEntity;
|
import com.mcwl.common.core.domain.BaseEntity;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
// 提成表
|
/**
|
||||||
|
* 提成表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("commissions")
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("inv_commission")
|
||||||
public class Commission extends BaseEntity {
|
public class Commission extends BaseEntity {
|
||||||
|
|
||||||
@TableId
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
// 用户id
|
// 消费者id
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
// 消费id
|
|
||||||
private Long consumeId;
|
private Long consumeId;
|
||||||
|
|
||||||
// 提成金额
|
// 提成金额
|
||||||
|
@ -26,16 +27,4 @@ public class Commission extends BaseEntity {
|
||||||
|
|
||||||
// 支付状态
|
// 支付状态
|
||||||
private Integer payStatus;
|
private Integer payStatus;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Commission that = (Commission) o;
|
|
||||||
return Objects.equals(id, that.id) && Objects.equals(userId, that.userId) && Objects.equals(consumeId, that.consumeId) && Objects.equals(amount, that.amount) && Objects.equals(payStatus, that.payStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id, userId, consumeId, amount, payStatus);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,17 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.mcwl.common.core.domain.BaseEntity;
|
import com.mcwl.common.core.domain.BaseEntity;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
// 消费表
|
/**
|
||||||
|
* 消费表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("consumes")
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("inv_consume")
|
||||||
public class Consume extends BaseEntity {
|
public class Consume extends BaseEntity {
|
||||||
|
|
||||||
@TableId
|
@TableId
|
||||||
|
@ -24,16 +28,4 @@ public class Consume extends BaseEntity {
|
||||||
|
|
||||||
// 消费时间
|
// 消费时间
|
||||||
private Date consumeDate;
|
private Date consumeDate;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Consume consume = (Consume) o;
|
|
||||||
return Objects.equals(id, consume.id) && Objects.equals(userId, consume.userId) && Objects.equals(amount, consume.amount) && Objects.equals(consumeDate, consume.consumeDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id, userId, amount, consumeDate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,12 @@ import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
// 邀请表
|
/**
|
||||||
|
* 邀请表
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("invitations")
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("inv_invitation")
|
||||||
public class Invitation extends BaseEntity {
|
public class Invitation extends BaseEntity {
|
||||||
|
|
||||||
@TableId
|
@TableId
|
||||||
|
@ -24,17 +27,4 @@ public class Invitation extends BaseEntity {
|
||||||
|
|
||||||
// 邀请码
|
// 邀请码
|
||||||
private String invitationCode;
|
private String invitationCode;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Invitation that = (Invitation) o;
|
|
||||||
return Objects.equals(id, that.id) && Objects.equals(userId, that.userId) && Objects.equals(userInviteId, that.userInviteId) && Objects.equals(invitationCode, that.invitationCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id, userId, userInviteId, invitationCode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.mcwl.myInvitation.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消费记录Dto
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ConsumeDto {
|
||||||
|
private Long userId;
|
||||||
|
private Double amount;
|
||||||
|
private Date consumeDate;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.mcwl.myInvitation.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class EarningsDisplay {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.mcwl.myInvitation.domain.dto;
|
||||||
|
|
||||||
|
import com.mcwl.common.core.domain.entity.SysUser;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class EarningsDisplayDto {
|
||||||
|
|
||||||
|
private SysUser user;
|
||||||
|
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.mcwl.myInvitation.domain.vo;
|
||||||
|
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplay;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplayDto;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class EarningsDisplayVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总金额
|
||||||
|
*/
|
||||||
|
private Double totalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提成列表
|
||||||
|
*/
|
||||||
|
private List<EarningsDisplayDto> earningsDisplayList;
|
||||||
|
}
|
|
@ -1,11 +1,16 @@
|
||||||
package com.mcwl.myInvitation.mapper;
|
package com.mcwl.myInvitation.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.mcwl.myInvitation.domain.Commission;
|
|
||||||
import com.mcwl.myInvitation.domain.Invitation;
|
import com.mcwl.myInvitation.domain.Invitation;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplay;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface InvitationMapper extends BaseMapper<Invitation> {
|
public interface InvitationMapper extends BaseMapper<Invitation> {
|
||||||
|
|
||||||
|
Double getTotalAmount(Long userId);
|
||||||
|
|
||||||
|
List<EarningsDisplay> getEarningsDisplay(Long userId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,5 @@ import com.mcwl.myInvitation.domain.Consume;
|
||||||
|
|
||||||
public interface ConsumeService extends IService<Consume> {
|
public interface ConsumeService extends IService<Consume> {
|
||||||
|
|
||||||
|
void saveConsume(Consume consume);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,10 @@ package com.mcwl.myInvitation.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.mcwl.myInvitation.domain.Invitation;
|
import com.mcwl.myInvitation.domain.Invitation;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplay;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplayDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface InvitationService extends IService<Invitation> {
|
public interface InvitationService extends IService<Invitation> {
|
||||||
|
|
||||||
|
@ -11,4 +15,8 @@ public interface InvitationService extends IService<Invitation> {
|
||||||
* @return 邀请码
|
* @return 邀请码
|
||||||
*/
|
*/
|
||||||
String getInvitationCode(Long userId);
|
String getInvitationCode(Long userId);
|
||||||
|
|
||||||
|
List<EarningsDisplayDto> getEarningsDisplay(Long userId);
|
||||||
|
|
||||||
|
Double getTotalAmount(Long userId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,47 @@
|
||||||
package com.mcwl.myInvitation.service.impl;
|
package com.mcwl.myInvitation.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.mcwl.common.core.domain.entity.SysUser;
|
||||||
|
import com.mcwl.myInvitation.domain.Commission;
|
||||||
import com.mcwl.myInvitation.domain.Consume;
|
import com.mcwl.myInvitation.domain.Consume;
|
||||||
import com.mcwl.myInvitation.mapper.ConsumeMapper;
|
import com.mcwl.myInvitation.mapper.ConsumeMapper;
|
||||||
|
import com.mcwl.myInvitation.service.CommissionService;
|
||||||
import com.mcwl.myInvitation.service.ConsumeService;
|
import com.mcwl.myInvitation.service.ConsumeService;
|
||||||
|
import com.mcwl.system.service.ISysUserService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ConsumeServiceImpl extends ServiceImpl<ConsumeMapper, Consume> implements ConsumeService {
|
public class ConsumeServiceImpl extends ServiceImpl<ConsumeMapper, Consume> implements ConsumeService {
|
||||||
|
|
||||||
|
private final ConsumeMapper consumeMapper;
|
||||||
|
|
||||||
|
private final CommissionService commissionService;
|
||||||
|
|
||||||
|
private final ISysUserService sysUserService;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void saveConsume(Consume consume) {
|
||||||
|
consumeMapper.insert(consume);
|
||||||
|
|
||||||
|
Commission commission = new Commission();
|
||||||
|
SysUser sysUser = sysUserService.selectUserById(consume.getUserId());
|
||||||
|
// TODO 设置用户id
|
||||||
|
// commission.setUserId(sysUser.getParentId());
|
||||||
|
|
||||||
|
// 设置消费者id
|
||||||
|
commission.setConsumeId(consume.getUserId());
|
||||||
|
|
||||||
|
// TODO 设置佣金,目前固定2.0
|
||||||
|
commission.setAmount(2.0);
|
||||||
|
commission.setPayStatus(0);
|
||||||
|
|
||||||
|
commissionService.save(commission);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,60 @@
|
||||||
package com.mcwl.myInvitation.service.impl;
|
package com.mcwl.myInvitation.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.mcwl.common.constant.JwtConstants;
|
|
||||||
import com.mcwl.common.utils.JwtUtils;
|
|
||||||
import com.mcwl.common.utils.ShareCodeUtils;
|
import com.mcwl.common.utils.ShareCodeUtils;
|
||||||
import com.mcwl.myInvitation.domain.Invitation;
|
import com.mcwl.myInvitation.domain.Invitation;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplay;
|
||||||
|
import com.mcwl.myInvitation.domain.dto.EarningsDisplayDto;
|
||||||
import com.mcwl.myInvitation.mapper.InvitationMapper;
|
import com.mcwl.myInvitation.mapper.InvitationMapper;
|
||||||
|
import com.mcwl.myInvitation.service.ConsumeService;
|
||||||
import com.mcwl.myInvitation.service.InvitationService;
|
import com.mcwl.myInvitation.service.InvitationService;
|
||||||
|
import com.mcwl.system.service.ISysUserService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class InvitationServiceImpl extends ServiceImpl<InvitationMapper, Invitation> implements InvitationService {
|
public class InvitationServiceImpl extends ServiceImpl<InvitationMapper, Invitation> implements InvitationService {
|
||||||
|
|
||||||
|
|
||||||
|
private final ConsumeService consumeService;
|
||||||
|
|
||||||
|
private final ISysUserService sysUserService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getInvitationCode(Long userId) {
|
public String getInvitationCode(Long userId) {
|
||||||
|
if (userId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// 生成邀请码
|
// 生成邀请码
|
||||||
String invitationCode = ShareCodeUtils.idToCode(userId);
|
return ShareCodeUtils.idToCode(userId);
|
||||||
return invitationCode;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EarningsDisplayDto> getEarningsDisplay(Long userId) {
|
||||||
|
List<EarningsDisplay> earningsDisplay = baseMapper.getEarningsDisplay(userId);
|
||||||
|
if (earningsDisplay == null || earningsDisplay.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<EarningsDisplayDto> list = new ArrayList<>();
|
||||||
|
earningsDisplay.forEach(item -> {
|
||||||
|
EarningsDisplayDto edd = new EarningsDisplayDto();
|
||||||
|
edd.setUser(sysUserService.selectUserById(item.getUserId()));
|
||||||
|
edd.setCount(item.getCount());
|
||||||
|
list.add(edd);
|
||||||
|
});
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double getTotalAmount(Long userId) {
|
||||||
|
return baseMapper.getTotalAmount(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,23 @@
|
||||||
<mapper namespace="com.mcwl.myInvitation.mapper.InvitationMapper">
|
<mapper namespace="com.mcwl.myInvitation.mapper.InvitationMapper">
|
||||||
|
|
||||||
|
|
||||||
|
<select id="getTotalAmount" resultType="java.lang.Double">
|
||||||
|
select sum(com.amount)
|
||||||
|
from inv_invitation inv
|
||||||
|
join inv_consume con
|
||||||
|
on inv.user_invite_id = con.user_id
|
||||||
|
join inv_commission com on com.consume_id = con.id
|
||||||
|
where inv.user_id = #{userId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getEarningsDisplay" resultType="com.mcwl.myInvitation.domain.dto.EarningsDisplay">
|
||||||
|
select inv.user_invite_id as userId, count(con.id) as count
|
||||||
|
from inv_invitation inv
|
||||||
|
left join inv_consume con
|
||||||
|
on inv.user_invite_id = con.user_id
|
||||||
|
where inv.user_id = #{userId}
|
||||||
|
group by inv.user_invite_id
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
Loading…
Reference in New Issue