wanghao 2 месяцев назад
Родитель
Сommit
b44cf947de

+ 20 - 0
commons/src/main/java/com/jzg/commons/entity/dto/GenerateQrcodeParam.java

@@ -0,0 +1,20 @@
+package com.jzg.commons.entity.dto;
+
+import lombok.Data;
+
+/**
+ * 获取本地生活二维码参数实体
+ */
+@Data
+public class GenerateQrcodeParam {
+    /**
+     * 活动id
+     */
+    private String activityId;
+    /**
+     * 拼接参数(活动id,手机号,抽奖次数)
+     */
+    private String query;
+
+
+}

+ 3 - 0
commons/src/main/java/com/jzg/commons/entity/vo/InsOrdersOtherInfoVo.java

@@ -100,6 +100,9 @@ public class InsOrdersOtherInfoVo {
     @Schema(description = "商业折扣")
     private BigDecimal syAdjustRate;
 
+    @Schema(description = "整单折扣")
+    private BigDecimal totalAdjustRate;
+
 //    @Schema(description = "太平绿黄红区间评分")
 //    private String tpColorScore;
 //

+ 9 - 13
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/client/LocalLivingClient.java

@@ -1,10 +1,11 @@
 package com.jzg.quotation.summary.client;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.databind.JsonNode;
 import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.GenerateQrcodeParam;
 import com.jzg.commons.entity.dto.LotteryCounDTO;
 import com.jzg.commons.entity.dto.UnifiedUserCenterDTO;
-import com.jzg.commons.entity.vo.LotteryActivityVO;
 import com.jzg.commons.entity.vo.LotteryCountVO;
 import com.jzg.commons.entity.vo.UnifiedUserClientVO;
 import com.jzg.quotation.summary.entity.Result;
@@ -76,7 +77,7 @@ public interface LocalLivingClient {
      * @return 活动列表
      */
     @GetMapping("lottery/lotteryActivity/queryActivityList")
-    HttpResult<List<LotteryActivityVO>> queryActivityRules(@RequestParam("scene") Integer scene);
+    JsonNode queryActivityRules(@RequestParam("scene") Integer scene);
     /**
      * 添加用户抽奖次数
      *
@@ -86,18 +87,13 @@ public interface LocalLivingClient {
     @PostMapping("/localUserLotteryCount/add")
     HttpResult<LotteryCountVO> addLotteryCount(@RequestBody LotteryCounDTO lotteryCounDTO);
 
+
     /**
-     * 查询用户绑定
-     * @param unifiedUserCenterDTO
-     * @return
-     */
-    @PostMapping("/userApp/queryBind")
-    HttpResult<UnifiedUserClientVO> queryBind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
-    /**
-     * 添加用户绑定
-     * @param unifiedUserCenterDTO
+     * 获取小程序二维码
+     * @param param
      * @return
      */
-    @PostMapping("/userApp/bind")
-    HttpResult<UnifiedUserClientVO> bind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
+    @PostMapping("/lottery/lotteryActivity/generateQrcode")
+    Result<String> generateQrcode(@RequestBody GenerateQrcodeParam param);
+
 }

+ 41 - 0
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/client/UnifiedAccountClient.java

@@ -0,0 +1,41 @@
+package com.jzg.quotation.summary.client;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.LotteryCounDTO;
+import com.jzg.commons.entity.dto.UnifiedUserCenterDTO;
+import com.jzg.commons.entity.vo.LotteryCountVO;
+import com.jzg.commons.entity.vo.UnifiedUserClientVO;
+import com.jzg.quotation.summary.entity.Result;
+import com.jzg.quotation.summary.entity.dto.*;
+import com.jzg.quotation.summary.entity.vo.ChannelRightsPackageVO;
+import com.jzg.quotation.summary.entity.vo.ChannelRightsVO;
+import com.jzg.quotation.summary.utils.FeignConfig;
+import jakarta.validation.Valid;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 调用一账通client
+ */
+@FeignClient(value = "jeecg-boot", url = "${feign.client.unifiedAccountClient.url}" )
+public interface UnifiedAccountClient {
+
+    /**
+     * 查询用户绑定
+     * @param unifiedUserCenterDTO
+     * @return
+     */
+    @PostMapping("/userApp/queryBind")
+    HttpResult<UnifiedUserClientVO> queryBind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
+    /**
+     * 添加用户绑定
+     * @param unifiedUserCenterDTO
+     * @return
+     */
+    @PostMapping("/userApp/bind")
+    HttpResult<UnifiedUserClientVO> bind(@RequestBody UnifiedUserCenterDTO unifiedUserCenterDTO);
+}

+ 234 - 86
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/controller/UnifyOrderManager.java

@@ -10,7 +10,12 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.jzg.commons.constants.CompanyConstants;
 import com.jzg.commons.constants.InsuranceRisk;
 import com.jzg.commons.constants.dict.InsOrderStatusEnum;
@@ -18,6 +23,7 @@ import com.jzg.commons.constants.quote.enums.base.QuoteRuleCategory;
 import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.core.base.StateResult;
 import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.GenerateQrcodeParam;
 import com.jzg.commons.entity.dto.LotteryCounDTO;
 import com.jzg.commons.entity.dto.MessageAddParam;
 import com.jzg.commons.entity.dto.UnifiedUserCenterDTO;
@@ -51,9 +57,13 @@ import com.jzg.quotation.summary.aop.QuoteVerification;
 import com.jzg.quotation.summary.async.AsyncGetPayLink;
 import com.jzg.quotation.summary.classifier.QuoteInfoParameterFilling;
 import com.jzg.quotation.summary.client.LocalLivingClient;
+import com.jzg.quotation.summary.client.UnifiedAccountClient;
 import com.jzg.quotation.summary.constants.QuoteNumberConstant;
 import com.jzg.quotation.summary.converter.QuoteInfoConverter;
+import com.jzg.quotation.summary.entity.Result;
 import com.jzg.quotation.summary.entity.po.QuoteRuleMapping;
+import com.jzg.quotation.summary.entity.vo.LocalLivingActivityTableVO;
+import com.jzg.quotation.summary.entity.vo.LocalLivingLotteryActivityVO;
 import com.jzg.quotation.summary.factory.CompanyFactory;
 import com.jzg.quotation.summary.service.*;
 import com.jzg.quotation.summary.state.listener.OrderStateListener;
@@ -72,6 +82,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
+import javax.annotation.Resource;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -168,14 +179,22 @@ public class UnifyOrderManager {
 
     @Autowired
     private LocalLivingClient localLivingClient;
+    @Autowired
+    private UnifiedAccountClient unifiedAccountClient;
+
+    @Autowired
+    private ObjectMapper objectMapper;
 
     @Value("${lottery.activity.scene:3}")
     private Integer lotteryScene;
 
+    @Value("${feign.client.jeecg-boot.url}")
+    private String LocalLivingUrl;
 
 
     //本地生活在一账通的固定平台ID
     private static final String CLIENT_ID = "bdsh-X9yZ1wV3uT5sR7qP9o";
+    private static final String JZG_CLIENT_ID = "jzg-7kP9xL2mN5vQ8zR1jW";
 
     private String getSystemCode() {
         //如果是APP登录的话 则传递SystemCode的头部字段
@@ -340,9 +359,11 @@ public class UnifyOrderManager {
 
     /**
      * 记录规则完成
+     *
+     * @return true-本次新增记录;false-已存在记录,未新增
      */
-    private void completeRule(String tenantId, String userId, String userPhone, String activityId,
-                              String tableId, String qutNum, String qutLotteryNum, String qutLotteryMax, Integer status, Integer activityType) {
+    private boolean completeRule(String tenantId, String userId, String userPhone, String activityId,
+                                 String tableId, String qutNum, String qutLotteryNum, String qutLotteryMax, Integer status, Integer activityType) {
         SysUserActivityCompleteInRule exist = null;
         // 先查询是否已存在记录(防重入)
         if (9 != activityType) {
@@ -354,22 +375,23 @@ public class UnifyOrderManager {
         }
 
         if (exist != null) {
-            return;
+            return false;
         }
 
         SysUserActivityCompleteInRule record = new SysUserActivityCompleteInRule();
+        record.setId(IdWorker.getIdStr());
         record.setSystemCode(tenantId);
         record.setUserId(userId);
         record.setUserPhone(userPhone);
         record.setActivityType(activityType);
         record.setActivityId(activityId);
         record.setLocalActivityTableId(tableId);
-        //报价次数
+        // 报价规则中这里记录“触发发放时的当天报价次数”,避免 qutNum 固定为 1 时第二次报价被防重拦截。
         record.setRuleCompleteNum(qutNum);
-        //抽奖次数
+        // 本次实际新增的抽奖次数
         record.setLotteryNum(StrUtil.isNotBlank(qutLotteryNum)
                 ? Integer.parseInt(qutLotteryNum) : 0);
-        //报价用,今日抽奖最大次数
+        // 报价用,今日抽奖最大次数
         record.setLotteryMaxNum(StrUtil.isNotBlank(qutLotteryMax)
                 ? Integer.parseInt(qutLotteryMax) : 0);
         record.setStatus(status);
@@ -380,6 +402,7 @@ public class UnifyOrderManager {
 
         log.info("报价规则完成,tenantId={}, userId={}, activityId={}, qutNum={}, qutLotteryNum={}, qutLotteryMax={}",
                 tenantId, userId, activityId, qutNum, qutLotteryNum, qutLotteryMax);
+        return true;
     }
 
     /**
@@ -398,16 +421,16 @@ public class UnifyOrderManager {
     private void handleQuoteLotteryActivity(QuoteVo quoteVo) {
         try {
             // 远程调用活动列表
-            HttpResult<List<LotteryActivityVO>> result = localLivingClient.queryActivityRules(lotteryScene);
-            if (result == null || result.getCode() != 200 || result.getData() == null) {
-                log.error("统一报价,查询本地生活的活动列表异常");
+            List<LocalLivingLotteryActivityVO> activities = queryLotteryActivities(lotteryScene);
+            if (CollUtil.isEmpty(activities)) {
                 return;
             }
 
-            String tenantId = baseController.getUserSystemCode();
-            String userId = quoteVo.getOrder().getRealQuoteUserId();
+            String tenantId = baseController.getSystemCode();
+            String userId = baseController.getUserId();
+            String quoteUserId = quoteVo.getOrder().getRealQuoteUserId();
 
-            for (LotteryActivityVO activity : result.getData()) {
+            for (LocalLivingLotteryActivityVO activity : activities) {
                 // 检查活动是否有效(当前时间需在活动时间范围内)
                 if (LocalDate.now().isBefore(activity.getActivityStartTime())
                         || LocalDate.now().isAfter(activity.getActivityEndTime())) {
@@ -417,7 +440,7 @@ public class UnifyOrderManager {
                     continue;
                 }
 
-                for (LocalActivityTableVO table : activity.getLocalActivityTables()) {
+                for (LocalLivingActivityTableVO table : activity.getLocalActivityTables()) {
                     // 只处理 type=6 的报价规则
                     if (!"6".equals(table.getType())) {
                         continue;
@@ -428,13 +451,13 @@ public class UnifyOrderManager {
                     }
 
                     // 查询用户是否在一账通绑定过本地生活
-                    HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId, tenantId);
+                    HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId,quoteUserId, tenantId);
                     if (bindResult == null || bindResult.getCode() != 200 || bindResult.getData() == null) {
                         // 未绑定:统计报价次数,满足条件则存本地记录
-                        handleUnboundQuoteRule(tenantId, userId, activity, table);
+                        handleUnboundQuoteRule(tenantId, quoteUserId, activity, table);
                     } else {
                         // 已绑定:检查是否绑定了本地生活客户端,若绑定了则远程同步抽奖次数
-                        handleBoundQuoteRule(tenantId, userId, activity, table, bindResult.getData());
+                        handleBoundQuoteRule(tenantId, quoteUserId, activity, table, bindResult.getData());
                     }
                 }
             }
@@ -443,16 +466,39 @@ public class UnifyOrderManager {
         }
     }
 
+    /**
+     * 查询本地生活抽奖活动列表
+     */
+    private List<LocalLivingLotteryActivityVO> queryLotteryActivities(Integer lotteryScene) {
+        JsonNode response = localLivingClient.queryActivityRules(lotteryScene);
+        if (response == null) {
+            log.error("查询本地生活活动列表异常,返回为空");
+            return Collections.emptyList();
+        }
+        if (!response.path("success").asBoolean(false) || response.path("code").asInt() != 200) {
+            log.error("查询本地生活活动列表异常,response={}", response);
+            return Collections.emptyList();
+        }
+        JsonNode resultNode = response.get("result");
+        if (resultNode == null || !resultNode.isArray() || resultNode.isEmpty()) {
+            log.error("查询本地生活活动列表异常,result为空,response={}", response);
+            return Collections.emptyList();
+        }
+        return objectMapper.convertValue(resultNode, new TypeReference<List<LocalLivingLotteryActivityVO>>() {
+        });
+    }
+
     /**
      * 查询用户在一账通的绑定状态
      */
-    private HttpResult<UnifiedUserClientVO> queryUserBind(String userId, String tenantId) {
+    private HttpResult<UnifiedUserClientVO> queryUserBind(String userId,String userPhone, String tenantId) {
         UnifiedUserCenterDTO dto = new UnifiedUserCenterDTO();
         dto.setUserId(userId);
-        dto.setClientId(CLIENT_ID);
+        dto.setClientId(JZG_CLIENT_ID);
         dto.setTenantId(tenantId);
+        dto.setUserPhone(userPhone);
         try {
-            return localLivingClient.queryBind(dto);
+            return unifiedAccountClient.queryBind(dto);
         } catch (Exception e) {
             log.info("业务员报价,查询用户绑定一账通接口异常,userId:{},clientId:{},tenantId:{}", userId, CLIENT_ID, tenantId);
             log.error("业务员报价,查询用户绑定一账通接口异常", e);
@@ -461,28 +507,78 @@ public class UnifyOrderManager {
     }
 
     /**
-     * 处理未绑定用户的报价规则:统计报价次数,满足条件则存本地记录
+     * 处理未绑定用户的报价规则:统计当天报价次数,满足条件则存本地记录。
+     * <p>
+     * 规则示例:报价1次得1次抽奖机会,每天最多2次。
+     * count=1 时本次新增1次;count=2 时本次新增1次;count>=3 时达到上限,不再新增。
      */
     private void handleUnboundQuoteRule(String tenantId, String userId,
-                                         LotteryActivityVO activity, LocalActivityTableVO table) {
+                                         LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
         int count = insOrdersService.countQuoteNum(tenantId, userId,
-                activity.getActivityStartTime(), activity.getActivityEndTime());
-        if (count >= Integer.parseInt(table.getQutNum())
-                && count <= Integer.parseInt(table.getQutLotteryMax())) {
-            completeRule(tenantId, userId, null, activity.getId(),
-                    table.getId(), table.getQutNum(), table.getQutLotteryNum(),
-                    table.getQutLotteryMax(), YesNoEnum.NO.getCode(), 6);
-            log.info("业务员报价,满足条件插入记录,userId:{},clientId:{},tenantId:{}",
-                    userId, CLIENT_ID, tenantId);
-            // 发送抽奖次数下发通知消息
-            HttpResult<SysUserJzgInfo> sysUser = orgClient.queryUserByUserId(userId,tenantId);
+                LocalDate.now(), LocalDate.now());
+        int currentGrantNum = calculateCurrentQuoteLotteryNum(count, table);
+        if (currentGrantNum <= 0) {
+            return;
+        }
 
-            MessageAddParam param = new MessageAddParam();
-            param.setTitle("抽奖次数下发通知消息");
-            param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
-            param.setTplCode("template_13");
-            param.setReceive(List.of(sysUser.getData().getMobile()));
-            orgClient.messageAdd(param);
+        boolean inserted = completeRule(tenantId, userId, null, activity.getId(),
+                table.getId(), String.valueOf(count), String.valueOf(currentGrantNum),
+                table.getQutLotteryMax(), YesNoEnum.NO.getCode(), 6);
+        if (!inserted) {
+            return;
+        }
+        log.info("业务员报价,满足条件插入记录,userId:{},clientId:{},tenantId:{},count:{},currentGrantNum:{}",
+                userId, CLIENT_ID, tenantId, count, currentGrantNum);
+
+        // 发送抽奖次数下发通知消息,未绑定用户等绑定后再同步发放。
+        HttpResult<SysUserJzgInfo> sysUser = orgClient.queryUserByUserId(userId,tenantId);
+
+        MessageAddParam param = new MessageAddParam();
+        param.setTitle("抽奖次数下发通知消息");
+        param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
+        param.setTplCode("template_13");
+        param.setReceive(List.of(userId));
+        orgClient.messageAdd(param);
+    }
+
+    /**
+     * 计算本次报价应新增的抽奖次数。
+     * 计算方式:
+     * 1. 按当天报价次数计算“当前累计应得次数”:{@code (count / qutNum) * qutLotteryNum}。
+     * 2. 按上一次报价次数计算“上一次累计应得次数”:{@code ((count - 1) / qutNum) * qutLotteryNum}。
+     * 3. 两者都受每日上限 {@code qutLotteryMax} 限制。
+     * 4. 两者差值就是本次报价新增的抽奖次数。
+     * 示例:qutNum=1,qutLotteryNum=1,qutLotteryMax=2。
+     * count=1 返回1;count=2 返回1;count=3 返回0。
+     */
+    private int calculateCurrentQuoteLotteryNum(int count, LocalLivingActivityTableVO table) {
+        int qutNum = parsePositiveInt(table.getQutNum());
+        int qutLotteryNum = parsePositiveInt(table.getQutLotteryNum());
+        int qutLotteryMax = parsePositiveInt(table.getQutLotteryMax());
+        if (count <= 0 || qutNum <= 0 || qutLotteryNum <= 0 || qutLotteryMax <= 0) {
+            return 0;
+        }
+
+        // 当前报价次数下,今天累计最多应该获得多少次抽奖机会。
+        int currentTotal = Math.min((count / qutNum) * qutLotteryNum, qutLotteryMax);
+        // 本次报价之前,今天累计最多应该获得多少次抽奖机会。
+        int previousTotal = Math.min(((count - 1) / qutNum) * qutLotteryNum, qutLotteryMax);
+        // 差值就是本次新增次数;达到每日上限后差值为0,不再新增。
+        return Math.max(currentTotal - previousTotal, 0);
+    }
+
+    /**
+     * 解析正整数,空值或非法数字按0处理,避免活动配置异常影响主报价流程。
+     */
+    private int parsePositiveInt(String value) {
+        if (StrUtil.isBlank(value)) {
+            return 0;
+        }
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            log.warn("抽奖活动数字配置解析失败,value={}", value);
+            return 0;
         }
     }
 
@@ -490,7 +586,7 @@ public class UnifyOrderManager {
      * 处理已绑定用户的报价规则:先判断是否满足规则条件,满足后再远程同步抽奖次数并标记已同步
      */
     private void handleBoundQuoteRule(String tenantId, String userId,
-                                       LotteryActivityVO activity, LocalActivityTableVO table,
+                                       LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table,
                                        UnifiedUserClientVO bindData) {
         Map<String, List<UnifiedUserClientVO>> clientGroupMap = bindData.getUserClients()
                 .stream()
@@ -499,43 +595,49 @@ public class UnifyOrderManager {
             return;
         }
 
-        // 先判断是否满足规则条件
-        int qutLotteryNum = Integer.parseInt(table.getQutLotteryNum());
+        // 按当天报价次数计算本次应新增的抽奖次数,达到每日上限后不再新增。
         int count = insOrdersService.countQuoteNum(tenantId, userId,
-                activity.getActivityStartTime(), activity.getActivityEndTime());
-        if (count < Integer.parseInt(table.getQutNum()) || count > Integer.parseInt(table.getQutLotteryMax())) {
+                LocalDate.now(), LocalDate.now());
+        int currentGrantNum = calculateCurrentQuoteLotteryNum(count, table);
+        if (currentGrantNum <= 0) {
+            return;
+        }
+        // 防止同一次报价重复执行时重复远程发放;这里用当天报价次数作为防重维度。
+        SysUserActivityCompleteInRule exist = insOrdersService.selectByRule(
+                tenantId, userId, activity.getId(), String.valueOf(count), 6);
+        if (exist != null) {
             return;
         }
         HttpResult<SysUserJzgInfo> sysUser = orgClient.queryUserByUserId(userId,tenantId);
 
-        // 满足条件,远程调用抽奖次数增加接口
+        // 满足条件,远程调用抽奖次数增加接口,只发放本次新增次数。
         LotteryCounDTO lotteryCounDTO = new LotteryCounDTO();
         lotteryCounDTO.setAppUserId(userId);
         lotteryCounDTO.setActivityId(activity.getId());
-        lotteryCounDTO.setCount(qutLotteryNum);
+        lotteryCounDTO.setCount(currentGrantNum);
 
         HttpResult<LotteryCountVO> lotteryResult = null;
         try {
             lotteryResult = localLivingClient.addLotteryCount(lotteryCounDTO);
         } catch (Exception e) {
             log.info("业务员报价,远程调用本地生活抽奖次数增加接口异常,userId:{},count:{},tenantId:{}",
-                    userId, table.getQutLotteryNum(), tenantId);
+                    userId, currentGrantNum, tenantId);
             log.error("业务员报价,远程调用本地生活抽奖次数增加异常", e);
         }
 
         if (lotteryResult != null && lotteryResult.getData().getSuccess()) {
             completeRule(tenantId, userId, null, activity.getId(),
-                    table.getId(), table.getQutNum(), table.getQutLotteryNum(),
+                    table.getId(), String.valueOf(count), String.valueOf(currentGrantNum),
                     table.getQutLotteryMax(), YesNoEnum.YES.getCode(), 6);
-            log.info("业务员报价,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{}",
-                    userId, CLIENT_ID, tenantId);
+            log.info("业务员报价,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{},count:{},currentGrantNum:{}",
+                    userId, CLIENT_ID, tenantId, count, currentGrantNum);
 
             // 发送抽奖次数下发通知消息
             MessageAddParam param = new MessageAddParam();
             param.setTitle("抽奖次数下发通知消息");
             param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
             param.setTplCode("template_13");
-            param.setReceive(List.of(sysUser.getData().getMobile()));
+            param.setReceive(List.of(userId));
             orgClient.messageAdd(param);
         }
     }
@@ -843,7 +945,6 @@ public class UnifyOrderManager {
         //////////////////////////////////////////新增营销抽奖活动////////////////////////////////////////////////
         // 承保(客户)、出单(业务员)
         if (orderStatusResultVo.getOrderStatus() == InsOrderStatusEnum.UNDERWRITED) {
-            // TODO: 本地生活逻辑未调试通畅,暂时先注掉
             doSomethingAfterUnderwited(insOrders);
         }
         return HttpResult.ok("状态刷新成功");
@@ -919,16 +1020,34 @@ public class UnifyOrderManager {
      */
     private void doSomethingAfterUnderwited(InsOrders insOrders) {
         try {
-            HttpResult<List<LotteryActivityVO>> result = localLivingClient.queryActivityRules(lotteryScene);
-            if (result == null || result.getCode() != 200 || result.getData() == null) {
-                log.error("活动列表异常");
+            List<LocalLivingLotteryActivityVO> activities = queryLotteryActivities(lotteryScene);
+            if (CollUtil.isEmpty(activities)) {
                 return;
             }
 
-            String tenantId = baseController.getUserSystemCode();
-            String userId = insOrders.getRealQuoteUserId();
+            String tenantId = baseController.getSystemCode();
+            String userId = baseController.getUserId();
+            String quoteUserId = insOrders.getRealQuoteUserId();
+            // 业务员的相关活动
+            for (LocalLivingLotteryActivityVO activity : activities) {
+                // 检查活动是否有效(当前时间需在活动时间范围内)
+                if (LocalDate.now().isBefore(activity.getActivityStartTime())
+                        || LocalDate.now().isAfter(activity.getActivityEndTime())) {
+                    continue;
+                }
+                if (activity.getLocalActivityTables() == null) {
+                    continue;
+                }
 
-            for (LotteryActivityVO activity : result.getData()) {
+                for (LocalLivingActivityTableVO table : activity.getLocalActivityTables()) {
+                    if ("8".equals(table.getType())) {
+                        handleOrderRule(tenantId, userId,quoteUserId, activity, table);
+                    }
+                }
+            }
+            // 客户的相关活动
+            List<LocalLivingLotteryActivityVO> activities2 = queryLotteryActivities(4);
+            for (LocalLivingLotteryActivityVO activity : activities2) {
                 // 检查活动是否有效(当前时间需在活动时间范围内)
                 if (LocalDate.now().isBefore(activity.getActivityStartTime())
                         || LocalDate.now().isAfter(activity.getActivityEndTime())) {
@@ -938,15 +1057,14 @@ public class UnifyOrderManager {
                     continue;
                 }
 
-                for (LocalActivityTableVO table : activity.getLocalActivityTables()) {
+                for (LocalLivingActivityTableVO table : activity.getLocalActivityTables()) {
                     if ("9".equals(table.getType())) {
-                        handleUnderwritingRule(insOrders, activity, table);
-                    }
-                    if ("8".equals(table.getType())) {
-                        handleOrderRule(tenantId, userId, activity, table);
+                        handleUnderwritingRule(tenantId, userId,quoteUserId, insOrders, activity,table);
                     }
                 }
             }
+
+
         } catch (Exception e) {
             log.error("处理承保抽奖活动异常,不影响主承保流程", e);
         }
@@ -955,17 +1073,30 @@ public class UnifyOrderManager {
     /**
      * 处理 type=9 承保规则:按保费区间匹配,满足条件则存本地记录
      */
-    private void handleUnderwritingRule(InsOrders insOrders, LotteryActivityVO activity, LocalActivityTableVO table) {
-        Double totalFee = insOrdersService.queryTotalFee(insOrders.getInsOrderNo());
-        String userPhone = insOrdersService.queryCustomerPhone(insOrders.getInsOrderNo());
-        for (UnderwritingRuleVO rule : table.getUnderwritingRules()) {
+    private void handleUnderwritingRule(String tenantId,String userId,String quoteUserId,InsOrders insOrders, LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
+        Double totalFee = insOrdersService.queryTotalFee(insOrders.getId());
+        String userPhone = insOrdersService.queryCustomerPhone(insOrders.getId());
+        for (LocalLivingActivityTableVO.UnderwritingRule rule : table.getUnderwritingRules()) {
             BigDecimal fee = new BigDecimal(totalFee);
             if (fee.compareTo(rule.getUwMinPremium()) >= 0 && fee.compareTo(rule.getUwMaxPremium()) <= 0) {
-                completeRule(null, null, userPhone, activity.getId(),
+                completeRule(tenantId, quoteUserId, userPhone, activity.getId(),
                         table.getId(), rule.getUwMinPremium() + "-" + rule.getUwMaxPremium(),
                         rule.getUwLotteryNum(), null, YesNoEnum.NO.getCode(), 9);
                 log.info("客户承保,满足条件插入记录,userId:{},clientId:{},tenantId:{}",
                         insOrders.getRealQuoteUserId(), CLIENT_ID, baseController.getUserSystemCode());
+                GenerateQrcodeParam qparam = new GenerateQrcodeParam();
+                qparam.setActivityId(activity.getId());
+                qparam.setQuery("i="+activity.getId()+"&t=1&n="+rule.getUwLotteryNum());
+                Result<String> stringResult = localLivingClient.generateQrcode(qparam);
+                if(stringResult.isSuccess() && !stringResult.getResult().isEmpty()){
+
+                    MessageAddParam param = new MessageAddParam();
+                    param.setTitle("抽奖次数下发通知消息");
+                    param.setContent("{\"qrcode\":\"" + LocalLivingUrl+stringResult.getResult() + "\",\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"投保客户投保已获取奖励,点击为客户发放奖励\"}");
+                    param.setTplCode("template_14");
+                    param.setReceive(List.of(quoteUserId));
+                    orgClient.messageAdd(param);
+                }
             }
         }
     }
@@ -977,20 +1108,20 @@ public class UnifyOrderManager {
      * 1. 未绑定:统计出单次数,满足条件则存本地记录
      * 2. 已绑定:远程同步抽奖次数,成功后标记已同步
      */
-    private void handleOrderRule(String tenantId, String userId,
-                                  LotteryActivityVO activity, LocalActivityTableVO table) {
+    private void handleOrderRule(String tenantId, String userId, String quoteUserId,
+                                  LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
         // 只处理本租户的出单规则
         if (!tenantId.equals(table.getTenantId())) {
             return;
         }
 
-        HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId, tenantId);
+        HttpResult<UnifiedUserClientVO> bindResult = queryUserBind(userId,quoteUserId, tenantId);
         if (bindResult == null || bindResult.getCode() != 200 || bindResult.getData() == null) {
             // 未绑定:统计出单次数,满足条件则存本地记录
-            handleUnboundOrderRule(tenantId, userId, activity, table);
+            handleUnboundOrderRule(tenantId, quoteUserId, activity, table);
         } else {
             // 已绑定:远程同步抽奖次数
-            handleBoundOrderRule(tenantId, userId, activity, table, bindResult.getData());
+            handleBoundOrderRule(tenantId, quoteUserId, activity, table, bindResult.getData());
         }
     }
 
@@ -998,17 +1129,28 @@ public class UnifyOrderManager {
      * 处理未绑定用户的出单规则
      */
     private void handleUnboundOrderRule(String tenantId, String userId,
-                                         LotteryActivityVO activity, LocalActivityTableVO table) {
+                                         LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table) {
         int count = insOrdersService.countOrderNum(tenantId, userId,
                 activity.getActivityStartTime(), activity.getActivityEndTime());
-        for (OrderRuleVO orderRule : table.getOrderRules()) {
+        for (LocalLivingActivityTableVO.OrderRule orderRule : table.getOrderRules()) {
             if (count >= Integer.parseInt(orderRule.getOrdNum())) {
-                completeRule(tenantId, userId, null, activity.getId(),
+                boolean inserted = completeRule(tenantId, userId, null, activity.getId(),
                         table.getId(), orderRule.getOrdNum(),
                         String.valueOf(orderRule.getOrdLotteryNum()), null,
                         YesNoEnum.NO.getCode(), 8);
+                if(!inserted){
+                    break;
+                }
                 log.info("业务员出单,满足条件插入记录,userId:{},clientId:{},tenantId:{}",
                         userId, CLIENT_ID, tenantId);
+
+                MessageAddParam param = new MessageAddParam();
+                param.setTitle("抽奖次数下发通知消息");
+                param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
+                param.setTplCode("template_13");
+                param.setReceive(List.of(userId));
+                orgClient.messageAdd(param);
+
             }
         }
     }
@@ -1017,7 +1159,7 @@ public class UnifyOrderManager {
      * 处理已绑定用户的出单规则:先判断是否满足规则条件,满足后再远程同步抽奖次数并标记已同步
      */
     private void handleBoundOrderRule(String tenantId, String userId,
-                                       LotteryActivityVO activity, LocalActivityTableVO table,
+                                       LocalLivingLotteryActivityVO activity, LocalLivingActivityTableVO table,
                                        UnifiedUserClientVO bindData) {
         Map<String, List<UnifiedUserClientVO>> clientGroupMap = bindData.getUserClients()
                 .stream()
@@ -1030,12 +1172,22 @@ public class UnifyOrderManager {
         int count = insOrdersService.countOrderNum(tenantId, userId,
                 activity.getActivityStartTime(), activity.getActivityEndTime());
         boolean anyMatch = false;
-        for (OrderRuleVO orderRule : table.getOrderRules()) {
+        boolean instare = false;
+        for (LocalLivingActivityTableVO.OrderRule orderRule : table.getOrderRules()) {
             if (count >= Integer.parseInt(orderRule.getOrdNum())) {
                 anyMatch = true;
+                instare = completeRule(tenantId, userId, null, activity.getId(),
+                        table.getId(), table.getQutNum(), table.getQutLotteryNum(),
+                        table.getQutLotteryMax(), YesNoEnum.YES.getCode(), 8);
+                log.info("业务员出单,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{}",
+                        userId, CLIENT_ID, tenantId);
                 break;
             }
         }
+        // 已完成的出单任务不走奖励
+        if(!instare){
+            return;
+        }
         if (!anyMatch) {
             return;
         }
@@ -1055,17 +1207,13 @@ public class UnifyOrderManager {
                     userId, table.getQutLotteryNum(), tenantId);
             log.error("业务员出单,远程调用本地生活抽奖次数增加异常", e);
         }
-
         if (lotteryResult != null && lotteryResult.getData().getSuccess()) {
-            for (OrderRuleVO orderRule : table.getOrderRules()) {
-                if (count >= Integer.parseInt(orderRule.getOrdNum())) {
-                    completeRule(tenantId, userId, null, activity.getId(),
-                            table.getId(), table.getQutNum(), table.getQutLotteryNum(),
-                            table.getQutLotteryMax(), YesNoEnum.YES.getCode(), 8);
-                    log.info("业务员出单,满足条件插入记录并远程同步,userId:{},clientId:{},tenantId:{}",
-                            userId, CLIENT_ID, tenantId);
-                }
-            }
+            MessageAddParam param = new MessageAddParam();
+            param.setTitle("抽奖次数下发通知消息");
+            param.setContent("{\"eventId\":\"" + activity.getId() + "\",\"localActivityTableId\":\"" + table.getId() + "\",\"message\":\"抽奖次数奖励下发\"}");
+            param.setTplCode("template_13");
+            param.setReceive(List.of(userId));
+            orgClient.messageAdd(param);
         }
     }
     //return HttpResult.ok("状态刷新成功");

+ 2 - 2
tenant/insurance/quotation-summary/src/main/java/com/jzg/quotation/summary/mapper/InsOrdersMapper.java

@@ -177,14 +177,14 @@ public interface InsOrdersMapper extends BaseMapper<InsOrders> {
     int countOrderNum(String systemCode, String realQuoteUserId, LocalDate activityStartTime, LocalDate activityEndTime);
     /**
      * 查询营销活动规则表中符合的规则记录
-     * @param tenantId
+     * @param systemCode
      * @param userId
      * @param activityId
      * @param qutNum
      * @param activityType
      * @return
      */
-    SysUserActivityCompleteInRule selectByRule(String tenantId, String userId, String activityId, String qutNum, Integer activityType);
+    SysUserActivityCompleteInRule selectByRule(@Param("systemCode") String systemCode, @Param("userId") String userId, @Param("activityId")String activityId, @Param("qutNum")String qutNum, @Param("activityType")Integer activityType);
     /**
      * 添加营销活动规则表中的符合规则记录
      * @param record

+ 4 - 4
tenant/insurance/quotation-summary/src/main/resources/mapper/InsOrdersMapper.xml

@@ -1609,12 +1609,12 @@
           AND io.create_time &gt;= CONCAT(#{activityStartTime},' 00:00:00')
           AND io.create_time &lt;= CONCAT(#{activityEndTime},' 23:59:59')
     </select>
-    <select id="selectByRule" resultType="com.jzg.commons.entity.po.SysUserActivityCompleteInRule">
+    <select id="selectByRule" resultType="com.jzg.commons.entity.po.SysUserActivityCompleteInRule" >
         SELECT *
         FROM sys_user_activity_complete_in_rule
         <where>
             and is_delete = 0
-            and tenant_id = #{tenantId}
+            and system_code = #{systemCode}
             and user_id = #{userId}
             and activity_id = #{activityId}
             and activity_type = #{activityType}
@@ -1639,7 +1639,7 @@
     <insert id="insertActivityCompleteInRule" parameterType="com.jzg.commons.entity.po.SysUserActivityCompleteInRule">
         INSERT INTO sys_user_activity_complete_in_rule (
             id,
-            tenant_id,
+            system_code,
             user_id,
             activity_type,
             activity_id,
@@ -1656,7 +1656,7 @@
             is_delete
         ) VALUES (
                      #{id},
-                     #{tenantId},
+                     #{systemCode},
                      #{userId},
                      #{activityType},
                      #{activityId},