Kaynağa Gözat

积分模块积分获取,积分自动过期,完成订单积分规则

wanxl 1 yıl önce
ebeveyn
işleme
d29fc18b7a

+ 16 - 0
db/tcwn20241118.sql

@@ -0,0 +1,16 @@
+INSERT INTO `tcwm2.5`.common_info
+(id, create_at, max, min, `type`, value, condition_from)
+VALUES(436, now(), NULL, '完成订单获取积分开关(0:关 1:开)', 436, 0, 'integral');
+INSERT INTO `tcwm2.5`.common_info
+(id, create_at, max, min, `type`, value, condition_from)
+VALUES(437, now(), NULL, '积分获取规则', 437, '10,1,30,8,1', 'integral');
+INSERT INTO `tcwm2.5`.common_info
+(id, create_at, max, min, `type`, value, condition_from)
+VALUES(438, now(), NULL, '积分过期规则', 438, 10, 'integral');
+INSERT INTO `tcwm2.5`.common_info
+(id, create_at, max, min, `type`, value, condition_from)
+VALUES(439, now(), NULL, '每笔订单积分上限', 439, 10, 'integral');
+
+ALTER TABLE `tcwm2.5`.user_integral_details ADD order_number varchar(100) NULL COMMENT '关联订单号';
+ALTER TABLE `tcwm2.5`.user_integral_details ADD exp_time varchar(64) NULL COMMENT '过期时间';
+ALTER TABLE `tcwm2.5`.user_integral_details MODIFY COLUMN classify int(11) NULL COMMENT '获取类型 1签到 2积分兑换优惠券 3系统赠送积分 4 完成订单获取积分 5 积分过期';

+ 64 - 0
src/main/java/com/sqx/modules/integral/controller/AdminUserIntegralController.java

@@ -1,6 +1,10 @@
 package com.sqx.modules.integral.controller;
 
+import com.alibaba.fastjson.JSONObject;
 import com.sqx.common.utils.Result;
+import com.sqx.modules.common.entity.CommonInfo;
+import com.sqx.modules.common.service.CommonInfoService;
+import com.sqx.modules.integral.dto.IntegralRulesDto;
 import com.sqx.modules.integral.service.UserIntegralService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -9,6 +13,9 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.HashMap;
+import java.util.Map;
+
 @Api(tags={"管理端-积分"})
 @RestController
 @RequestMapping("/admin/userintegral")
@@ -16,6 +23,8 @@ public class AdminUserIntegralController {
 
     @Autowired
     private UserIntegralService userIntegralService;
+    @Autowired
+    private CommonInfoService commonInfoService;
 
     @ApiOperation("管理端给用户添加积分")
     @PostMapping(value = "addAdminIntegral")
@@ -24,5 +33,60 @@ public class AdminUserIntegralController {
         return userIntegralService.addAdminIntegral(userId, sum, type);
     }
 
+    @ApiOperation("管理端查询积分规则")
+    @PostMapping(value = "queryIntegralRules")
+    public Result queryIntegralRules(){
+        Map<String,Object> result=new HashMap<>();
+        //积分开关
+        String flag =commonInfoService.findOne(436).getValue();
+        //积分规则
+        String rules=commonInfoService.findOne(437).getValue();
+        String[] split = rules.split(",",5);
+        //积分过期规则 -1永不过期
+        String overdue= commonInfoService.findOne(438).getValue();
+        //每笔订单积分上限
+        String maxIntegral= commonInfoService.findOne(439).getValue();
+        result.put("flag",flag);
+        result.put("ruleAmount1",split[0]);
+        result.put("ruleValue1",split[1]);
+        result.put("ruleMaxAmount",split[2]);
+        result.put("ruleAmount2",split[3]);
+        result.put("ruleValue2",split[4]);
+        result.put("overdue",overdue);
+        result.put("overdueFlag","-1".equals(overdue)?"0":"1");
+        result.put("maxIntegral",maxIntegral);
+        return Result.success().put("data", result);
+    }
+
+    @ApiOperation("管理端更新积分规则")
+    @PostMapping(value = "updateIntegralRules")
+    public Result updateIntegralRules(IntegralRulesDto irDto){
+        String rules=irDto.getRuleAmount1()+","+irDto.getRuleValue1()+","+irDto.getRuleMaxAmount()+","+irDto.getRuleAmount2()+
+                ","+irDto.getRuleValue2();
+        //积分开关
+        CommonInfo commonInfo1=commonInfoService.findOne(436);
+        commonInfo1.setValue(irDto.getFlag());
+        commonInfoService.updateBody(commonInfo1);
+        //积分规则
+        CommonInfo commonInfo2=commonInfoService.findOne(437);
+        commonInfo2.setValue(rules);
+        commonInfoService.updateBody(commonInfo2);
+        //过期规则
+        CommonInfo commonInfo3=commonInfoService.findOne(438);
+        commonInfo3.setValue(irDto.getOverdue());
+        commonInfoService.updateBody(commonInfo3);
+        //积分上限
+        CommonInfo commonInfo4=commonInfoService.findOne(439);
+        commonInfo4.setValue(irDto.getMaxIntegral());
+        commonInfoService.updateBody(commonInfo4);
 
+        return Result.success();
+    }
+
+    @ApiOperation("管理端查询积分列表")
+    @PostMapping(value = "queryIntegralList")
+    public Result queryIntegralList(Integer page, Integer limit,Long phone, String orderNumber, Integer classify){
+
+        return userIntegralService.queryIntegralList(page,limit,phone, orderNumber, classify);
+    }
 }

+ 43 - 4
src/main/java/com/sqx/modules/integral/controller/app/UserIntegralController.java

@@ -2,14 +2,16 @@ package com.sqx.modules.integral.controller.app;
 
 import com.sqx.common.utils.Result;
 import com.sqx.modules.app.annotation.Login;
+import com.sqx.modules.common.service.CommonInfoService;
 import com.sqx.modules.integral.service.UserIntegralService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.val;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
 
 @Api(tags={"用户端-积分"})
 @RestController
@@ -18,6 +20,8 @@ public class UserIntegralController {
 
     @Autowired
     private UserIntegralService userIntegralService;
+    @Autowired
+    private CommonInfoService commonInfoService;
 
     @Login
     @ApiOperation("判断用户是否已签到")
@@ -68,5 +72,40 @@ public class UserIntegralController {
         return userIntegralService.findUserMessage(userId);
     }
 
+    @Login
+    @ApiOperation("根据计算可获得积分数")
+    @GetMapping(value = "/getIntegralByMoney")
+    public Result getIntegralByMoney(String money){
+        //积分规则
+        Map<String,Object> result=new HashMap<>();
+        String flag=commonInfoService.findOne(436).getValue();
+        String rules=commonInfoService.findOne(437).getValue();
+        String maxIntegral= commonInfoService.findOne(439).getValue();
+        String[] split = rules.split(",",5);
+        int a= Integer.parseInt(split[0]);
+        int b = Integer.parseInt(split[1]);
+        int c= Integer.parseInt(split[2]);
+        int d = Integer.parseInt(split[3]);
+        int e= Integer.parseInt(split[4]);
+        double amount= Double.parseDouble(money);
+        int intergral=0;
+        if (amount>a){
+            intergral=intergral+b;
+            if (amount>c+d){
+                int count= (int) ((amount-c)/d);
+                intergral=intergral+count*e;
+            }
+        }
+        int max =Integer.parseInt(maxIntegral);
+        result.put("ruleAmount1",split[0]);
+        result.put("ruleValue1",split[1]);
+        result.put("ruleMaxAmount",split[2]);
+        result.put("ruleAmount2",split[3]);
+        result.put("ruleValue2",split[4]);
+        result.put("maxIntegral",maxIntegral);
+        result.put("flag",flag);
+        result.put("intergral", Math.min(max, intergral));
+        return Result.success().put("data", result);
+    }
 
 }

+ 6 - 0
src/main/java/com/sqx/modules/integral/dao/UserIntegralDetailsDao.java

@@ -8,6 +8,8 @@ import com.sqx.modules.integral.entity.UserIntegralDetails;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 @Mapper
 public interface UserIntegralDetailsDao extends BaseMapper<UserIntegralDetails> {
 
@@ -18,4 +20,8 @@ public interface UserIntegralDetailsDao extends BaseMapper<UserIntegralDetails>
     IPage<UserIntegralDetails> selectSignIn(Page<UserIntegralDetails> pages,@Param("userId") Long userId);
 
     UserIntegralDetails selectUserIntegralDetails(@Param("userId") Long userId, @Param("date") String date);
+
+    IPage<UserIntegralDetails> queryIntegralList(Page<UserIntegralDetails> pages, Long phone, String orderNumber, Integer classify);
+
+    List<UserIntegralDetails> selectUserIntegralDetailsByExp(@Param("date") String date);
 }

+ 37 - 0
src/main/java/com/sqx/modules/integral/dto/IntegralRulesDto.java

@@ -0,0 +1,37 @@
+package com.sqx.modules.integral.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+
+@Data
+public class IntegralRulesDto {
+    @ApiModelProperty("积分获取开关 1开、0关")
+    @NotBlank(message = "积分获取开关不能为空")
+    @Pattern(regexp = "(0|1)", message = "积分获取开关只能为0或1")
+    private String flag;
+
+    @ApiModelProperty("积分获取规则金额1")
+    @NotBlank(message = "积分获取规则金额1不能为空")
+    private String ruleAmount1;
+    @ApiModelProperty("积分获取规则积分1")
+    @NotBlank(message = "积分获取规则积分1不能为空")
+    private String ruleValue1;
+    @ApiModelProperty("积分获取二阶段规则金额")
+    @NotBlank(message = "积分获取二阶段规则金额不能为空")
+    private String ruleMaxAmount;
+    @ApiModelProperty("积分获取规则金额2")
+    @NotBlank(message = "金额2不能为空")
+    private String ruleAmount2;
+    @ApiModelProperty("积分获取规则积分2")
+    @NotBlank(message = "积分2不能为空")
+    private String ruleValue2;
+    @ApiModelProperty("积分过期规则(-1为永不过期)")
+    @NotBlank(message = "过期天数不能为空")
+    private String overdue;
+    @ApiModelProperty("单笔订单获取积分上限")
+    @NotBlank(message = "积分上限不能为空")
+    private String maxIntegral;
+}

+ 15 - 0
src/main/java/com/sqx/modules/integral/entity/UserIntegralDetails.java

@@ -1,6 +1,7 @@
 package com.sqx.modules.integral.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -46,5 +47,19 @@ public class UserIntegralDetails implements Serializable {
     @ApiModelProperty("连续签到天数")
     private Integer day;
 
+    @ApiModelProperty("过期时间")
+    private String expTime;
+
+    @ApiModelProperty("订单编号")
+    private String orderNumber;
+
+    @ApiModelProperty("手机号")
+    @TableField(exist = false)
+    private String phone;
+
+    @ApiModelProperty("用户昵称")
+    @TableField(exist = false)
+    private String userName;
+
     public UserIntegralDetails() {}
 }

+ 3 - 0
src/main/java/com/sqx/modules/integral/service/UserIntegralService.java

@@ -22,4 +22,7 @@ public interface UserIntegralService extends IService<UserIntegral> {
 
     Result addAdminIntegral(Long userId, Integer sum, Integer type);
 
+    Result queryIntegralList(Integer page, Integer limit,Long phone, String orderNumber, Integer classify);
+
+    void updateExpiration();
 }

+ 34 - 4
src/main/java/com/sqx/modules/integral/service/impl/UserIntegralServiceImpl.java

@@ -1,7 +1,9 @@
 package com.sqx.modules.integral.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sqx.common.utils.PageUtils;
 import com.sqx.common.utils.Result;
 import com.sqx.modules.app.dao.UserMoneyDao;
 import com.sqx.modules.app.entity.UserMoney;
@@ -20,10 +22,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
+import java.util.*;
 
 @Service
 public class UserIntegralServiceImpl extends ServiceImpl<UserIntegralDao, UserIntegral> implements UserIntegralService {
@@ -299,4 +298,35 @@ public class UserIntegralServiceImpl extends ServiceImpl<UserIntegralDao, UserIn
         return Result.success();
     }*/
 
+    /**
+     * @param phone
+     * @param orderNumber
+     * @param classify
+     * @return
+     */
+    @Override
+    public Result queryIntegralList(Integer page, Integer limit,Long phone, String orderNumber, Integer classify) {
+        Page<UserIntegralDetails> pages=new Page<>(page,limit);
+        PageUtils pageUtils = new PageUtils(userIntegralDetailsDao.queryIntegralList(pages, phone,orderNumber,classify));
+        return Result.success().put("data", pageUtils);
+    }
+
+    /**
+     *
+     */
+    @Override
+    public void updateExpiration() {
+        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+        List<UserIntegralDetails> detailsList=userIntegralDetailsDao.selectUserIntegralDetailsByExp(date);
+        for(UserIntegralDetails userIntegralDetails:detailsList){
+            userIntegralDetails.setClassify(6);
+            userIntegralDetailsDao.updateById(userIntegralDetails);
+            userIntegralDetails.setClassify(5);
+            userIntegralDetails.setType(2);
+            userIntegralDetails.setContent("积分过期");
+            userIntegralDetails.setId(null);
+            userIntegralDetailsDao.insert(userIntegralDetails);
+            userIntegralDao.updateUserIntegral(userIntegralDetails.getUserId(),userIntegralDetails.getNum());
+        }
+    }
 }

+ 51 - 0
src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java

@@ -57,6 +57,9 @@ import com.sqx.modules.goods.entity.Goods;
 import com.sqx.modules.goods.entity.GoodsShop;
 import com.sqx.modules.goods.entity.GoodsShopRelevancy;
 import com.sqx.modules.goods.entity.GoodsSku;
+import com.sqx.modules.integral.dao.UserIntegralDao;
+import com.sqx.modules.integral.dao.UserIntegralDetailsDao;
+import com.sqx.modules.integral.entity.UserIntegralDetails;
 import com.sqx.modules.message.dao.MessageInfoDao;
 import com.sqx.modules.message.entity.MessageInfo;
 import com.sqx.modules.order.dao.AppOrderDao;
@@ -172,6 +175,10 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
     private TbIndentSmsTemplateService smsTemplateService;
     @Autowired
     private PlatformTransactionManager transactionManager;
+    @Autowired
+    private UserIntegralDao userIntegralDao;
+    @Autowired
+    private UserIntegralDetailsDao userIntegralDetailsDao;
 
     @Resource
     private RedissonClient redissonClient;
@@ -2034,6 +2041,50 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         } else if (shopIds != -1) {
             contentBuffer.append("(本单为商家优惠券,商家补贴)");
         }
+        //计算积分
+        String flag=commonInfoService.findOne(436).getValue();
+        if("1".equals(flag)){
+            try {
+                UserIntegralDetails userIntegralDetails = new UserIntegralDetails();
+                String rules=commonInfoService.findOne(437).getValue();
+                //积分过期规则 -1永不过期
+                String overdue= commonInfoService.findOne(438).getValue();
+                String maxIntegral= commonInfoService.findOne(439).getValue();
+                String[] split = rules.split(",",5);
+                int am1= Integer.parseInt(split[0]);
+                int av1 = Integer.parseInt(split[1]);
+                int mx= Integer.parseInt(split[2]);
+                int am2 = Integer.parseInt(split[3]);
+                int av2= Integer.parseInt(split[4]);
+                double amount= tbOrder.getPayMoney().doubleValue();
+                int intergral=0;
+                if (amount>am1){
+                    intergral=intergral+av1;
+                    if (amount>mx+am2){
+                        int count= (int) ((amount-mx)/am2);
+                        intergral=intergral+count*av2;
+                    }
+                }
+                int max =Math.min(Integer.parseInt(maxIntegral), intergral);
+                userIntegralDetails.setContent("完成订单获得积分");
+                userIntegralDetails.setClassify(4);
+                userIntegralDetails.setType(1);
+                userIntegralDetails.setNum(max);
+                userIntegralDetails.setOrderNumber(tbOrder.getOrderNumber());
+                if(!"-1".equals(overdue)){
+                     Date expdata=DateUtils.addDateDays(new Date(), Integer.parseInt(overdue));
+                    userIntegralDetails.setExpTime(new SimpleDateFormat("yyyy-MM-dd").format(expdata));
+                }
+
+                userIntegralDetails.setCreateTime(format);
+                userIntegralDetails.setUserId(tbOrder.getUserId());
+                userIntegralDetailsDao.insert(userIntegralDetails);
+                //添加积分
+                userIntegralDao.addUserIntegral(max, tbOrder.getUserId());
+            } catch (NumberFormatException e) {
+                log.error("订单{}====积分入账异常{}",orderId, e.getMessage());
+            }
+        }
 
         userMoneyDetails1.setContent(contentBuffer.toString());
 

+ 5 - 0
src/main/java/com/sqx/scheduler/config/SchedulerLock.java

@@ -42,4 +42,9 @@ public interface SchedulerLock {
      * 订单超时锁
      */
     String TIME_OUT_LOCK = "wm:time:out:lock";
+
+    /**
+     * 用户优惠券自动过期锁
+     */
+    String INTEGRAL_OF_USER_EXPIRATION_LOCK = "wm:lock:integral:exp";
 }

+ 48 - 0
src/main/java/com/sqx/scheduler/integral/IntegralScheduler.java

@@ -0,0 +1,48 @@
+package com.sqx.scheduler.integral;
+
+import com.sqx.modules.coupon.service.TbCouponUserService;
+import com.sqx.modules.integral.service.UserIntegralService;
+import com.sqx.scheduler.config.SchedulerLock;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 优惠券定时任务
+ *
+ * @author : codingliang
+ * @date : 2024-09-09 12:22
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class IntegralScheduler {
+
+    private final UserIntegralService integralService;
+    private final RedissonClient redissonClient;
+
+    /**
+     * 将所有超过失效时间的积分改为失效状态
+     * 每分钟运行一次
+     */
+    @Async
+    @Scheduled(cron = "0 0 2 * * ?", zone = "Asia/Shanghai")
+    public void couponEnd(){
+        RLock lock = redissonClient.getLock(SchedulerLock.INTEGRAL_OF_USER_EXPIRATION_LOCK);
+        lock.lock();
+        try {
+            log.info("用户积分自动过期任务运行");
+            integralService.updateExpiration();
+            log.info("用户积分自动过期任务运行成功");
+        } catch (Exception e) {
+            log.error("用户积分自动过期任务运行失败,【{}】", e);
+        } finally {
+            lock.unlock();
+        }
+
+    }
+}

+ 1 - 1
src/main/resources/application-dev.yml

@@ -47,7 +47,7 @@ spring:
                 max-wait: -1
 secure-api:
     # 开启SecureApi功能,如果为false则其余配置项均不生效
-    enabled: true
+    enabled: false
     # 开启加解密日志打印,会打印出接口名、加密模式、算法、明文和密文等信息
     show-log: true
     url-safe: true

+ 18 - 0
src/main/resources/mapper/integra/UserIntegralDetailsMapper.xml

@@ -23,4 +23,22 @@
         select * from user_integral_details where user_id = #{userId} and date_format(create_time,'%Y-%m-%d')=date_format(#{date},'%Y-%m-%d') and classify = 1
     </select>
 
+    <select id="queryIntegralList" resultType="com.sqx.modules.integral.entity.UserIntegralDetails">
+        select uid.*,tu.phone as phone ,tu.user_name as userName
+        from user_integral_details uid left join tb_user tu on uid.user_id =tu.user_id
+        where 1=1
+        <if test="classify!=null and classify!=''">
+            and uid.classify = #{classify}
+        </if>
+        <if test="phone!=null and phone!=''">
+            and tu.phone like CONCAT('%',#{phone},'%')
+        </if>
+        <if test="orderNumber!=null and orderNumber!=''" >
+            and uid.orderNumber like CONCAT('%',#{orderNumber},'%')
+        </if>
+        order by create_time desc
+    </select>
+    <select id="selectUserIntegralDetailsByExp" resultType="com.sqx.modules.integral.entity.UserIntegralDetails">
+        select * from user_integral_details where date_format(exp_time,'%Y-%m-%d') &lt;=date_format(#{date},'%Y-%m-%d') and classify = 4
+    </select>
 </mapper>