Ver código fonte

Merge remote-tracking branch 'origin/bjcz_his_scrm' into bjcz_his_scrm

吴树波 2 dias atrás
pai
commit
a4fa802a13

+ 32 - 0
fs-common/src/main/java/com/fs/common/core/page/TableDataInfo.java

@@ -1,7 +1,10 @@
 package com.fs.common.core.page;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 表格分页数据对象
@@ -24,6 +27,9 @@ public class TableDataInfo implements Serializable
     /** 消息内容 */
     private String msg;
 
+    /** 扩展数据(用于存放统计信息等额外数据) */
+    private Map<String, Object> ext;
+
     /**
      * 表格数据对象
      */
@@ -82,4 +88,30 @@ public class TableDataInfo implements Serializable
     {
         this.msg = msg;
     }
+
+    public Map<String, Object> getExt()
+    {
+        return ext;
+    }
+
+    public void setExt(Map<String, Object> ext)
+    {
+        this.ext = ext;
+    }
+
+    /**
+     * 添加扩展数据
+     * @param key 键
+     * @param value 值
+     * @return TableDataInfo
+     */
+    public TableDataInfo put(String key, Object value)
+    {
+        if (this.ext == null)
+        {
+            this.ext = new HashMap<>();
+        }
+        this.ext.put(key, value);
+        return this;
+    }
 }

+ 32 - 3
fs-company/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java

@@ -73,14 +73,43 @@ public class FsStorePaymentScrmController extends BaseController
         fsStorePayment.setCompanyId(loginUser.getCompany().getCompanyId());
         startPage();
         List<FsStorePaymentVO> list = fsStorePaymentService.selectFsStorePaymentListQueryVO(fsStorePayment);
+        
+        // 计算总支付金额和总退款金额
+        BigDecimal totalPaymentAmount = BigDecimal.ZERO;
+        BigDecimal totalRefundAmount = BigDecimal.ZERO;
+        
         for (FsStorePaymentVO vo : list){
             vo.setUserPhone(ParseUtils.parsePhone(vo.getUserPhone()));
+            
+            // 状态为1(已支付)或-1(已退款)时,累加到总支付金额
+            if (vo.getStatus() != null && (vo.getStatus() == 1 || vo.getStatus() == -1)) {
+                if (vo.getPayMoney() != null) {
+                    totalPaymentAmount = totalPaymentAmount.add(vo.getPayMoney());
+                }
+            }
+            
+            // 状态为-1(已退款)时,累加到总退款金额
+            // 根据规范,只统计退款审核状态为2(审核完成)的退款金额
+            if (vo.getStatus() != null && vo.getStatus() == -1) {
+                if (vo.getRefundAuditStatus() != null && vo.getRefundAuditStatus() == 2) {
+                    if (vo.getRefundMoney() != null) {
+                        totalRefundAmount = totalRefundAmount.add(vo.getRefundMoney());
+                    }
+                }
+            }
         }
+        
         // 记录查询条件,包括新增的退款审核状态
-        logger.info("支付明细列表查询,公司ID:{},退款审核状态:{},退款审核人:{},查询结果数量:{}",
+        logger.info("支付明细列表查询,公司ID:{},退款审核状态:{},退款审核人:{},查询结果数量:{},总支付金额:{},总退款金额:{}",
             loginUser.getCompany().getCompanyId(), fsStorePayment.getRefundAuditStatus(), 
-            fsStorePayment.getRefundAuditBy(), list.size());
-        return getDataTable(list);
+            fsStorePayment.getRefundAuditBy(), list.size(), totalPaymentAmount, totalRefundAmount);
+        
+        TableDataInfo dataTable = getDataTable(list);
+
+        dataTable.put("totalPaymentAmount", totalPaymentAmount);
+        dataTable.put("totalRefundAmount", totalRefundAmount);
+        
+        return dataTable;
     }
 
     /**

+ 24 - 2
fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java

@@ -313,14 +313,35 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
             
             // 确定开始课次 - 从现有最大课次+1开始,确保连续性
             int startLesson;
+            LocalDate startDate; // 新增:确定开始日期
+            
             if (param.getStartLesson() != null) {
                 startLesson = param.getStartLesson();
+                // 如果指定了起始课次,仍然基于营期开始时间计算日期
+                startDate = period.getPeriodStartingTime().plusDays(startLesson - 1);
             } else {
                 // 获取现有最大课次,如果没有则从1开始
                 startLesson = existingDays.stream()
                         .mapToInt(FsUserCoursePeriodDays::getLesson)
                         .max()
                         .orElse(0) + 1;
+                
+                // 关键修复:获取已存在课程的最后日期,从该日期的下一天开始
+                if (!existingDays.isEmpty()) {
+                    // 按日期排序,获取最后一个课程的日期
+                    LocalDate lastDate = existingDays.stream()
+                            .map(FsUserCoursePeriodDays::getDayDate)
+                            .filter(date -> date != null)
+                            .max(LocalDate::compareTo)
+                            .orElse(period.getPeriodStartingTime().plusDays(startLesson - 2));
+                    
+                    startDate = lastDate.plusDays(1); // 从最后日期的下一天开始
+                    log.info("基于已存在课程的最后日期计算起始日期:最后日期={}, 新起始日期={}", lastDate, startDate);
+                } else {
+                    // 如果没有已存在的课程,从营期开始时间计算
+                    startDate = period.getPeriodStartingTime();
+                    log.info("营期暂无课程,从营期开始时间计算起始日期:{}", startDate);
+                }
             }
             
             // 使用排序后的视频列表进行处理,确保按courseSort顺序添加
@@ -336,8 +357,9 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
                 // 设置课次 - 严格按排序后的顺序递增,确保有序
                 newDay.setLesson(startLesson + i);
                 
-                // 计算日期 - 基于课次计算正确日期(课次从1开始,所以偏移量是课次-1)
-                LocalDate courseDate = period.getPeriodStartingTime().plusDays(newDay.getLesson() - 1);
+                // 计算日期 - 修复:基于起始日期递增,而不是基于课次计算
+                // 这样可以避免当已存在课程的日期与课次不对应时出现重复日期
+                LocalDate courseDate = startDate.plusDays(i);
                 newDay.setDayDate(courseDate);
                 
                 // 设置时间 - 优先使用参数中的时间,其次使用视频默认时间

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

@@ -1883,12 +1883,21 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if (!isUserCoursePeriodValid(param)) {
             return ResponseResult.fail(504, "请观看最新的课程项目");
         }
-        // 项目看课数限制
-        if(!EXCLUDE_PROJECTS.contains(signProjectName) && !CloudHostUtils.hasCloudHostName("弘德堂")) {
+
+        // 检查是否为自由模式
+        FsUserCoursePeriod period = fsUserCoursePeriodMapper.selectFsUserCoursePeriodById(param.getPeriodId());
+        boolean isFreeMode = period != null && period.getFreeMode() != null && period.getFreeMode() == 1;
+
+        // 项目看课数限制(自由模式下跳过此限制)
+        if(!isFreeMode && !EXCLUDE_PROJECTS.contains(signProjectName) && !CloudHostUtils.hasCloudHostName("弘德堂")) {
             Integer logCount = fsUserCourseMapper.selectTodayCourseWatchLogCountByUserIdAndProjectId(param.getUserId(), courseProject);
             if (Objects.isNull(watchCourseVideo) && logCount > 0) {
+                log.info("【自由模式检查】固定模式下超过项目看课数量限制,periodId={}, userId={}, logCount={}",
+                        param.getPeriodId(), param.getUserId(), logCount);
                 return ResponseResult.fail(504, "超过项目看课数量限制");
             }
+        } else if(isFreeMode) {
+            log.info("【自由模式检查】✅ 自由模式,跳过项目看课数量限制检查,periodId={}", param.getPeriodId());
         }
 
         //添加判断:该用户是否已经存在此课程的看课记录,并且看课记录的销售id不是传入的销售id
@@ -1946,8 +1955,16 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
      * @return 如果当前时间在有效范围内且状态为1,返回true,否则返回false
      */
     public boolean isUserCoursePeriodValid(FsUserCourseAddCompanyUserParam param) {
+        log.info("【自由模式检查】开始验证课程权限,参数:periodId={}, videoId={}, courseId={}, companyUserId={}",
+                param.getPeriodId(), param.getVideoId(), param.getCourseId(), param.getCompanyUserId());
+
         // 查询课程周期信息
         FsUserCoursePeriodDays periodDays = getPeriodDaysInfo(param);
+        log.info("【自由模式检查】课程周期信息:periodDays={}, status={}, startTime={}, endTime={}",
+                periodDays != null ? periodDays.getId() : null,
+                periodDays != null ? periodDays.getStatus() : null,
+                periodDays != null ? periodDays.getStartDateTime() : null,
+                periodDays != null ? periodDays.getEndDateTime() : null);
 
         // 检查是否开启自由模式
         FsUserCoursePeriod period = fsUserCoursePeriodMapper.selectFsUserCoursePeriodById(param.getPeriodId());

+ 14 - 46
fs-service/src/main/resources/mapper/course/FsCourseQuestionBankMapper.xml

@@ -149,52 +149,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
     <update id="updateFsCourseQuestionBankBatch">
-        update fs_course_question_bank
-        <trim prefix="SET" suffixOverrides=",">
-            <trim prefix="sort = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.sort}
-                </foreach>
-            </trim>
-            <trim prefix="type = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.type}
-                </foreach>
-            </trim>
-            <trim prefix="status = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.status}
-                </foreach>
-            </trim>
-            <trim prefix="question = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.question}
-                </foreach>
-            </trim>
-            <trim prefix="answer = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.answer}
-                </foreach>
-            </trim>
-            <trim prefix="create_by = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.createBy}
-                </foreach>
-            </trim>
-            <trim prefix="question_type = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.questionType}
-                </foreach>
-            </trim>
-            <trim prefix="question_sub_type = CASE" suffix="END,">
-                <foreach collection="list" item="item">
-                    WHEN title = #{item.title} THEN #{item.questionSubType}
-                </foreach>
-            </trim>
-        </trim>
-        WHERE title IN
-        <foreach collection="list" item="item" open="(" separator="," close=")">
-            #{item.title}
+        <foreach collection="list" item="item" separator=";">
+            update fs_course_question_bank
+            <set>
+                <if test="item.sort != null">sort = #{item.sort},</if>
+                <if test="item.type != null">type = #{item.type},</if>
+                <if test="item.status != null">status = #{item.status},</if>
+                <if test="item.question != null">question = #{item.question},</if>
+                <if test="item.answer != null">answer = #{item.answer},</if>
+                <if test="item.createBy != null">create_by = #{item.createBy},</if>
+                <if test="item.questionType != null">question_type = #{item.questionType},</if>
+                <if test="item.questionSubType != null">question_sub_type = #{item.questionSubType},</if>
+                <if test="item.userId != null">user_id = #{item.userId},</if>
+            </set>
+            where title = #{item.title}
         </foreach>
     </update>
 </mapper>