Quellcode durchsuchen

Merge remote-tracking branch 'origin/master'

yjwang vor 1 Woche
Ursprung
Commit
f409836d0f
30 geänderte Dateien mit 236 neuen und 59 gelöschten Zeilen
  1. 2 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserCoursePeriodController.java
  2. 9 0
      fs-admin/src/test/java/com/fs/course/controller/FsCourseDomainNameControllerTest.java
  3. 1 1
      fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java
  4. 36 5
      fs-company/src/main/java/com/fs/company/controller/IndexStatisticsController.java
  5. 2 0
      fs-service-system/src/main/java/com/fs/course/domain/FsCourseRedPacketLog.java
  6. 1 1
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  7. 1 0
      fs-service-system/src/main/java/com/fs/course/param/FsCourseSendRewardUParam.java
  8. 5 0
      fs-service-system/src/main/java/com/fs/course/param/FsCourseTrafficLogParam.java
  9. 3 0
      fs-service-system/src/main/java/com/fs/course/param/PeriodCountParam.java
  10. 7 1
      fs-service-system/src/main/java/com/fs/course/service/IFsCourseRedPacketLogService.java
  11. 2 1
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java
  12. 5 1
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java
  13. 5 2
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  14. 3 1
      fs-service-system/src/main/java/com/fs/his/param/WxSendRedPacketParam.java
  15. 2 2
      fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsCompanyServiceImpl.java
  16. 3 0
      fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java
  17. 3 2
      fs-service-system/src/main/java/com/fs/store/param/FsUserEditParam.java
  18. 5 10
      fs-service-system/src/main/java/com/fs/store/service/impl/FsStorePaymentServiceImpl.java
  19. 6 5
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
  20. 5 0
      fs-service-system/src/main/resources/application-config-zkzh.yml
  21. 5 0
      fs-service-system/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml
  22. 15 2
      fs-service-system/src/main/resources/mapper/course/FsCourseTrafficLogMapper.xml
  23. 1 0
      fs-service-system/src/main/resources/mapper/course/FsUserWatchStatisticsMapper.xml
  24. 12 0
      fs-service-system/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml
  25. 0 1
      fs-service-system/src/main/resources/mapper/store/FsUserCourseCountMapper.xml
  26. 88 20
      fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml
  27. 3 0
      fs-user-app/src/main/java/com/fs/app/controller/UserController.java
  28. 3 2
      fs-user-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java
  29. 1 2
      fs-user-app/src/main/java/com/fs/app/controller/WxPayController.java
  30. 2 0
      fs-user-app/src/main/java/com/fs/app/param/LoginMaWxParam.java

+ 2 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserCoursePeriodController.java

@@ -189,6 +189,7 @@ public class FsUserCoursePeriodController extends BaseController {
         return R.ok().put("data", periodRedPacketList);
     }
 
+    @Log(title = "按课程批量保存设置红包金额", businessType = BusinessType.UPDATE)
     @PreAuthorize("@ss.hasPermi('course:period:setCourseRedPacket')")
     @ApiOperation("按课程批量保存设置红包金额")
     @PostMapping("/batchRedPacket")
@@ -202,6 +203,7 @@ public class FsUserCoursePeriodController extends BaseController {
         return R.ok();
     }
 
+    @Log(title = "按营期批量保存设置红包金额", businessType = BusinessType.UPDATE)
     @PreAuthorize("@ss.hasPermi('course:period:setRedPacket')")
     @ApiOperation("按营期批量保存设置红包金额")
     @PostMapping("/batchRedPacket/byPeriod")

+ 9 - 0
fs-admin/src/test/java/com/fs/course/controller/FsCourseDomainNameControllerTest.java

@@ -4,6 +4,8 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.json.JSONUtil;
 import com.fs.FSAdminApplication;
 import com.fs.course.config.RedPacketConfig;
+import com.fs.statis.service.IStatisticsCompanyService;
+import com.fs.statis.service.impl.StatisticsCompanyServiceImpl;
 import com.fs.system.service.ISysConfigService;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
@@ -32,11 +34,18 @@ import static org.junit.jupiter.api.Assertions.*;
 @Slf4j
 class FsCourseDomainNameControllerTest {
 
+    @Autowired
+    private StatisticsCompanyServiceImpl statisticsCompanyService;
     @Autowired
     private WxPayService wxPayService;
 
     @Autowired
     private ISysConfigService configService;
+
+    @Test
+    public void test(){
+        statisticsCompanyService.rewardMoneyTaskEverydayCompanyUser();
+    }
     @Test
     public void nativePay() throws WxPayException {
 

+ 1 - 1
fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java

@@ -316,7 +316,7 @@ public class FsUserController extends AppBaseController {
         return fsUserService.becomeMember(param);
     }
 
-    //    @Login
+    @Login
     @PostMapping("/userImage")
     @ApiOperation("生成分享会员海报")
     public R createCourseImage(@RequestBody FsUserCourseBeMemberImageParam param) {

+ 36 - 5
fs-company/src/main/java/com/fs/company/controller/IndexStatisticsController.java

@@ -8,6 +8,7 @@ import com.fs.core.web.service.TokenService;
 import com.fs.statis.StatisticsRedisConstant;
 import com.fs.statis.dto.*;
 import io.jsonwebtoken.lang.Assert;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.http.util.Asserts;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -20,6 +21,7 @@ import static com.fs.statis.StatisticsRedisConstant.*;
 /**
  * 首页-统计
  */
+@Slf4j
 @RestController
 @RequestMapping("/index/statistics")
 public class IndexStatisticsController {
@@ -161,20 +163,32 @@ public class IndexStatisticsController {
      */
     @PostMapping("/rewardMoneyTopTen")
     public R rewardMoneyTopTen(@RequestBody AnalysisPreviewQueryDTO param){
+        log.info("开始处理奖励金额top10请求");
+
         Integer type = param.getType();
         Integer dataType = param.getDataType();
         Integer userType = param.getUserType();
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long companyId = loginUser.getCompany().getCompanyId();
         Long companyUserId = loginUser.getUser().getUserId();
+        log.info("请求参数: type={}, dataType={}, userType={}, companyId={}, companyUserId={}",
+                type, dataType, userType, companyId, companyUserId);
 
         param.setCompanyId(companyId);
         List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS;
+        String cacheKey;
+
         if(loginUser.getUser().isAdmin()) {
-            rewardMoneyTopTenDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,param.getCompanyId()));
+            cacheKey = String.format("%s:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,param.getCompanyId());
+            log.info("管理员用户,使用缓存key: {}", cacheKey);
+
         } else {
-            rewardMoneyTopTenDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,param.getCompanyId(),companyUserId));
+            cacheKey = String.format("%s:%d:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,param.getCompanyId(),companyUserId);
+            log.info("普通用户,使用缓存key: {}", cacheKey);
+
         }
+        rewardMoneyTopTenDTOS = redisCache.getCacheObject(cacheKey);
+        log.info("从Redis缓存中获取到的数据大小: {}", rewardMoneyTopTenDTOS != null ? rewardMoneyTopTenDTOS.size() : 0);
 
         return R.ok().put("data", rewardMoneyTopTenDTOS);
     }
@@ -189,8 +203,13 @@ public class IndexStatisticsController {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long companyId = loginUser.getCompany().getCompanyId();
         param.setCompanyId(companyId);
+        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS;
+        if(loginUser.getUser().isAdmin()) {
+            rewardMoneyTrendDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType,param.getCompanyId()));
+        } else {
+            rewardMoneyTrendDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType,param.getCompanyId(),loginUser.getUser().getUserId()));
+        }
 
-        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType,param.getCompanyId()));
         return R.ok().put("data", rewardMoneyTrendDTOS);
     }
 
@@ -206,8 +225,13 @@ public class IndexStatisticsController {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long companyId = loginUser.getCompany().getCompanyId();
         param.setCompanyId(companyId);
+        List<CourseStatsDTO> courseStatsDTOS;
+        if(loginUser.getUser().isAdmin()) {
+            courseStatsDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%s:%d", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort,param.getCompanyId()));
+        } else {
+            courseStatsDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%s:%d:%d", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort,param.getCompanyId(),loginUser.getUser().getUserId()));
+        }
 
-        List<CourseStatsDTO> courseStatsDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%s:%d", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort,param.getCompanyId()));
         return R.ok().put("data", courseStatsDTOS);
     }
 
@@ -219,7 +243,14 @@ public class IndexStatisticsController {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long companyId = loginUser.getCompany().getCompanyId();
 
-        DealerAggregatedDTO dealerAggregatedDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED,companyId));
+        DealerAggregatedDTO dealerAggregatedDTO;
+
+        if(loginUser.getUser().isAdmin()) {
+            dealerAggregatedDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED,companyId));
+        } else {
+            dealerAggregatedDTO = redisCache.getCacheObject(String.format("%s:%d:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED,companyId,loginUser.getUser().getUserId()));
+        }
+
 
         return R.ok().put("data",dealerAggregatedDTO);
     }

+ 2 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsCourseRedPacketLog.java

@@ -61,4 +61,6 @@ public class FsCourseRedPacketLog extends BaseEntity
 
     private String result;
 
+    private String batchId;//微信批次单号
+
 }

+ 1 - 1
fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -327,7 +327,7 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
 
     void batchUpdateFsUserWatchLog(@Param("list") List<FsCourseWatchLog> logs);
 
-    @Select("select * from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId} and send_type = 1")
+    @Select("select * from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId} and send_type = 1 order by log_id desc limit 1")
     FsCourseWatchLog getCourseWatchLogByUser(@Param("userId") Long userId, @Param("videoId") Long videoId);
 
     @Select("WITH date_series AS (\n" +

+ 1 - 0
fs-service-system/src/main/java/com/fs/course/param/FsCourseSendRewardUParam.java

@@ -27,4 +27,5 @@ public class FsCourseSendRewardUParam implements Serializable
     private Integer sendType;
     private Long periodId;
 
+    private String appId;
 }

+ 5 - 0
fs-service-system/src/main/java/com/fs/course/param/FsCourseTrafficLogParam.java

@@ -27,4 +27,9 @@ public class FsCourseTrafficLogParam {
 
     private String startDate;
     private String endDate;
+
+    /**
+     * tab类型
+     */
+    private String tabType;
 }

+ 3 - 0
fs-service-system/src/main/java/com/fs/course/param/PeriodCountParam.java

@@ -30,5 +30,8 @@ public class PeriodCountParam implements Serializable {
 
     private LocalDate maxDate;
 
+    @ApiModelProperty(value = "公司ID")
+    private Long companyId;
+
 }
 

+ 7 - 1
fs-service-system/src/main/java/com/fs/course/service/IFsCourseRedPacketLogService.java

@@ -64,7 +64,13 @@ public interface IFsCourseRedPacketLogService
      */
     public int deleteFsCourseRedPacketLogByLogId(Long logId);
 
-    R syncRedPacket(String outBatchNo);
+    /**
+     *
+     * @param outBatchNo 商家批次单号
+     * @param batchId 微信批次单号
+     * @return
+     */
+    R syncRedPacket(String outBatchNo,String batchId);
 
     List<FsCourseRedPacketLogListPVO> selectFsCourseRedPacketLogListVO(FsCourseRedPacketLogParam fsCourseRedPacketLog);
     List<FsCourseRedPacketLogListPVO> selectFsCourseRedPacketLogListVONew(FsCourseRedPacketLogParam fsCourseRedPacketLog);

+ 2 - 1
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java

@@ -100,11 +100,12 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
     }
 
     @Override
-    public R syncRedPacket(String outBatchNo) {
+    public R syncRedPacket(String outBatchNo,String batchId) {
         FsCourseRedPacketLog log = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByBatchNo(outBatchNo);
         if (log!=null){
             log.setStatus(1);
             log.setUpdateTime(new Date());
+            log.setBatchId(batchId);
             fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(log);
             return R.ok();
         }

+ 5 - 1
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java

@@ -35,7 +35,10 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -238,6 +241,7 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
         CourseAnalysisParam courseAnalysisParam = new CourseAnalysisParam();
         courseAnalysisParam.setPeriodId(param.getPeriodId());
         courseAnalysisParam.setVideoIdList(param.getVideoIdList());
+        courseAnalysisParam.setCompanyId(param.getCompanyId());
         List<FsCourseAnalysisCountVO> courseCountList = fsUserMapper.courseAnalysisWatchLog(courseAnalysisParam);
         List<FsCourseAnalysisCountVO> redPacketCountList = fsUserMapper.courseAnalysisRedPacketCount(courseAnalysisParam);
         List<FsCourseAnalysisCountVO> answerCountList = fsUserMapper.courseAnalysisAnswerCount(courseAnalysisParam);

+ 5 - 2
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -818,6 +818,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         packetParam.setSource(param.getSource());
         packetParam.setRedPacketMode(config.getRedPacketMode());
         packetParam.setCompanyId(param.getCompanyId());
+        packetParam.setAppId(param.getAppId());
 
         //2025.7.11 红包金额为0的时候
         if (amount.compareTo(BigDecimal.ZERO)>0){
@@ -830,8 +831,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                     transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
                     redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
                     redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
+                    redPacketLog.setBatchId(transferBillsResult.getTransferBillNo());
                 }else {
                     redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+                    redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());
                 }
                 // 添加红包记录
                 redPacketLog.setCourseId(param.getCourseId());
@@ -1016,7 +1019,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         // 逻辑调整:如果会员已经绑定了销售,直接提示,不添加重粉数据了-2025年6月16日14点53分
         if (fsUser.getCompanyUserId() != null && !param.getCompanyUserId().equals(fsUser.getCompanyUserId())){
-            return ResponseResult.fail(406,"该用户已成为其他销售会员");
+            return ResponseResult.fail(500,"该用户("+fsUser.getUserId() + ")已成为其他销售会员");
         }
 
         // 如果开启了黑名单审核,需要提示
@@ -1451,7 +1454,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         //读取配置给前端返回
         String json = sysConfigService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (org.apache.commons.lang3.StringUtils.isEmpty(user.getNickname()) || org.apache.commons.lang3.StringUtils.isEmpty(user.getAvatar())){
+        if (StringUtils.isEmpty(user.getNickname())){
             Map<String,Object> map = new HashMap<>();
             map.put("authType",config.getMiniAppAuthType());
             if (config.getMiniAppAuthType()==2){

+ 3 - 1
fs-service-system/src/main/java/com/fs/his/param/WxSendRedPacketParam.java

@@ -16,7 +16,9 @@ public class WxSendRedPacketParam implements Serializable {
 
     private Integer source=1;//来源 1:h5  2:看课小程序
 
-    private Integer redPacketMode; //红包模式
+    private Integer redPacketMode;//红包模式
+
+    private String appId;
 
 
 }

+ 2 - 2
fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsCompanyServiceImpl.java

@@ -438,7 +438,7 @@ public class StatisticsCompanyServiceImpl implements IStatisticsCompanyService {
         param.setUserType(userType);
         List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = this.watchEndPlayTrend(param);
 
-        redisCache.setCacheObject(String.format("%s:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType),watchEndPlayTrendDTOS);
+        redisCache.setCacheObject(String.format("%s:%d:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType,companyId),watchEndPlayTrendDTOS);
     }
 
     @Override
@@ -497,7 +497,7 @@ public class StatisticsCompanyServiceImpl implements IStatisticsCompanyService {
         param.setCompanyUserId(companyUserId);
         List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = this.watchEndPlayTrend(param);
 
-        redisCache.setCacheObject(String.format("%s:%d:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType,companyUserId),watchEndPlayTrendDTOS);
+        redisCache.setCacheObject(String.format("%s:%d:%d:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType,companyId,companyUserId),watchEndPlayTrendDTOS);
     }
 
     @Override

+ 3 - 0
fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java

@@ -314,4 +314,7 @@ public interface FsUserMapper
     List<FsUser> selectFsUserListByJointUserNameKey(String userNameKey);
 
     Map<String, Long> countUserCourse2(UserStatisticsCommonParam param);
+
+    Map<String, Long> countCourseDetailsNew(UserStatisticsCommonParam param);
+
 }

+ 3 - 2
fs-service-system/src/main/java/com/fs/store/param/FsUserEditParam.java

@@ -3,16 +3,17 @@ package com.fs.store.param;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
 @Data
 public class FsUserEditParam implements Serializable
 {
 
-    @NotBlank(message = "用户昵称不能为空!")
+    @NotNull(message = "用户昵称不能为空!")
     private String nickname;
 
-    @NotBlank(message = "用户头像不能为空!")
+//    @NotBlank(message = "用户头像不能为空!")
     private String avatar;
 
     private Long userId;

+ 5 - 10
fs-service-system/src/main/java/com/fs/store/service/impl/FsStorePaymentServiceImpl.java

@@ -377,7 +377,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
         }
         //H5的用公众号的appid发,小程序的用小程序的appid来发
         if (param.getSource()==2){
-            config.setAppId(config.getMiniappId());
+            config.setAppId(param.getAppId());
         }
         //组合返回参数
         R result = new R();
@@ -481,7 +481,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
 
         try {
             TransferBatchesResult transferBatchesResult = transferService.transferBatches(request);
-            return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo());
+            return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo()).put("batchId", transferBatchesResult.getBatchId());
         } catch (WxPayException e) {
             e.printStackTrace();
             return R.error("发送失败");
@@ -565,8 +565,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
             signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
             WxPayTransferBatchesNotifyV3Result result = wxPayService.parseTransferBatchesNotifyV3Result(notifyData,signatureHeader);
             logger.info("到零钱回调:{}",result.getResult());
-            if (result.getResult().getBatchStatus().equals("FINISHED")) {
-                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo());
+            if (result.getResult().getBatchStatus().equals("FINISHED") && result.getResult().getFailNum()==0) {
+                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo(),result.getResult().getBatchId());
                 logger.info("result:{}",r);
                 if (r.get("code").equals(200)){
                     return WxPayNotifyResponse.success("处理成功");
@@ -591,14 +591,9 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
             //创建微信订单
             WxPayConfig payConfig = new WxPayConfig();
             BeanUtils.copyProperties(config,payConfig);
-//            payConfig.setCertSerialNo("63AC73F33E0A21973BB1DE533421A2337FD91C20");
             WxPayService wxPayService = new WxPayServiceImpl();
             wxPayService.setConfig(payConfig);
             SignatureHeader signatureHeader = new SignatureHeader();
-//            signatureHeader.setTimeStamp("1622450000");  // 时间戳(Unix时间戳)
-//            signatureHeader.setNonce("5K8264ILTKCH16CQ2502SI8ZNMTM67VS");  // 随机字符串
-//            signatureHeader.setSerial("63AC73F33E0A21973BB1DE533421A2337FD91C20");
-//            signatureHeader.setSignature("HbjssPzTBkM2iSCmxknS663zigo3gQ1jGQ4R6E6x9356bmV6Um4WfgGWZOH+fdCx5dxjHEiIci5kOYKl0ZdRfnexFFuM2riXLSqnRboOJZ+ew8FH4ZP/zCxtlDnmIYbARoIN46RegcRmGgfOznkLcD7ihr0JixgoZ0BOYk7YLhhcbLZaE2OJmwyyYIdJCH5lvg0mXyX1yfutNxPZz13i3OmZiU42xYr4bByJICWMFTwkzha9GVfOp67q/oVu0bEGIMgGdAVoEUJZXOijKdZdOrieXT07wMU31KITKcnizaUGl5peXejbJEd6CAQcX5e8KRlRSjY8DybHAm0JawVuAw==");
             signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
             signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
             signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
@@ -606,7 +601,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
             TransferBillsNotifyResult result = wxPayService.parseTransferBillsNotifyV3Result(notifyData,signatureHeader);
             logger.info("到零钱回调:{}",result.getResult());
             if (result.getResult().getState().equals("SUCCESS")) {
-                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo());
+                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo(),result.getResult().getTransferBillNo());
                 logger.info("result:{}",r);
                 if (r.get("code").equals(200)){
                     return WxPayNotifyResponse.success("处理成功");

+ 6 - 5
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java

@@ -761,7 +761,8 @@ public class FsUserServiceImpl implements IFsUserService
             param.setCompanyId(companyUser.getCompanyId());
         }
         // 获取课程统计
-        Map<String, Long> couserMap = fsUserMapper.countUserCourse(param);
+//        Map<String, Long> couserMap = fsUserMapper.countUserCourse(param);
+        Map<String, Long> couserMap = fsUserMapper.countUserCourse2(param);
         if (couserMap != null) {
             fsUserStatisticsVO.setCourseWatchNum(couserMap.get("courseWatchNum").intValue()).setCourseCompleteNum(couserMap.get("courseCompleteNum").intValue());
 
@@ -799,8 +800,8 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     public FsUserStatisticsVO userStatisticsDetails(UserStatisticsCommonParam param) {
-//        FsUserStatisticsVO userStatisticsVO = getUserStatistics(param);
-        FsUserStatisticsVO userStatisticsVO = getUserStatistics2(param);
+        FsUserStatisticsVO userStatisticsVO = getUserStatistics(param);
+//        FsUserStatisticsVO userStatisticsVO = getUserStatistics2(param);
 
         // 判断是否是管理员
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
@@ -808,7 +809,7 @@ public class FsUserServiceImpl implements IFsUserService
             param.setUserId(0L);
         }
         //统计课程数据详情,在查询统计详情的时候需要显示
-        Map<String, Long> courseDetailsMap = fsUserMapper.countCourseDetails(param);
+        Map<String, Long> courseDetailsMap = fsUserMapper.countCourseDetailsNew(param);
         if(courseDetailsMap != null && courseDetailsMap.get("courseNum") != null && courseDetailsMap.get("videoNum") != null && courseDetailsMap.get("courseUserNum") != null){
             userStatisticsVO.setCourseNum(Integer.parseInt(courseDetailsMap.get("courseNum").toString()))
                     .setVideoNum(Integer.parseInt(courseDetailsMap.get("videoNum").toString()))
@@ -998,7 +999,7 @@ public class FsUserServiceImpl implements IFsUserService
 
         // 逻辑调整:如果会员已经绑定了销售,直接提示,不添加重粉数据了-2025年6月16日14点53分
         if (fsUser.getCompanyUserId() != null && !param.getCompanyUserId().equals(fsUser.getCompanyUserId())){
-            return ResponseResult.fail(406,"该用户已成为其他销售会员");
+            return ResponseResult.fail(500,"该用户("+fsUser.getUserId() + ")已成为其他销售会员");
         }
 
         //判断该销售是否存在

+ 5 - 0
fs-service-system/src/main/resources/application-config-zkzh.yml

@@ -76,6 +76,11 @@ wx:
         token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
         aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
         msgDataFormat: JSON
+      - appid: wx414427b10866c04e   #凯逸轩服装店C
+        secret: 4a56cc02f53859e1e9582c15d840c4af
+        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+        msgDataFormat: JSON
 
   pay:
     appId: wx11a2ce7c2bbc4521 #微信公众号或者小程序等的appid

+ 5 - 0
fs-service-system/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml

@@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="watchLogId"    column="watch_log_id"    />
         <result property="remark"    column="remark"    />
         <result property="result"    column="result"    />
+        <result property="batchId"    column="batch_id"    />
     </resultMap>
 
     <sql id="selectFsCourseRedPacketLogVo">
@@ -113,6 +114,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remark != null">remark,</if>
             <if test="periodId != null">period_id,</if>
             <if test="result != null">result,</if>
+            <if test="batchId != null">batch_id,</if>
+
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="courseId != null">#{courseId},</if>
@@ -130,6 +133,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remark != null">#{remark},</if>
             <if test="periodId != null">#{periodId},</if>
             <if test="result != null">#{result},</if>
+            <if test="batchId != null">#{batchId},</if>
          </trim>
     </insert>
 
@@ -151,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remark != null">remark = #{remark},</if>
             <if test="periodId != null">period_id = #{periodId},</if>
             <if test="result != null">result = #{result},</if>
+            <if test="batchId != null">batch_id = #{batchId},</if>
         </trim>
         where log_id = #{logId}
     </update>

+ 15 - 2
fs-service-system/src/main/resources/mapper/course/FsCourseTrafficLogMapper.xml

@@ -62,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ,DATE_FORMAT(create_time, '%Y-%m-%d') AS `month`  from fs_course_traffic_log
         <where>
             <if test="startDate != null and endDate != null">
-                and create_time between #{startDate} AND #{endDate}
+                and DATE_FORMAT(create_time, '%Y-%m-%d') between #{startDate} AND #{endDate}
             </if>
             <if test='companyId !=null'>
                 and company_id = #{companyId}
@@ -74,7 +74,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 and project = ${project}
             </if>
         </where>
-        group by company_id,`month`,project,course_id
+
+        <if test="tabType==null or tabType==''">
+            group by company_id,`month`,course_id,project
+        </if>
+        <if test="tabType!=null and tabType=='project'">
+            group by project,`month`
+        </if>
+        <if test="tabType!=null and tabType=='course'">
+            group by course_id,`month`
+        </if>
+        <if test="tabType!=null and tabType=='company'">
+            group by company_id,`month`
+        </if>
+
     </select>
     <select id="getTodayTrafficLog" resultType="java.lang.Long">
         SELECT

+ 1 - 0
fs-service-system/src/main/resources/mapper/course/FsUserWatchStatisticsMapper.xml

@@ -119,6 +119,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             fwl.company_id
         FROM
             fs_course_watch_log fwl
+
         WHERE
             fwl.send_type = 1
         GROUP BY

+ 12 - 0
fs-service-system/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml

@@ -213,6 +213,12 @@
             <if test="userType != null">
                 AND send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                AND company_id = #{companyId}
+            </if>
+            <if test="companyUserId != null">
+                AND company_user_id = #{companyUserId}
+            </if>
         </where>
         GROUP BY
         start_date
@@ -322,6 +328,9 @@
             <if test="companyId != null">
                 and log.company_id = ${companyId}
             </if>
+            <if test="companyUserId != null">
+                and log.company_user_id = #{companyUserId}
+            </if>
         </where>
         GROUP BY
             <if test="dataType == 0">
@@ -361,6 +370,9 @@
             <if test="companyId != null">
                 and log.company_id = ${companyId}
             </if>
+            <if test="companyUserId != null">
+                and log.company_user_id = #{companyUserId}
+            </if>
         </where>
         group by start_date
     </select>

+ 0 - 1
fs-service-system/src/main/resources/mapper/store/FsUserCourseCountMapper.xml

@@ -61,7 +61,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             ifnull ( sum( fs_user_course_count.miss_course_count ), 0 ) AS miss_course_count,
             ifnull ( sum( fs_user_course_count.part_course_count ), 0 ) AS part_course_count,
             Max( fs_user_course_count.last_watch_date ) AS last_watch_date,
-            ifnull ( sum( fs_user_course_count.stop_watch_days ), 0 ) AS stop_watch_days,
             Max( fs_user_course_count.complete_watch_date) AS complete_watch_date
             from fs_user_course_count where user_id = ${userId}
     </select>

+ 88 - 20
fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml

@@ -525,10 +525,12 @@
         fs_user.*,
         fs_user_course_count.id,
         fs_user_course_count.watch_course_count,
+--         fs_course_watch_log.watch_course_count,
         fs_user_course_count.miss_course_count,
         fs_user_course_count.miss_course_status,
         fs_user_course_count.course_ids,
         fs_user_course_count.part_course_count,
+--         fs_course_watch_log.part_course_count,
         fs_user_course_count.last_watch_date,
         fs_user_course_count.STATUS AS courseCountStatus,
         fs_user_course_count.stop_watch_days,
@@ -544,6 +546,17 @@
         LEFT JOIN company_tag ON FIND_IN_SET(company_tag.tag_id, company_tag_user.tag_ids) > 0
         LEFT JOIN fs_user_company_user ON fs_user_company_user.user_id = fs_user.user_id
         LEFT JOIN company_user ON company_user.user_id = fs_user_company_user.company_user_id
+--         LEFT JOIN (
+--         SELECT
+--         fs_course_watch_log.user_id,
+--         count( DISTINCT fs_course_watch_log.video_id ) watch_course_count,
+--         count( DISTINCT fs_course_watch_log.period_id ) part_course_count
+--         FROM
+--         fs_course_watch_log
+--         GROUP BY
+--         fs_course_watch_log.user_id
+--         ) fs_course_watch_log ON fs_course_watch_log.user_id = fs_user.user_id
+        LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
         where fs_user.is_del = 0
         <if test="userId != null and userId!= 0 ">
             and fs_user.company_user_id = #{userId}
@@ -1418,6 +1431,9 @@
                     #{videoId}
                 </foreach>
             </if>
+            <if test="companyId != null">
+                AND flog.company_id = #{companyId}
+            </if>
         </where>
         GROUP BY
         flog.video_id
@@ -1462,7 +1478,9 @@
                     #{videoId}
                 </foreach>
             </if>
-
+            <if test="companyId != null">
+                AND fs_course_answer_logs.company_id = #{companyId}
+            </if>
         </where>
         GROUP BY
         fs_course_answer_logs.video_id
@@ -1582,6 +1600,9 @@
                     #{videoId}
                 </foreach>
             </if>
+            <if test="companyId != null">
+                AND fwl.company_id = #{companyId}
+            </if>
         </where>
         GROUP BY
         fwl.video_id
@@ -1667,6 +1688,7 @@
             fwl.period_id, fwl.video_id, fwl.company_user_id, fwl.company_id
         FROM
             fs_course_watch_log fwl
+
         WHERE
             fwl.send_type = 1
         GROUP BY
@@ -1765,37 +1787,47 @@
             and company_user_id = #{companyUserId}
         </if>
     </select>
+
     <select id="countUserCourse2" resultType="java.util.Map">
         SELECT
         (
         SELECT
-        count(1)
+        count(DISTINCT l.user_id)
         FROM
         fs_course_watch_log l
+        LEFT JOIN fs_user on fs_user.user_id = l.user_id
         LEFT JOIN company_user ON l.company_user_id = company_user.user_id
         where
-            l.log_type != 3 and send_type = 1
-            <if test="userId != null and userId != 0 ">
-                and (l.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
-            </if>
-            <if test="userId != null and userId == 0 ">
-                and l.company_id = #{companyId}
-            </if>
-            <if test="periodId != null and periodId != ''">
-                AND l.period_id = #{periodId}
-            </if>
-            <if test="videoId != null and videoId != ''">
-                AND l.video_id = #{videoId}
-            </if>
-            <if test="companyUserId != null and companyUserId != ''">
-                AND l.user_id = #{companyUserId}
-            </if>
+        l.log_type != 3 and send_type = 1
+        <if test="userId != null and userId != 0 ">
+            and (l.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+        </if>
+        <if test="userId != null and userId == 0 ">
+            and l.company_id = #{companyId}
+        </if>
+        <if test="periodId != null and periodId != ''">
+            AND l.period_id = #{periodId}
+        </if>
+        <if test="videoId != null and videoId != ''">
+            AND l.video_id = #{videoId}
+        </if>
+        <if test="startTime != null and startTime !='' ">
+            and l.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null and endTime != ''">
+            and l.create_time &lt;= #{endTime}
+        </if>
+        -- 单独通过销售id查询
+        <if test="companyUserId != null and companyUserId != ''">
+            AND l.company_user_id = #{companyUserId}
+        </if>
         ) as courseWatchNum,
         (
         SELECT
-        count(1)
+        count(DISTINCT l.user_id)
         FROM
         fs_course_watch_log l
+        LEFT JOIN fs_user on fs_user.user_id = l.user_id
         LEFT JOIN company_user ON l.company_user_id = company_user.user_id
         where
         l.log_type = 2 and send_type = 1
@@ -1811,11 +1843,47 @@
         <if test="videoId != null and videoId != ''">
             AND l.video_id = #{videoId}
         </if>
+        <if test="startTime != null and startTime !='' ">
+            and l.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null and endTime != ''">
+            and l.create_time &lt;= #{endTime}
+        </if>
         -- 单独通过销售id查询
         <if test="companyUserId != null and companyUserId != ''">
-            AND l.user_id = #{companyUserId}
+            AND l.company_user_id = #{companyUserId}
         </if>
         ) as courseCompleteNum
     </select>
 
+    <select id="countCourseDetailsNew" resultType="Map">
+        SELECT
+        count( DISTINCT l.period_id ) as courseNum,
+        count( DISTINCT l.video_id ) as videoNum,
+        count( DISTINCT l.user_id ) as courseUserNum
+        FROM
+        fs_course_watch_log l
+        left join fs_user on fs_user.user_id = l.user_id
+        LEFT JOIN company_user ON l.company_user_id = company_user.user_id
+        WHERE
+        l.log_type != 3
+        AND send_type = 1
+        <if test="userId != null and userId != 0 ">
+            AND l.company_user_id = #{userId}
+        </if>
+        <if test="userId != null and userId == 0 ">
+            and l.company_id = #{companyId}
+        </if>
+        <if test="periodId != null and periodId != ''">
+            AND l.period_id =  #{periodId}
+        </if>
+        <if test="videoId != null and videoId != ''">
+            AND l.video_id = #{videoId}
+        </if>
+        -- 单独通过销售id查询
+        <if test="companyUserId != null and companyUserId != ''">
+            AND l.company_user_id = #{companyUserId}
+        </if>
+    </select>
+
 </mapper>

+ 3 - 0
fs-user-app/src/main/java/com/fs/app/controller/UserController.java

@@ -300,6 +300,9 @@ public class UserController extends  AppBaseController {
         if (param.getNickname().length()>50){
             return R.error("请授权正确的昵称!");
         }
+        if (StringUtils.isEmpty(param.getAvatar())){
+            param.setAvatar("https://zkzh-2025.oss-cn-beijing.aliyuncs.com/fs/20250715/533c6f87cc2e4ba4a9504374bb58416d.png");
+        }
         FsUser user=new FsUser();
         user.setUserId(Long.parseLong(getUserId()));
         user.setAvatar(param.getAvatar());

+ 3 - 2
fs-user-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java

@@ -76,7 +76,7 @@ public class WxCompanyUserController extends AppBaseController {
 //            return R.error("昵称不符合标准!");
 //        }
         //获取第二个小程序配置,序号从0开始
-        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(1).getAppid());
+        final WxMaService wxService = WxMaConfiguration.getMaService(param.getAppId());
         try {
             WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
             this.logger.info(session.getSessionKey());
@@ -131,7 +131,7 @@ public class WxCompanyUserController extends AppBaseController {
                     userMap.setPhone(phoneNoInfo.getPhoneNumber());
                     // 逻辑调整:如果会员已经绑定了销售,直接提示,不让注册-2025年6月16日14点53分
                     if (user.getCompanyUserId() != null && !param.getCompanyUserId().equals(user.getCompanyUserId())){
-                        return R.error(406, "该用户已成为其他销售会员");
+                        return R.error(500, "该用户("+user.getUserId() + ")已成为其他销售会员");
                     }
 //                    if((companyUser.getIsAllowedAllRegister() == null || companyUser.getIsAllowedAllRegister() == 1)
 //                            && companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1){
@@ -154,6 +154,7 @@ public class WxCompanyUserController extends AppBaseController {
                         user.setCompanyId(param.getCompanyId());
                         user.setCompanyUserId(param.getCompanyUserId());
                     }
+//                    redisCache.setCacheObject("");
                     userService.insertFsUser(user);
                 }
             } else {

+ 1 - 2
fs-user-app/src/main/java/com/fs/app/controller/WxPayController.java

@@ -112,8 +112,7 @@ public class WxPayController {
     }
 
     @PostMapping( "/test")
-    public R test() throws Exception {
-        WxSendRedPacketParam param  = new WxSendRedPacketParam();
+    public R test(@RequestBody WxSendRedPacketParam param) throws Exception {
         storePaymentService.sendRedPacketTest(param);
         return R.ok();
     }

+ 2 - 0
fs-user-app/src/main/java/com/fs/app/param/LoginMaWxParam.java

@@ -55,4 +55,6 @@ public class LoginMaWxParam implements Serializable {
     @ApiModelProperty(value = "小程序授权类型")
     private Integer authType;
 
+    private String appId;
+
 }