Просмотр исходного кода

1、看课记录调整迁移
2、积分购调整迁移

yfh 1 месяц назад
Родитель
Сommit
8bdcfa513f

+ 6 - 7
fs-admin/src/main/java/com/fs/his/controller/FsIntegralGoodsController.java

@@ -10,7 +10,6 @@ import com.fs.his.domain.FsIntegralGoods;
 import com.fs.his.service.IFsIntegralGoodsService;
 import com.fs.his.utils.RedisCacheUtil;
 import com.fs.his.vo.FsIntegralGoodsListVO;
-import com.fs.his.vo.FsStoreProductExcelVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -35,7 +34,7 @@ public class FsIntegralGoodsController extends BaseController
     /**
      * 查询积分商品列表
      */
-    @PreAuthorize("@ss.hasPermi('his:integralGoods:list')")
+//    @PreAuthorize("@ss.hasPermi('his:integralGoods:list')")
     @GetMapping("/list")
     public TableDataInfo list(FsIntegralGoods fsIntegralGoods)
     {
@@ -47,7 +46,7 @@ public class FsIntegralGoodsController extends BaseController
     /**
      * 导出积分商品列表
      */
-    @PreAuthorize("@ss.hasPermi('his:integralGoods:export')")
+//    @PreAuthorize("@ss.hasPermi('his:integralGoods:export')")
     @Log(title = "积分商品", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
     public AjaxResult export(FsIntegralGoods fsIntegralGoods)
@@ -60,7 +59,7 @@ public class FsIntegralGoodsController extends BaseController
     /**
      * 获取积分商品详细信息
      */
-    @PreAuthorize("@ss.hasPermi('his:integralGoods:query')")
+//    @PreAuthorize("@ss.hasPermi('his:integralGoods:query')")
     @GetMapping(value = "/{goodsId}")
     public AjaxResult getInfo(@PathVariable("goodsId") Long goodsId)
     {
@@ -91,7 +90,7 @@ public class FsIntegralGoodsController extends BaseController
     /**
      * 新增积分商品
      */
-    @PreAuthorize("@ss.hasPermi('his:integralGoods:add')")
+//    @PreAuthorize("@ss.hasPermi('his:integralGoods:add')")
     @Log(title = "积分商品", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@RequestBody FsIntegralGoods fsIntegralGoods)
@@ -104,7 +103,7 @@ public class FsIntegralGoodsController extends BaseController
     /**
      * 修改积分商品
      */
-    @PreAuthorize("@ss.hasPermi('his:integralGoods:edit')")
+//    @PreAuthorize("@ss.hasPermi('his:integralGoods:edit')")
     @Log(title = "积分商品", businessType = BusinessType.UPDATE)
     @PutMapping
     public AjaxResult edit(@RequestBody FsIntegralGoods fsIntegralGoods)
@@ -118,7 +117,7 @@ public class FsIntegralGoodsController extends BaseController
     /**
      * 删除积分商品
      */
-    @PreAuthorize("@ss.hasPermi('his:integralGoods:remove')")
+//    @PreAuthorize("@ss.hasPermi('his:integralGoods:remove')")
     @Log(title = "积分商品", businessType = BusinessType.DELETE)
 	@DeleteMapping("/{goodsIds}")
     public AjaxResult remove(@PathVariable Long[] goodsIds)

+ 24 - 31
fs-admin/src/main/java/com/fs/his/controller/FsIntegralOrderController.java

@@ -1,6 +1,9 @@
 package com.fs.his.controller;
 
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
@@ -10,21 +13,25 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.his.domain.FsIntegralGoods;
 import com.fs.his.domain.FsIntegralOrder;
-import com.fs.his.domain.FsStoreOrder;
 import com.fs.his.dto.ExpressInfoDTO;
 import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.mapper.FsIntegralGoodsMapper;
+import com.fs.his.param.FsIntegralOrderCreateParam;
 import com.fs.his.param.FsIntegralOrderParam;
 import com.fs.his.service.IFsExpressService;
 import com.fs.his.service.IFsIntegralOrderService;
 import com.fs.his.utils.PhoneUtil;
-import com.fs.his.vo.*;
+import com.fs.his.vo.FsIntegralOrderListVO;
+import com.fs.his.vo.FsIntegralOrderPVO;
+import com.fs.his.vo.FsStoreProductDeliverExcelVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.util.List;
+import java.util.*;
 
 import static com.fs.his.utils.PhoneUtil.decryptAutoPhoneMk;
 import static com.fs.his.utils.PhoneUtil.decryptPhone;
@@ -36,13 +43,16 @@ import static com.fs.his.utils.PhoneUtil.decryptPhone;
  * @date 2023-11-02
  */
 @RestController
-@RequestMapping("store/his/integralOrder")
+@RequestMapping("/his/integralOrder")
 public class FsIntegralOrderController extends BaseController
 {
     @Autowired
     private IFsIntegralOrderService fsIntegralOrderService;
     @Autowired
     private IFsExpressService expressService;
+
+    @Autowired
+    private FsIntegralGoodsMapper fsIntegralGoodsMapper;
     /**
      * 查询积分商品订单列表
      */
@@ -64,30 +74,13 @@ public class FsIntegralOrderController extends BaseController
     @PreAuthorize("@ss.hasPermi('his:integralOrder:export')")
     @Log(title = "积分商品订单", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
-    public AjaxResult export(FsIntegralOrder fsIntegralOrder)
-    {
-        List<FsIntegralOrder> list = fsIntegralOrderService.selectFsIntegralOrderList(fsIntegralOrder);
-        for (FsIntegralOrder vo : list) {
-            //商品名称以及原价赋值
-            String itemJson = vo.getItemJson();
-            if(StringUtils.isNotBlank(itemJson)){
-                JSONObject jsonObject = JSONObject.parseObject(itemJson);
-                vo.setGoodsName(jsonObject.getString("goodsName"));
-                vo.setOtPrice(jsonObject.getBigDecimal("otPrice"));
-            }
-            if (vo.getUserPhone()!=null&&!vo.getUserPhone().equals("")){
-                if(vo.getUserPhone().chars().allMatch(Character::isDigit)){continue;}
-//                vo.setUserPhone(vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
-                vo.setUserPhone(PhoneUtil.decryptPhone(vo.getUserPhone()));
-            }
-        }
-        ExcelUtil<FsIntegralOrder> util = new ExcelUtil<FsIntegralOrder>(FsIntegralOrder.class);
-        return util.exportExcel(list, "积分商品订单数据");
+    public AjaxResult export(FsIntegralOrder fsIntegralOrder) {
+        return fsIntegralOrderService.export(fsIntegralOrder);
     }
     /**
      * 发货
      */
-    @PreAuthorize("@ss.hasPermi('his:integralOrder:sendGoods')")
+//    @PreAuthorize("@ss.hasPermi('his:integralOrder:sendGoods')")
     @PutMapping("/sendGoods")
     public AjaxResult sendGoods(@RequestBody FsIntegralOrder fsIntegralOrder)
     {
@@ -109,7 +102,7 @@ public class FsIntegralOrderController extends BaseController
         String message = fsIntegralOrderService.importProductDeliver(list);
         return AjaxResult.success(message);
     }
-    @PreAuthorize("@ss.hasPermi('his:integralOrder:express')")
+//    @PreAuthorize("@ss.hasPermi('his:integralOrder:express')")
     @GetMapping(value = "/getExpress/{id}")
     public R getExpress(@PathVariable("id") Long id)
     {
@@ -131,7 +124,7 @@ public class FsIntegralOrderController extends BaseController
     /**
      * 获取积分商品订单详细信息
      */
-    @PreAuthorize("@ss.hasPermi('his:integralOrder:query')")
+//    @PreAuthorize("@ss.hasPermi('his:integralOrder:query')")
     @GetMapping(value = "/{orderId}")
     public AjaxResult getInfo(@PathVariable("orderId") Long orderId)
     {
@@ -157,18 +150,18 @@ public class FsIntegralOrderController extends BaseController
     /**
      * 新增积分商品订单
      */
-    @PreAuthorize("@ss.hasPermi('his:integralOrder:add')")
+//    @PreAuthorize("@ss.hasPermi('his:integralOrder:add')")
     @Log(title = "积分商品订单", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody FsIntegralOrder fsIntegralOrder)
+    public R add(@RequestBody FsIntegralOrderCreateParam param)
     {
-        return toAjax(fsIntegralOrderService.insertFsIntegralOrder(fsIntegralOrder));
+        return fsIntegralOrderService.createOrder(param);
     }
 
     /**
      * 修改积分商品订单
      */
-    @PreAuthorize("@ss.hasPermi('his:integralOrder:edit')")
+//    @PreAuthorize("@ss.hasPermi('his:integralOrder:edit')")
     @Log(title = "积分商品订单", businessType = BusinessType.UPDATE)
     @PutMapping
     public AjaxResult edit(@RequestBody FsIntegralOrder fsIntegralOrder)
@@ -179,7 +172,7 @@ public class FsIntegralOrderController extends BaseController
     /**
      * 删除积分商品订单
      */
-    @PreAuthorize("@ss.hasPermi('his:integralOrder:remove')")
+//    @PreAuthorize("@ss.hasPermi('his:integralOrder:remove')")
     @Log(title = "积分商品订单", businessType = BusinessType.DELETE)
 	@DeleteMapping("/{orderIds}")
     public AjaxResult remove(@PathVariable Long[] orderIds)

+ 2 - 2
fs-service/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java

@@ -120,8 +120,8 @@ public interface FsCourseAnswerLogsMapper
             "</script>"})
     int selectErrorCountByCourseVideo(@Param("videoId") Long videoId,@Param("userId") Long userId,@Param("qwUserId") String qwUserId);
 
-    @Select("select count(log_id) from fs_course_red_packet_log where user_id = #{userId} and video_id = #{videoId}")
-    Long selectRedStatus(@Param("userId") Long userId, @Param("videoId") Long videoId);
+    @Select("select count(log_id) from fs_course_red_packet_log where user_id = #{userId} and video_id = #{videoId} and period_id = #{periodId}")
+    Long selectRedStatus(@Param("userId") Long userId, @Param("videoId") Long videoId, @Param("periodId") Long periodId);
 
     List<FsCourseAnswerLogsListVO> selectFsCourseAnswerLogsListVONew(FsCourseAnswerLogsParam param);
 

+ 0 - 2
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -2,7 +2,6 @@ package com.fs.course.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.course.domain.FsCourseWatchLog;
-import com.fs.course.domain.FsUserCourseVideo;
 import com.fs.course.dto.WatchLogDTO;
 import com.fs.course.param.*;
 import com.fs.course.vo.*;
@@ -12,7 +11,6 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
-import javax.validation.constraints.NotNull;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;

+ 1 - 1
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java

@@ -540,7 +540,7 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
             recordVO.setWatchLxCount(lxDay);
 
             // 领取状态
-            Long count = fsCourseAnswerLogsMapper.selectRedStatus(recordVO.getUserId(), recordVO.getVideoId());
+            Long count = fsCourseAnswerLogsMapper.selectRedStatus(recordVO.getUserId(), recordVO.getVideoId(), (Long) params.get("periodId"));
             if (Objects.nonNull(count) && count > 0) {
                 recordVO.setRedStatus(1);
             } else {

+ 74 - 165
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -89,6 +89,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -115,27 +116,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     private Boolean isNewWxMerchant;
     private static final Logger logger = LoggerFactory.getLogger(FsUserCourseVideoServiceImpl.class);
 
-    /**
-     * 红包账户锁
-     */
-    private static final String REDPACKET_POOL_LOCK = "redpacket_pool_lock";
-
-    /**
-     * 公司红包金额
-     */
-    private static final String REDPACKET_COMPANY_MONEY = "redpacket_money";
-
-    /**
-     * 红包改变记录
-     */
-    private static final String REDPACKET_COMPANY_MONEY_CHANGE = "redpacket_money_change";
-
-    /**
-     * 是否开启红包账户扣减
-     */
-    @Value("${enableRedPackAccount:0}")
-    private String ENABLE_RED_PACK_ACCOUNT;
-
     private static final String miniappRealLink = "/pages_course/video.html?course=";
     private static final String REAL_LINK_PREFIX = "/courseH5/pages/course/learning?course=";
     private static final String SHORT_LINK_PREFIX = "/courseH5/pages/course/learning?s=";
@@ -252,8 +232,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     @Autowired
     ConfigUtil configUtil;
 
-    @Autowired
-    private RedisTemplate<String,BigDecimal> redisTemplate;
 
 
     /**
@@ -1024,6 +1002,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if (log == null) {
             return R.error("无记录");
         }
+        if (log.getLogType() != 2) {
+            return R.error("未完课");
+        }
         if (log.getRewardType() != null) {
             FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
             if(packetLog != null && packetLog.getStatus() == 1) {
@@ -1159,23 +1140,46 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         // 准备发送红包参数
         WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
-        packetParam.setOpenId(user.getMpOpenId());
-        // 来源是小程序切换openId
-        if (param.getSource() == 2) {
-            //处理多小程序问题
+
+        if (user.getMpOpenId()!=null&&!isNewWxMerchant){
+            packetParam.setOpenId(user.getMpOpenId());
+        }else {
+            //修复数据
             FsUserWx fsUserWx = fsUserWxService.selectByAppIdAndUserId(param.getAppId(),user.getUserId(),1);
             if (fsUserWx ==null){
+                if (user.getCourseMaOpenId()==null){
+                    logger.error(" 【转账openId参数错误】:{}", user.getUserId());
+                    return R.error("openId参数错误,请清理缓存后重新授权!");
+                }
+                packetParam.setOpenId(user.getCourseMaOpenId());
                 try {
                     handleFsUserWx(user,param.getAppId());
                 }catch (Exception e){
-                    logger.error("【更新或插入用户与小程序的绑定关系失败】:{}", user.getUserId());
+                    logger.error(" 【更新或插入用户与小程序的绑定关系失败】:{}", user.getUserId(),e);
                 }
+
             }else {
                 packetParam.setOpenId(fsUserWx.getOpenId());
             }
-            //查出公司绑定openid并赋值
         }
 
+//        packetParam.setOpenId(user.getMpOpenId());
+//        // 来源是小程序切换openId
+//        if (param.getSource() == 2) {
+//            //处理多小程序问题
+//            FsUserWx fsUserWx = fsUserWxService.selectByAppIdAndUserId(param.getAppId(),user.getUserId(),1);
+//            if (fsUserWx ==null){
+//                try {
+//                    handleFsUserWx(user,param.getAppId());
+//                }catch (Exception e){
+//                    logger.error("【更新或插入用户与小程序的绑定关系失败】:{}", user.getUserId());
+//                }
+//            }else {
+//                packetParam.setOpenId(fsUserWx.getOpenId());
+//            }
+//            //查出公司绑定openid并赋值
+//        }
+
         //判断服务号配置是否存在
         if (StringUtils.isNotEmpty(config.getMpAppId())){
             packetParam.setMpAppId(config.getMpAppId());
@@ -1190,28 +1194,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         logger.info("红包金额 {},红包商户号 {}",amount,packetParam);
         //2025.6.19 红包金额为0的时候
         if (amount.compareTo(BigDecimal.ZERO)>0){
-
-            //---------------发红包前先判断润天账户余额是否足够---------
-            RLock lock = redissonClient.getLock(REDPACKET_POOL_LOCK);
-            try{
-                boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
-
-                if (!locked) {
-                    logger.error("获取锁失败");
-                    return R.error("[红包领取] 系统繁忙,请重试!");
-                }
-
-                // 发送红包
-                return sendRedPacketRewardToUser(param, log, config, packetParam, amount);
-
-            }catch (Exception e){
-                logger.error("领取红包失败原因:{}", ExceptionUtils.getFullStackTrace(e),e);
-                throw new RuntimeException(e);
-            }finally {
-                if (lock.isHeldByCurrentThread()) {
-                    lock.unlock();
-                }
-            }
+            // 发送红包
+            return sendRedPacketRewardToUser(param, log, config, packetParam, amount);
         } else {
             FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
             // 添加红包记录
@@ -1239,25 +1223,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     private R sendRedPacketRewardToUser(FsCourseSendRewardUParam param, FsCourseWatchLog log, CourseConfig config, WxSendRedPacketParam packetParam, BigDecimal amount) {
 
-        BigDecimal companyMoney = null;
-        if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-            companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
-
-            if(ObjectUtils.isNull(companyMoney)){
-                SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("company.money");
-                if(ObjectUtils.isNull(sysConfig)){
-                    throw new IllegalArgumentException("润天公司账户余额不能为空!请检查配置!");
-                }
-                String configValue = sysConfig.getConfigValue();
-                companyMoney = new BigDecimal(configValue);
-                logger.info("缓存公司余额为空,从数据库读取 companyMoney: {}",companyMoney);
-            }
-
-            if (companyMoney.compareTo(BigDecimal.ZERO) <= 0) {
-                logger.info("润天账户余额: {} 不足!", companyMoney);
-                return R.error("[红包领取] 账户余额不足,请联系管理员!");
-            }
-        }
 
         // 发送红包
         R sendRedPacket = paymentService.sendRedPacket(packetParam);
@@ -1283,23 +1248,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             redPacketLog.setAmount(amount);
             redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
             redPacketLog.setPeriodId(param.getPeriodId());
-            if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                redPacketLog.setAccBalanceBefore(companyMoney);
-                redPacketLog.setAccBalanceAfter(companyMoney.subtract(amount));
-            }
 
             redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
             // 更新观看记录的奖励类型
             log.setRewardType(config.getRewardType());
             courseWatchLogMapper.updateFsCourseWatchLog(log);
 
-            if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                // 更新账户余额
-                logger.info("[更新账户余额] 当前余额{} 更新后余额{}",companyMoney.toPlainString(),companyMoney.subtract(amount).toPlainString());
-
-                companyMoney = companyMoney.subtract(amount);
-                redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
-            }
             return sendRedPacket;
         } else {
             return R.error("奖励发送失败,请联系客服");
@@ -1307,6 +1261,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
 
+
+
     private void handleFsUserWx(FsUser user, String appId) {
         FsUserWx fsUserWx = new FsUserWx();
         fsUserWx.setType(1);
@@ -1411,92 +1367,43 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 return R.error("服务商余额不足,请联系群主服务器充值!");
             }
 
-            //---------------发红包前先判断润天账户余额是否足够---------
-            RLock lock = redissonClient.getLock(REDPACKET_POOL_LOCK);
-            try{
-                boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
-
-                if (!locked) {
-                    logger.error("获取锁失败");
-                    return R.error("[红包领取] 系统繁忙,请重试!");
-                }
-
-                BigDecimal companyMoney = null;
-                if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                    companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
-                    if(ObjectUtils.isNull(companyMoney)){
-                        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("company.money");
-                        if(ObjectUtils.isNull(sysConfig)){
-                            throw new IllegalArgumentException("润天公司账户余额不能为空!请检查配置!");
-                        }
-                        String configValue = sysConfig.getConfigValue();
-                        companyMoney = new BigDecimal(configValue);
-                        logger.info("缓存公司余额为空,从数据库读取 companyMoney: {}",companyMoney);
-                    }
-
-                    if (companyMoney.compareTo(BigDecimal.ZERO) <= 0) {
-                        logger.info("润天账户余额: {} 不足!", companyMoney);
-                        return R.error("[红包领取] 账户余额不足,请联系管理员!");
-                    }
-                }
-                // 发送红包
-                R sendRedPacket = paymentService.sendRedPacket(packetParam);
-                if (sendRedPacket.get("code").equals(200)) {
-                    FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
-                    TransferBillsResult transferBillsResult;
-                    if (sendRedPacket.get("isNew").equals(1)){
-                        transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
-                        redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
-                        redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
-                    }else {
-                        redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
-                        redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());
-                    }
-                    // 添加红包记录
-                    redPacketLog.setCourseId(param.getCourseId());
-                    redPacketLog.setCompanyId(param.getCompanyId());
-                    redPacketLog.setUserId(param.getUserId());
-                    redPacketLog.setVideoId(param.getVideoId());
-                    redPacketLog.setStatus(0);
-                    redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null);
-                    redPacketLog.setCompanyUserId(param.getCompanyUserId());
-                    redPacketLog.setCreateTime(new Date());
-                    redPacketLog.setAmount(amount);
-                    redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
-                    redPacketLog.setPeriodId(param.getPeriodId());
-                    redPacketLog.setAppId(param.getAppId());
-                    if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                        redPacketLog.setAccBalanceBefore(companyMoney);
-                        redPacketLog.setAccBalanceAfter(companyMoney.subtract(amount));
-                    }
-                    redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
-
-                    // 更新观看记录的奖励类型
-                    log.setRewardType(config.getRewardType());
-                    courseWatchLogMapper.updateFsCourseWatchLog(log);
-
-
-                    if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
-                        // 更新账户余额
-                        logger.info("[更新账户余额] 当前余额{} 更新后余额{}",companyMoney.toPlainString(),companyMoney.subtract(amount).toPlainString());
-
-                        companyMoney = companyMoney.subtract(amount);
-                        redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
-                    }
-
-                    return sendRedPacket;
-                } else {
-                    return R.error("奖励发送失败,请联系客服");
-                }
-            }catch (Exception e){
-                logger.error("领取红包失败原因:{}", ExceptionUtils.getFullStackTrace(e),e);
-                throw new RuntimeException(e);
-            }finally {
-                if (lock.isHeldByCurrentThread()) {
-                    lock.unlock();
+            // 发送红包
+            R sendRedPacket = paymentService.sendRedPacket(packetParam);
+            if (sendRedPacket.get("code").equals(200)) {
+                FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
+                TransferBillsResult transferBillsResult;
+                if (sendRedPacket.get("isNew").equals(1)){
+                    transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
+                    redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
+                    redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
+                }else {
+                    redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+                    redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());
                 }
+                // 添加红包记录
+                redPacketLog.setCourseId(param.getCourseId());
+                redPacketLog.setCompanyId(param.getCompanyId());
+                redPacketLog.setUserId(param.getUserId());
+                redPacketLog.setVideoId(param.getVideoId());
+                redPacketLog.setStatus(0);
+                redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null);
+                redPacketLog.setCompanyUserId(param.getCompanyUserId());
+                redPacketLog.setCreateTime(new Date());
+                redPacketLog.setAmount(amount);
+                redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
+                redPacketLog.setPeriodId(param.getPeriodId());
+                redPacketLog.setAppId(param.getAppId());
+
+                redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+
+                // 更新观看记录的奖励类型
+                log.setRewardType(config.getRewardType());
+                courseWatchLogMapper.updateFsCourseWatchLog(log);
+
+                return sendRedPacket;
+            } else {
+                return R.error("奖励发送失败,请联系客服");
             }
-
         } else {
             FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
             // 添加红包记录
@@ -1654,6 +1561,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         redPacketLog.setAmount(BigDecimal.valueOf(config.getAnswerIntegral()).divide(BigDecimal.valueOf(1000)));
         redPacketLog.setRemark("点播答题领取积分转");
         redPacketLog.setWatchLogId(log.getLogId() !=null ? log.getLogId() : null);
+        redPacketLog.setPeriodId(param.getPeriodId());
         redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
         return R.ok("奖励发放成功").put("rewardType",config.getRewardType());
     }
@@ -2856,3 +2764,4 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
 }
+

+ 1 - 1
fs-service/src/main/java/com/fs/his/mapper/FsIntegralGoodsMapper.java

@@ -66,7 +66,7 @@ public interface FsIntegralGoodsMapper
      */
     public int deleteFsIntegralGoodsByGoodsIds(Long[] goodsIds);
 
-    @Select({"<script> select goods_id, img_url, images, goods_name, ot_price, goods_type, status, integral, cash, sort, stock, descs, create_time from fs_integral_goods" +
+    @Select({"<script> select goods_id,bar_code, img_url, images, goods_name, ot_price, goods_type, status, integral, cash, sort, stock, descs, create_time from fs_integral_goods" +
             "<where>  \n" +
             "            <if test=\"goodsName != null  and goodsName != ''\"> and goods_name like concat('%', #{goodsName}, '%')</if>\n" +
             "            <if test=\"goodsType != null \"> and goods_type = #{goodsType}</if>\n" +

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsIntegralOrderCreateParam.java

@@ -13,6 +13,7 @@ public class FsIntegralOrderCreateParam {
     private Long addressId;
 
     private Long goodsId;
+    private Long companyUserId;
 
 
 }

+ 3 - 0
fs-service/src/main/java/com/fs/his/service/IFsIntegralOrderService.java

@@ -1,5 +1,6 @@
 package com.fs.his.service;
 
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsIntegralOrder;
 import com.fs.his.enums.PaymentMethodEnum;
@@ -100,4 +101,6 @@ public interface IFsIntegralOrderService
      * 支付回调
      */
     R payConfirm(String orderSn, String payCode, String tradeNo, String payType, int type,String bankTransactionId,String bankSerialNo);
+
+    AjaxResult export(FsIntegralOrder fsIntegralOrder);
 }

+ 103 - 4
fs-service/src/main/java/com/fs/his/service/impl/FsIntegralOrderServiceImpl.java

@@ -2,6 +2,7 @@ package com.fs.his.service.impl;
 
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.lang.TypeReference;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
@@ -9,12 +10,16 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.constant.FsConstants;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.his.domain.*;
 import com.fs.his.enums.BusinessTypeEnum;
@@ -26,6 +31,7 @@ import com.fs.his.service.IFsIntegralCartService;
 import com.fs.his.service.IFsIntegralOrderService;
 import com.fs.his.service.IFsStorePaymentService;
 import com.fs.his.service.IFsUserIntegralLogsService;
+import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.FsIntegralOrderListUVO;
 import com.fs.his.vo.FsIntegralOrderListVO;
 import com.fs.his.vo.FsIntegralOrderPVO;
@@ -37,6 +43,8 @@ import com.fs.ybPay.domain.OrderResult;
 import com.fs.ybPay.dto.OrderQueryDTO;
 import com.fs.ybPay.service.IPayService;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -73,6 +81,9 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
 
     @Autowired
     private QwUserMapper qwUserMapper;
+
+    @Autowired
+    private CompanyUserMapper companyUserMapper;
     @Autowired
     private IFsUserIntegralLogsService userIntegralLogsService;
     @Autowired
@@ -223,15 +234,20 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         goodsItem.add(integralGoods);
 
         // 创建订单
-        return createOrder(user, address, integralGoods.getIntegral(),integralGoods.getCash(), goodsItem);
+        return createOrder(user, address, integralGoods.getIntegral(),integralGoods.getCash(), goodsItem,param.getCompanyUserId());
     }
 
     /**
      * 创建订单
      */
-    private R createOrder(FsUser user, FsUserAddress address, Long totalIntegral, BigDecimal totalCash, List<FsIntegralGoods> goodsItem) {
+    private R createOrder(FsUser user, FsUserAddress address, Long totalIntegral, BigDecimal totalCash, List<FsIntegralGoods> goodsItem, Long companyUserId) {
         FsIntegralOrder order = new FsIntegralOrder();
-        String orderSn = OrderCodeUtils.getOrderSn();
+        String orderSn = null;
+        try{
+            orderSn = OrderCodeUtils.getOrderSn();
+        }catch (Exception e){
+            orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
+        }
         if(StringUtils.isEmpty(orderSn)){
             throw new CustomException("订单生成失败,请重试");
         }
@@ -261,6 +277,11 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         order.setUserAddress(address.getProvince()+address.getCity()+address.getDistrict()+address.getDetail());
         order.setUserPhone(address.getPhone());
         order.setCreateTime(new Date());
+        order.setCompanyUserId(companyUserId);
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserByCompanyUserId(companyUserId);
+        if (ObjectUtil.isNotEmpty(companyUser)){
+            order.setCompanyId(companyUser.getCompanyId());
+        }
 
         //判断当前用户是否有关联企微ID
         if(ObjectUtil.isNotNull(user.getQwUserId())){
@@ -364,7 +385,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             goodsItem.add(integralGoods);
         }
 
-        return createOrder(user, address, totalIntegral, totalCash, goodsItem);
+        return createOrder(user, address, totalIntegral, totalCash, goodsItem, null);
     }
 
     @Override
@@ -579,4 +600,82 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         return R.ok();
     }
 
+    @Override
+    public AjaxResult export(FsIntegralOrder fsIntegralOrder) {
+        List<FsIntegralOrder> list = fsIntegralOrderMapper.selectFsIntegralOrderList(fsIntegralOrder);
+
+        // 使用Set避免重复数据
+        Set<FsIntegralOrder> fsIntegralOrderSet = new LinkedHashSet<>();
+
+        for (FsIntegralOrder order : list) {
+            // 处理手机号脱敏
+            processPhoneNumber(order);
+
+            // 处理商品信息
+            processGoodsInfo(order, fsIntegralOrderSet);
+        }
+
+        ExcelUtil<FsIntegralOrder> util = new ExcelUtil<>(FsIntegralOrder.class);
+        return util.exportExcel(new ArrayList<>(fsIntegralOrderSet), "积分商品订单数据");
+    }
+
+    /**
+     * 处理手机号脱敏
+     */
+    private void processPhoneNumber(FsIntegralOrder order) {
+        String userPhone = order.getUserPhone();
+        if (StringUtils.isNotBlank(userPhone) && !userPhone.chars().allMatch(Character::isDigit)) {
+            order.setUserPhone(PhoneUtil.decryptPhone(userPhone));
+        }
+    }
+
+    /**
+     * 处理商品信息
+     */
+    private void processGoodsInfo(FsIntegralOrder order, Set<FsIntegralOrder> resultSet) {
+        String itemJson = order.getItemJson();
+        if (StringUtils.isBlank(itemJson)) {
+            return;
+        }
+
+        try {
+            // 判断是否为数组格式
+            if (itemJson.startsWith("[") && itemJson.endsWith("]")) {
+                // 数组格式 - 多个商品
+                List<FsIntegralGoods> goodsList = JSONUtil.toBean(itemJson,
+                        new TypeReference<List<FsIntegralGoods>>(){}, true);
+
+                for (FsIntegralGoods goods : goodsList) {
+                    if (ObjectUtil.isNotEmpty(goods)) {
+                        FsIntegralOrder newOrder = cloneOrder(order);
+                        newOrder.setGoodsName(goods.getGoodsName());
+                        newOrder.setOtPrice(goods.getOtPrice());
+                        resultSet.add(newOrder);
+                    }
+                }
+            } else {
+                // 单商品格式
+                FsIntegralGoods goods = JSONUtil.toBean(itemJson, FsIntegralGoods.class);
+                if (ObjectUtil.isNotEmpty(goods)) {
+                    order.setGoodsName(goods.getGoodsName());
+                    order.setOtPrice(goods.getOtPrice());
+                    resultSet.add(order);
+                }
+            }
+        } catch (Exception e) {
+            // JSON解析异常处理,可以根据需要记录日志
+            log.warn("解析商品JSON数据失败,orderId: {}, json: {}", order.getOrderId(), itemJson);
+        }
+    }
+
+    /**
+     * 克隆订单对象(用于多商品情况)
+     */
+    private FsIntegralOrder cloneOrder(FsIntegralOrder original) {
+        // 这里需要根据实际情况实现对象的深拷贝或浅拷贝
+        // 以下是简单示例,实际项目中可能需要使用BeanUtils或序列化方式
+        FsIntegralOrder cloned = new FsIntegralOrder();
+        BeanUtils.copyProperties(original, cloned);
+        return cloned;
+    }
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/vo/FsIntegralGoodsListVO.java

@@ -22,6 +22,7 @@ public class FsIntegralGoodsListVO {
     /** 商品名称 */
     @Excel(name = "商品名称")
     private String goodsName;
+    private String barCode;
 
     /** 原价 */
     @Excel(name = "原价")

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsIntegralOrderCreateParam.java

@@ -2,6 +2,7 @@ package com.fs.hisStore.param;
 
 import lombok.Data;
 
+
 @Data
 public class FsIntegralOrderCreateParam {
 
@@ -12,6 +13,7 @@ public class FsIntegralOrderCreateParam {
     private Long addressId;
 
     private Long goodsId;
+    private Long companyUserId;
 
 
 }

+ 1 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -235,6 +235,7 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
             "            <if test=\"userId != null  and userId != ''\"> and ec.user_id   like concat( #{userId}, '%') </if>\n" +
             "            <if test=\"qwUserName != null  and qwUserName != ''\"> and qu.qw_user_name   like concat( #{qwUserName}, '%') </if>\n" +
             "            <if test=\"externalUserId != null  and externalUserId != ''\"> and ec.external_user_id = #{externalUserId}</if>\n" +
+            "            <if test=\"wayId != null  and wayId != ''\"> and  SUBSTRING_INDEX(ec.state, ':', -1) = #{wayId} </if>\n" +
             "            <if test=\"name != null  and name != ''\"> and ec.name like concat( #{name}, '%')</if>\n" +
             "            <if test=\"type != null \"> and ec.type = #{type}</if>\n" +
             "            <if test=\"gender != null \"> and ec.gender = #{gender}</if>\n" +

+ 10 - 1
fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml

@@ -106,7 +106,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         from fs_user_course_video fucv
         inner join fs_course_watch_log fcwl on fcwl.video_id = fucv.video_id
         inner join fs_user fu on fu.user_id = fcwl.user_id
-        where fucv.video_id = #{params.videoId}
+        where fucv.video_id = #{params.videoId} and fcwl.send_type = 1
         <if test="params.keyword != null and params.keyword != ''">
             and (
             fu.user_id = #{params.keyword}
@@ -118,6 +118,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="params.companyUserId != null">
             and fcwl.company_user_id = #{params.companyUserId}
         </if>
+        <if test="params.periodId != null">
+            and fcwl.period_id = #{params.periodId}
+        </if>
         <if test="params.companyId != null">
             and fcwl.company_id = #{params.companyId}
         </if>
@@ -127,11 +130,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 select count(log.log_id) as count
                 from fs_course_answer_logs log
                 where log.user_id = fu.user_id and log.video_id = fucv.video_id and log.is_right = 1
+                <if test="params.periodId != null">
+                    and log.period_id = #{params.periodId}
+                </if>
                 ) > 0
                 and (
                 select count(log.log_id) as count
                 from fs_course_red_packet_log log
                 where log.user_id = fu.user_id and log.video_id = fucv.video_id and log.status = 1
+                <if test="params.periodId != null">
+                    and log.period_id = #{params.periodId}
+                </if>
                 ) > 0
             </when>
             <when test="params.type == 1">