diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml index 585f0c1..76e94bc 100644 --- a/ruoyi-admin/src/main/resources/logback.xml +++ b/ruoyi-admin/src/main/resources/logback.xml @@ -66,6 +66,14 @@ + + + + + + + + diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java index 5d2404b..e5c5cf6 100644 --- a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java +++ b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/ServiceTest.java @@ -7,6 +7,7 @@ import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.symmetric.AES; import com.cyl.h5.pojo.dto.PayNotifyMessageDTO; import com.cyl.h5.service.H5OrderService; +import com.cyl.manager.act.service.IntegralHistoryService; import com.cyl.manager.ums.service.MemberCartService; import com.ruoyi.RuoYiApplication; import com.ruoyi.common.config.properties.SmsProperties; @@ -24,6 +25,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; +import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -43,6 +45,14 @@ public class ServiceTest { @Value("${aes.key}") private String key; + @Autowired + private IntegralHistoryService integralHistoryService; + + @Test + public void test12(){ + integralHistoryService.handleIntegral(5405053175810048L,new BigDecimal("2.89"),29L); + } + @Test public void test1() { diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 493cfb7..96727be 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -132,6 +132,8 @@ public class Constants */ public static final String SYS_CONFIG_KEY = "sys_config:"; + public static final String INTEGRAL_RULE_KEY = "activity-integral-income-set-key"; + /** * 字典管理 cache key */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 855bc00..13ca6b3 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -3,9 +3,14 @@ package com.ruoyi.common.utils; import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.temporal.ChronoUnit; +import java.util.Arrays; import java.util.Date; +import java.util.List; + import org.apache.commons.lang3.time.DateFormatUtils; /** @@ -164,4 +169,16 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils public static Long betweenDay(LocalDateTime beginTime, LocalDateTime endTime){ return ChronoUnit.DAYS.between(beginTime.toLocalDate().atStartOfDay(),endTime.toLocalDate().atStartOfDay()); } + + public static List getTimeDiff(int days){ + // 获取当前日期 + LocalDate current = LocalDate.now(); + + // 获取第一天 + LocalDate firstDayOfLastMonth = current.minusMonths(days).withDayOfMonth(1); + // 获取上个月最后一天 + LocalDate lastDayOfLastMonth = firstDayOfLastMonth.plusMonths(1).withDayOfMonth(1).minusDays(1); + + return Arrays.asList(LocalDateTime.of(firstDayOfLastMonth, LocalTime.MIN),LocalDateTime.of(lastDayOfLastMonth, LocalTime.MAX)); + } } diff --git a/ruoyi-generator/src/test/java/com/ruoyi/generator/ApplicationTest.java b/ruoyi-generator/src/test/java/com/ruoyi/generator/ApplicationTest.java index 21ab343..35fdc6e 100644 --- a/ruoyi-generator/src/test/java/com/ruoyi/generator/ApplicationTest.java +++ b/ruoyi-generator/src/test/java/com/ruoyi/generator/ApplicationTest.java @@ -39,7 +39,7 @@ public class ApplicationTest { // "oms_order_operate_history", // "oms_aftersale", // "oms_aftersale_item" - "aws_system_statistics" + "act_integral_history" ); // 查询表信息 List tableList = genTableService.selectGenTableByName(tableNames); diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java b/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java index 989f2da..4975495 100644 --- a/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java +++ b/ruoyi-mall/src/main/java/com/cyl/h5/service/H5OrderService.java @@ -16,6 +16,7 @@ import com.cyl.h5.pojo.request.OrderPayRequest; import com.cyl.h5.pojo.response.OrderPayResponse; import com.cyl.h5.pojo.vo.*; import com.cyl.h5.pojo.vo.form.OrderSubmitForm; +import com.cyl.manager.act.service.IntegralHistoryService; import com.cyl.manager.oms.convert.AftersaleItemConvert; import com.cyl.manager.oms.convert.OrderItemConvert; import com.cyl.manager.oms.domain.*; @@ -119,6 +120,9 @@ public class H5OrderService { @Autowired private OrderItemConvert orderItemConvert; + @Autowired + private IntegralHistoryService integralHistoryService; + @Transactional public Long submit(OrderSubmitForm form) { Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO); @@ -602,6 +606,9 @@ public class H5OrderService { optHistory.setUpdateBy(order.getMemberId()); optHistory.setUpdateTime(optDate); orderOperateHistoryMapper.insert(optHistory); + + //处理积分 + integralHistoryService.handleIntegral(order.getId(),order.getPayAmount(),order.getMemberId()); }); UpdateWrapper paymentHistoryUpdateWrapper = new UpdateWrapper<>(); paymentHistoryUpdateWrapper.eq("order_id", messageDTO.getOutTradeNo()).set("payment_id", messageDTO.getTradeNo()) diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/controller/H5IntegralHistoryController.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/controller/H5IntegralHistoryController.java new file mode 100644 index 0000000..cd4d139 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/controller/H5IntegralHistoryController.java @@ -0,0 +1,80 @@ +package com.cyl.manager.act.controller; + +import com.cyl.h5.config.SecurityUtil; +import com.cyl.manager.act.domain.IntegralHistory; +import com.cyl.manager.act.pojo.query.IntegralHistoryQuery; +import com.cyl.manager.act.pojo.vo.IntegralStatVO; +import com.cyl.manager.act.service.IntegralHistoryService; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.DateUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 积分流水表Controller + * + * @author zcc + * @date 2024-03-01 + */ +@Api(description ="积分流水表接口列表") +@RestController +@RequestMapping("/h5/act/integral") +public class H5IntegralHistoryController extends BaseController { + @Autowired + private IntegralHistoryService service; + + @ApiOperation("查询积分流水表列表") + @GetMapping("/list") + public ResponseEntity> list(Integer month) { + IntegralHistoryQuery query = new IntegralHistoryQuery(); + query.setMemberId(SecurityUtil.getLocalMember().getId()); + query.setOpType(1); + query.setSubOpType(11); + List timeDiff = DateUtils.getTimeDiff(month); + query.setStart(timeDiff.get(0)); + query.setEnd(timeDiff.get(1)); + List list = service.selectList2(query); + return ResponseEntity.ok(list); + } + + @ApiOperation("新增积分流水表") + @Log(title = "积分流水表", businessType = BusinessType.INSERT) + @PostMapping("/add") + public ResponseEntity add(BigDecimal amount) { + + IntegralHistory history = new IntegralHistory(); + history.setOpType(1); + history.setSubOpType(11); + history.setAmount(amount); + history.setMemberId(SecurityUtil.getLocalMember().getId()); + history.setCreateTime(LocalDateTime.now()); + return ResponseEntity.ok(service.insert2(history)); + } + + @ApiOperation("积分流水") + @PostMapping("/history/list") + public ResponseEntity> list(@RequestBody IntegralHistoryQuery query, Pageable page) { + List list = service.selectListByH5(query, page); + return ResponseEntity.ok(new PageImpl<>(list, page, ((com.github.pagehelper.Page)list).getTotal())); + } + + @ApiOperation("积分统计") + @PostMapping("/stat") + public ResponseEntity statIntegral(@RequestBody IntegralHistoryQuery query) { + IntegralStatVO res = service.statIntegral(query); + return ResponseEntity.ok(res); + } + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/controller/IntegralHistoryController.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/controller/IntegralHistoryController.java new file mode 100644 index 0000000..0d4c5b6 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/controller/IntegralHistoryController.java @@ -0,0 +1,93 @@ +package com.cyl.manager.act.controller; + +import java.util.List; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Page; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.enums.BusinessType; +import com.cyl.manager.act.convert.IntegralHistoryConvert; +import com.cyl.manager.act.domain.IntegralHistory; +import com.cyl.manager.act.pojo.query.IntegralHistoryQuery; +import com.cyl.manager.act.service.IntegralHistoryService; +import com.cyl.manager.act.pojo.vo.IntegralHistoryVO; +import com.ruoyi.common.utils.poi.ExcelUtil; +/** + * 积分流水表Controller + * + * @author zcc + * @date 2024-03-01 + */ +@Api(description ="积分流水表接口列表") +@RestController +@RequestMapping("/act/integralHistory") +public class IntegralHistoryController extends BaseController { + @Autowired + private IntegralHistoryService service; + @Autowired + private IntegralHistoryConvert convert; + + @ApiOperation("查询积分流水表列表") + @PreAuthorize("@ss.hasPermi('act:integralHistory:list')") + @PostMapping("/list") + public ResponseEntity> list(@RequestBody IntegralHistoryQuery query, Pageable page) { + List list = service.selectList(query, page); + return ResponseEntity.ok(new PageImpl<>(list, page, ((com.github.pagehelper.Page)list).getTotal())); + } + + @ApiOperation("导出积分流水表列表") + @PreAuthorize("@ss.hasPermi('act:integralHistory:export')") + @Log(title = "积分流水表", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public ResponseEntity export(IntegralHistoryQuery query) { + List list = service.selectList(query, null); + ExcelUtil util = new ExcelUtil<>(IntegralHistoryVO.class); + return ResponseEntity.ok(util.writeExcel(convert.dos2vos(list), "积分流水表数据")); + } + + @ApiOperation("获取积分流水表详细信息") + @PreAuthorize("@ss.hasPermi('act:integralHistory:query')") + @GetMapping(value = "/{id}") + public ResponseEntity getInfo(@PathVariable("id") Long id) { + return ResponseEntity.ok(service.selectById(id)); + } + + @ApiOperation("新增积分流水表") + @PreAuthorize("@ss.hasPermi('act:integralHistory:add')") + @Log(title = "积分流水表", businessType = BusinessType.INSERT) + @PostMapping + public ResponseEntity add(@RequestBody IntegralHistory integralHistory) { + return ResponseEntity.ok(service.insert(integralHistory)); + } + + @ApiOperation("修改积分流水表") + @PreAuthorize("@ss.hasPermi('act:integralHistory:edit')") + @Log(title = "积分流水表", businessType = BusinessType.UPDATE) + @PutMapping + public ResponseEntity edit(@RequestBody IntegralHistory integralHistory) { + return ResponseEntity.ok(service.update(integralHistory)); + } + + @ApiOperation("删除积分流水表") + @PreAuthorize("@ss.hasPermi('act:integralHistory:remove')") + @Log(title = "积分流水表", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public ResponseEntity remove(@PathVariable Long id) { + return ResponseEntity.ok(service.deleteById(id)); + } +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/convert/IntegralHistoryConvert.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/convert/IntegralHistoryConvert.java new file mode 100644 index 0000000..4b60765 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/convert/IntegralHistoryConvert.java @@ -0,0 +1,16 @@ +package com.cyl.manager.act.convert; + +import org.mapstruct.Mapper; +import com.cyl.manager.act.domain.IntegralHistory; +import com.cyl.manager.act.pojo.vo.IntegralHistoryVO; +import java.util.List; +/** + * 积分流水表 DO <=> DTO <=> VO / BO / Query + * + * @author zcc + */ +@Mapper(componentModel = "spring") +public interface IntegralHistoryConvert { + + List dos2vos(List list); +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/domain/IntegralHistory.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/domain/IntegralHistory.java new file mode 100644 index 0000000..6c567c5 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/domain/IntegralHistory.java @@ -0,0 +1,54 @@ +package com.cyl.manager.act.domain; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.baomidou.mybatisplus.annotation.TableName; +/** + * 积分流水表对象 act_integral_history + * + * @author zcc + */ +@ApiModel(description="积分流水表对象") +@Data +@TableName("act_integral_history") +public class IntegralHistory { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("ID") + private Long id; + + @ApiModelProperty("MEMBER_ID") + @Excel(name = "MEMBER_ID") + private Long memberId; + + @ApiModelProperty("变动金额") + @Excel(name = "变动金额") + private BigDecimal amount; + + @ApiModelProperty("类型 1:收入 2:支出 3:其他") + @Excel(name = "类型 1:收入 2:支出 3:其他") + private Integer opType; + + @ApiModelProperty("子类型:11签到 12消费获得 21退款扣除积分") + @Excel(name = "子类型:11签到 12消费获得 21退款扣除积分") + private Integer subOpType; + + @ApiModelProperty("订单金额") + @Excel(name = "订单金额") + private BigDecimal orderAmount; + + @ApiModelProperty("订单id") + @Excel(name = "订单id") + private Long orderId; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/mapper/IntegralHistoryMapper.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/mapper/IntegralHistoryMapper.java new file mode 100644 index 0000000..c29c037 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/mapper/IntegralHistoryMapper.java @@ -0,0 +1,25 @@ +package com.cyl.manager.act.mapper; + +import java.time.LocalDateTime; +import java.util.List; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cyl.manager.act.pojo.vo.IntegralStatVO; +import org.apache.ibatis.annotations.Param; +import com.cyl.manager.act.domain.IntegralHistory; + +/** + * 积分流水表Mapper接口 + * + * @author zcc + */ +public interface IntegralHistoryMapper extends BaseMapper { + /** + * 查询积分流水表列表 + * + * @param integralHistory 积分流水表 + * @return 积分流水表集合 + */ + List selectByEntity(IntegralHistory integralHistory); + + IntegralStatVO statIntegral(LocalDateTime start, LocalDateTime end, Long memberId); +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/query/IntegralHistoryQuery.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/query/IntegralHistoryQuery.java new file mode 100644 index 0000000..78a4302 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/query/IntegralHistoryQuery.java @@ -0,0 +1,45 @@ +package com.cyl.manager.act.pojo.query; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotBlank; + +/** + * 积分流水表 查询 对象 + * + * @author zcc + */ +@ApiModel(description="积分流水表 查询 对象") +@Data +public class IntegralHistoryQuery { + @ApiModelProperty("MEMBER_ID 精确匹配") + private Long memberId; + + @ApiModelProperty("变动金额 精确匹配") + private BigDecimal amount; + + @ApiModelProperty("类型 1:收入 2:支出 3:其他 精确匹配") + private Integer opType; + + @ApiModelProperty("子类型:11签到 12消费获得 21退款扣除积分 精确匹配") + private Integer subOpType; + + @ApiModelProperty("订单金额 精确匹配") + private BigDecimal orderAmount; + + @ApiModelProperty("订单id 精确匹配") + private Long orderId; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime start; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime end; + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralHistoryVO.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralHistoryVO.java new file mode 100644 index 0000000..e64b725 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralHistoryVO.java @@ -0,0 +1,37 @@ +package com.cyl.manager.act.pojo.vo; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import com.ruoyi.common.annotation.Excel; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +/** + * 积分流水表 数据视图对象 + * + * @author zcc + */ +@Data +public class IntegralHistoryVO { + /** ID */ + private Long id; + /** MEMBER_ID */ + @Excel(name = "MEMBER_ID") + private Long memberId; + /** 变动金额 */ + @Excel(name = "变动金额") + private BigDecimal amount; + /** 类型 1:收入 2:支出 3:其他 */ + @Excel(name = "类型 1:收入 2:支出 3:其他") + private Integer opType; + /** 子类型:11签到 12消费获得 21退款扣除积分 */ + @Excel(name = "子类型:11签到 12消费获得 21退款扣除积分") + private Integer subOpType; + /** 订单金额 */ + @Excel(name = "订单金额") + private BigDecimal orderAmount; + /** 订单id */ + @Excel(name = "订单id") + private Long orderId; + /** 创建时间 */ + private LocalDateTime createTime; +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralRule.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralRule.java new file mode 100644 index 0000000..35c9fd2 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralRule.java @@ -0,0 +1,13 @@ +package com.cyl.manager.act.pojo.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class IntegralRule { + private Integer signStatus = 1; + private BigDecimal signCount = BigDecimal.valueOf(1); + private BigDecimal orderAmount = BigDecimal.valueOf(1); + private BigDecimal orderCount = BigDecimal.valueOf(1); +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralStatVO.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralStatVO.java new file mode 100644 index 0000000..0b1ba93 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/pojo/vo/IntegralStatVO.java @@ -0,0 +1,14 @@ +package com.cyl.manager.act.pojo.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class IntegralStatVO { + private BigDecimal balance = BigDecimal.ZERO; + + private BigDecimal income = BigDecimal.ZERO; + + private BigDecimal expenditure = BigDecimal.ZERO; +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/act/service/IntegralHistoryService.java b/ruoyi-mall/src/main/java/com/cyl/manager/act/service/IntegralHistoryService.java new file mode 100644 index 0000000..9691f3b --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/act/service/IntegralHistoryService.java @@ -0,0 +1,228 @@ +package com.cyl.manager.act.service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.time.LocalDateTime; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.cyl.h5.config.SecurityUtil; +import com.cyl.manager.act.pojo.vo.IntegralRule; +import com.cyl.manager.act.pojo.vo.IntegralStatVO; +import com.cyl.manager.ums.domain.Member; +import com.cyl.manager.ums.domain.MemberAccount; +import com.cyl.manager.ums.mapper.MemberAccountMapper; +import com.github.pagehelper.PageHelper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.framework.config.LocalDataUtil; +import com.ruoyi.system.service.ISysConfigService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import com.cyl.manager.act.mapper.IntegralHistoryMapper; +import com.cyl.manager.act.domain.IntegralHistory; +import com.cyl.manager.act.pojo.query.IntegralHistoryQuery; +import org.springframework.transaction.annotation.Transactional; + +/** + * 积分流水表Service业务层处理 + * + * @author zcc + */ +@Service +@Slf4j +@Transactional +public class IntegralHistoryService { + @Autowired + private IntegralHistoryMapper integralHistoryMapper; + @Autowired + private MemberAccountMapper memberAccountMapper; + @Autowired + private ISysConfigService sysConfigService; + + /** + * 查询积分流水表 + * + * @param id 积分流水表主键 + * @return 积分流水表 + */ + public IntegralHistory selectById(Long id) { + return integralHistoryMapper.selectById(id); + } + + /** + * 查询积分流水表列表 + * + * @param query 查询条件 + * @param page 分页条件 + * @return 积分流水表 + */ + public List selectList(IntegralHistoryQuery query, Pageable page) { + if (page != null) { + PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize()); + } + QueryWrapper qw = new QueryWrapper<>(); + Long memberId = query.getMemberId(); + if (memberId != null) { + qw.eq("member_id", memberId); + } + BigDecimal amount = query.getAmount(); + if (amount != null) { + qw.eq("amount", amount); + } + Integer opType = query.getOpType(); + if (opType != null) { + qw.eq("op_type", opType); + } + Integer subOpType = query.getSubOpType(); + if (subOpType != null) { + qw.eq("sub_op_type", subOpType); + } + BigDecimal orderAmount = query.getOrderAmount(); + if (orderAmount != null) { + qw.eq("order_amount", orderAmount); + } + Long orderId = query.getOrderId(); + if (orderId != null) { + qw.eq("order_id", orderId); + } + return integralHistoryMapper.selectList(qw); + } + + public List selectList2(IntegralHistoryQuery query) { + QueryWrapper qw = new QueryWrapper<>(); + Long memberId = query.getMemberId(); + if (memberId != null) { + qw.eq("member_id", memberId); + } + Integer opType = query.getOpType(); + if (opType != null) { + qw.eq("op_type", opType); + } + Integer subOpType = query.getSubOpType(); + if (subOpType != null) { + qw.eq("sub_op_type", subOpType); + } + if (query.getStart() != null) { + qw.ge("create_time", query.getStart()); + } + if (query.getEnd() != null) { + qw.le("create_time", query.getEnd()); + } + return integralHistoryMapper.selectList(qw); + } + + /** + * 新增积分流水表 + * + * @param integralHistory 积分流水表 + * @return 结果 + */ + public int insert(IntegralHistory integralHistory) { + integralHistory.setCreateTime(LocalDateTime.now()); + return integralHistoryMapper.insert(integralHistory); + } + + public int insert2(IntegralHistory history) { + Long memberId = history.getMemberId(); + //保存member_account + MemberAccount memberAccount = memberAccountMapper.selectById(memberId); + if (memberAccount == null) { + memberAccount = new MemberAccount(); + memberAccount.setMemberId(memberId); + memberAccount.setIntegralBalance(history.getAmount()); + memberAccount.setTotalIntegralBalance(history.getAmount()); + memberAccount.setCreateTime(LocalDateTime.now()); + memberAccountMapper.insert(memberAccount); + } else { + memberAccountMapper.updateIntegralBalance(history.getAmount(), memberId); + } + return integralHistoryMapper.insert(history); + } + + public void handleIntegral(Long orderId, BigDecimal amount, Long memberId) { + String config = sysConfigService.selectConfigByKey(Constants.INTEGRAL_RULE_KEY); + IntegralRule rule; + if (StringUtils.isNotEmpty(config)) { + rule = JSON.parseObject(config, IntegralRule.class); + } else { + rule = new IntegralRule(); + } + BigDecimal divide = amount.divide(rule.getOrderAmount(), 0, RoundingMode.DOWN); + if (divide.compareTo(BigDecimal.ZERO) < 1) { + log.info("订单:{},金额:{}不足{}元,不记录积分",orderId,amount,rule.getOrderAmount()); + return; + } + BigDecimal total = divide.multiply(rule.getOrderCount()); + if (total.compareTo(BigDecimal.ZERO) < 1) { + log.info("订单:{},orderCount为0,不记录积分",orderId); + return; + } + IntegralHistory history = new IntegralHistory(); + history.setOpType(1); + history.setSubOpType(12); + history.setAmount(total); + history.setOrderId(orderId); + history.setOrderAmount(amount); + history.setMemberId(memberId); + history.setCreateTime(LocalDateTime.now()); + insert2(history); + } + + /** + * 修改积分流水表 + * + * @param integralHistory 积分流水表 + * @return 结果 + */ + public int update(IntegralHistory integralHistory) { + return integralHistoryMapper.updateById(integralHistory); + } + + /** + * 删除积分流水表信息 + * + * @param id 积分流水表主键 + * @return 结果 + */ + public int deleteById(Long id) { + return integralHistoryMapper.deleteById(id); + } + + public List selectListByH5(IntegralHistoryQuery query, Pageable page) { + if (page != null) { + PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize()); + } + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("member_id", SecurityUtil.getLocalMember().getId()) + .ge("create_time", query.getStart()) + .le("create_time", query.getEnd()); + Integer opType = query.getOpType(); + if (opType != null) { + qw.eq("op_type", opType); + } + Integer subOpType = query.getSubOpType(); + if (subOpType != null) { + qw.eq("sub_op_type", subOpType); + } + qw.orderByDesc("id"); + return integralHistoryMapper.selectList(qw); + } + + public IntegralStatVO statIntegral(IntegralHistoryQuery query) { + Long memberId = SecurityUtil.getLocalMember().getId(); + IntegralStatVO statVO = integralHistoryMapper.statIntegral(query.getStart(), query.getEnd(), memberId); + if (statVO == null) { + statVO = new IntegralStatVO(); + } + MemberAccount memberAccount = memberAccountMapper.selectById(memberId); + statVO.setBalance(memberAccount == null ? BigDecimal.ZERO : memberAccount.getIntegralBalance()); + return statVO; + } +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/controller/MemberAccountController.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/controller/MemberAccountController.java new file mode 100644 index 0000000..bd0f05f --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/controller/MemberAccountController.java @@ -0,0 +1,93 @@ +package com.cyl.manager.ums.controller; + +import java.util.List; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Page; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.enums.BusinessType; +import com.cyl.manager.ums.convert.MemberAccountConvert; +import com.cyl.manager.ums.domain.MemberAccount; +import com.cyl.manager.ums.pojo.query.MemberAccountQuery; +import com.cyl.manager.ums.service.MemberAccountService; +import com.cyl.manager.ums.pojo.vo.MemberAccountVO; +import com.ruoyi.common.utils.poi.ExcelUtil; +/** + * 会员账户表Controller + * + * @author zcc + * @date 2024-03-01 + */ +@Api(description ="会员账户表接口列表") +@RestController +@RequestMapping("/ums/memberAccount") +public class MemberAccountController extends BaseController { + @Autowired + private MemberAccountService service; + @Autowired + private MemberAccountConvert convert; + + @ApiOperation("查询会员账户表列表") + @PreAuthorize("@ss.hasPermi('ums:memberAccount:list')") + @PostMapping("/list") + public ResponseEntity> list(@RequestBody MemberAccountQuery query, Pageable page) { + List list = service.selectList(query, page); + return ResponseEntity.ok(new PageImpl<>(list, page, ((com.github.pagehelper.Page)list).getTotal())); + } + + @ApiOperation("导出会员账户表列表") + @PreAuthorize("@ss.hasPermi('ums:memberAccount:export')") + @Log(title = "会员账户表", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public ResponseEntity export(MemberAccountQuery query) { + List list = service.selectList(query, null); + ExcelUtil util = new ExcelUtil<>(MemberAccountVO.class); + return ResponseEntity.ok(util.writeExcel(convert.dos2vos(list), "会员账户表数据")); + } + + @ApiOperation("获取会员账户表详细信息") + @PreAuthorize("@ss.hasPermi('ums:memberAccount:query')") + @GetMapping(value = "/{memberId}") + public ResponseEntity getInfo(@PathVariable("memberId") Long memberId) { + return ResponseEntity.ok(service.selectByMemberId(memberId)); + } + + @ApiOperation("新增会员账户表") + @PreAuthorize("@ss.hasPermi('ums:memberAccount:add')") + @Log(title = "会员账户表", businessType = BusinessType.INSERT) + @PostMapping + public ResponseEntity add(@RequestBody MemberAccount memberAccount) { + return ResponseEntity.ok(service.insert(memberAccount)); + } + + @ApiOperation("修改会员账户表") + @PreAuthorize("@ss.hasPermi('ums:memberAccount:edit')") + @Log(title = "会员账户表", businessType = BusinessType.UPDATE) + @PutMapping + public ResponseEntity edit(@RequestBody MemberAccount memberAccount) { + return ResponseEntity.ok(service.update(memberAccount)); + } + + @ApiOperation("删除会员账户表") + @PreAuthorize("@ss.hasPermi('ums:memberAccount:remove')") + @Log(title = "会员账户表", businessType = BusinessType.DELETE) + @DeleteMapping("/{memberId}") + public ResponseEntity remove(@PathVariable Long memberId) { + return ResponseEntity.ok(service.deleteByMemberId(memberId)); + } +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/convert/MemberAccountConvert.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/convert/MemberAccountConvert.java new file mode 100644 index 0000000..e1ad886 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/convert/MemberAccountConvert.java @@ -0,0 +1,16 @@ +package com.cyl.manager.ums.convert; + +import org.mapstruct.Mapper; +import com.cyl.manager.ums.domain.MemberAccount; +import com.cyl.manager.ums.pojo.vo.MemberAccountVO; +import java.util.List; +/** + * 会员账户表 DO <=> DTO <=> VO / BO / Query + * + * @author zcc + */ +@Mapper(componentModel = "spring") +public interface MemberAccountConvert { + + List dos2vos(List list); +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/domain/MemberAccount.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/domain/MemberAccount.java new file mode 100644 index 0000000..36bc614 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/domain/MemberAccount.java @@ -0,0 +1,42 @@ +package com.cyl.manager.ums.domain; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import com.baomidou.mybatisplus.annotation.TableName; +/** + * 会员账户表对象 ums_member_account + * + * @author zcc + */ +@ApiModel(description="会员账户表对象") +@Data +@TableName("ums_member_account") +public class MemberAccount { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("MEMBER_ID") + @TableId(value="member_id", type = IdType.ASSIGN_ID) + private Long memberId; + + @ApiModelProperty("积分余额") + @Excel(name = "积分余额") + private BigDecimal integralBalance; + + @ApiModelProperty("历史总共积分") + @Excel(name = "历史总共积分") + private BigDecimal totalIntegralBalance; + + @ApiModelProperty("修改时间") + private LocalDateTime updateTime; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/mapper/MemberAccountMapper.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/mapper/MemberAccountMapper.java new file mode 100644 index 0000000..f3e5950 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/mapper/MemberAccountMapper.java @@ -0,0 +1,24 @@ +package com.cyl.manager.ums.mapper; + +import java.math.BigDecimal; +import java.util.List; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import com.cyl.manager.ums.domain.MemberAccount; + +/** + * 会员账户表Mapper接口 + * + * @author zcc + */ +public interface MemberAccountMapper extends BaseMapper { + /** + * 查询会员账户表列表 + * + * @param memberAccount 会员账户表 + * @return 会员账户表集合 + */ + List selectByEntity(MemberAccount memberAccount); + + int updateIntegralBalance(@Param("amount") BigDecimal amount, @Param("memberId") Long memberId); +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/pojo/query/MemberAccountQuery.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/pojo/query/MemberAccountQuery.java new file mode 100644 index 0000000..26aaa26 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/pojo/query/MemberAccountQuery.java @@ -0,0 +1,23 @@ +package com.cyl.manager.ums.pojo.query; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * 会员账户表 查询 对象 + * + * @author zcc + */ +@ApiModel(description="会员账户表 查询 对象") +@Data +public class MemberAccountQuery { + @ApiModelProperty("积分余额 精确匹配") + private BigDecimal integralBalance; + + @ApiModelProperty("历史总共积分 精确匹配") + private BigDecimal totalIntegralBalance; + +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/pojo/vo/MemberAccountVO.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/pojo/vo/MemberAccountVO.java new file mode 100644 index 0000000..9bf06a8 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/pojo/vo/MemberAccountVO.java @@ -0,0 +1,27 @@ +package com.cyl.manager.ums.pojo.vo; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import com.ruoyi.common.annotation.Excel; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +/** + * 会员账户表 数据视图对象 + * + * @author zcc + */ +@Data +public class MemberAccountVO { + /** MEMBER_ID */ + private Long memberId; + /** 积分余额 */ + @Excel(name = "积分余额") + private BigDecimal integralBalance; + /** 历史总共积分 */ + @Excel(name = "历史总共积分") + private BigDecimal totalIntegralBalance; + /** 修改时间 */ + private LocalDateTime updateTime; + /** 创建时间 */ + private LocalDateTime createTime; +} diff --git a/ruoyi-mall/src/main/java/com/cyl/manager/ums/service/MemberAccountService.java b/ruoyi-mall/src/main/java/com/cyl/manager/ums/service/MemberAccountService.java new file mode 100644 index 0000000..8644812 --- /dev/null +++ b/ruoyi-mall/src/main/java/com/cyl/manager/ums/service/MemberAccountService.java @@ -0,0 +1,92 @@ +package com.cyl.manager.ums.service; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.github.pagehelper.PageHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import com.cyl.manager.ums.mapper.MemberAccountMapper; +import com.cyl.manager.ums.domain.MemberAccount; +import com.cyl.manager.ums.pojo.query.MemberAccountQuery; + +/** + * 会员账户表Service业务层处理 + * + * + * @author zcc + */ +@Service +public class MemberAccountService { + @Autowired + private MemberAccountMapper memberAccountMapper; + + /** + * 查询会员账户表 + * + * @param memberId 会员账户表主键 + * @return 会员账户表 + */ + public MemberAccount selectByMemberId(Long memberId) { + return memberAccountMapper.selectById(memberId); + } + + /** + * 查询会员账户表列表 + * + * @param query 查询条件 + * @param page 分页条件 + * @return 会员账户表 + */ + public List selectList(MemberAccountQuery query, Pageable page) { + if (page != null) { + PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize()); + } + QueryWrapper qw = new QueryWrapper<>(); + BigDecimal integralBalance = query.getIntegralBalance(); + if (integralBalance != null) { + qw.eq("integral_balance", integralBalance); + } + BigDecimal totalIntegralBalance = query.getTotalIntegralBalance(); + if (totalIntegralBalance != null) { + qw.eq("total_integral_balance", totalIntegralBalance); + } + return memberAccountMapper.selectList(qw); + } + + /** + * 新增会员账户表 + * + * @param memberAccount 会员账户表 + * @return 结果 + */ + public int insert(MemberAccount memberAccount) { + memberAccount.setCreateTime(LocalDateTime.now()); + return memberAccountMapper.insert(memberAccount); + } + + /** + * 修改会员账户表 + * + * @param memberAccount 会员账户表 + * @return 结果 + */ + public int update(MemberAccount memberAccount) { + return memberAccountMapper.updateById(memberAccount); + } + + /** + * 删除会员账户表信息 + * + * @param memberId 会员账户表主键 + * @return 结果 + */ + public int deleteByMemberId(Long memberId) { + return memberAccountMapper.deleteById(memberId); + } +} diff --git a/ruoyi-mall/src/main/resources/mapper/act/IntegralHistoryMapper.xml b/ruoyi-mall/src/main/resources/mapper/act/IntegralHistoryMapper.xml new file mode 100644 index 0000000..428a57c --- /dev/null +++ b/ruoyi-mall/src/main/resources/mapper/act/IntegralHistoryMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + select id, member_id, amount, op_type, sub_op_type, order_amount, order_id, create_time from act_integral_history + + + + + diff --git a/ruoyi-mall/src/main/resources/mapper/ums/MemberAccountMapper.xml b/ruoyi-mall/src/main/resources/mapper/ums/MemberAccountMapper.xml new file mode 100644 index 0000000..896bce5 --- /dev/null +++ b/ruoyi-mall/src/main/resources/mapper/ums/MemberAccountMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + select member_id, integral_balance, total_integral_balance, update_time, create_time from ums_member_account + + + update ums_member_account set integral_balance = integral_balance + #{amount},total_integral_balance = total_integral_balance + #{amount},update_time = now() + where member_id = #{memberId} + + + + diff --git a/sql/数据和结构.sql b/sql/数据和结构.sql index 202ad01..3bb43ab 100644 --- a/sql/数据和结构.sql +++ b/sql/数据和结构.sql @@ -35213,3 +35213,26 @@ CREATE TABLE `ums_feedback` `handle_time` datetime(3) DEFAULT NULL COMMENT '处理时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='意见反馈'; + +CREATE TABLE `act_integral_history` +( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `member_id` bigint(20) NOT NULL, + `amount` decimal(10, 2) NOT NULL COMMENT '变动金额', + `op_type` int(11) NOT NULL COMMENT '类型 1:收入 2:支出 3:其他', + `sub_op_type` int(11) DEFAULT NULL COMMENT '子类型:11签到 12消费获得 21退款扣除积分', + `order_amount` decimal(10, 2) DEFAULT NULL COMMENT '订单金额', + `order_id` bigint(20) DEFAULT NULL COMMENT '订单id', + `create_time` datetime(3) DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分流水表'; + +CREATE TABLE `ums_member_account` +( + `member_id` bigint(20) NOT NULL, + `integral_balance` decimal(10, 2) DEFAULT '0.00' COMMENT '积分余额', + `total_integral_balance` decimal(10, 2) DEFAULT NULL COMMENT '历史总共积分', + `update_time` datetime(3) DEFAULT NULL COMMENT '修改时间', + `create_time` datetime(3) DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`member_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员账户表'; \ No newline at end of file