Ver código fonte

Merge remote-tracking branch 'origin/master' into Payment

yfh 3 dias atrás
pai
commit
735903ab1b

+ 1 - 1
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreAfterSalesScrmController.java

@@ -123,7 +123,7 @@ public class FsStoreAfterSalesScrmController extends BaseController
                             zmvo.setRealName(vo.getUserName());
                             zmvo.setUserPhone(vo.getUserPhone());
                             zmvo.setUserAddress(vo.getUserAddress());
-                            zmvo.setCreateTime(vo.getCreateTime());
+                            zmvo.setCreateTime(vo.getOrderCreateTime());
                             zmvo.setPayTime(vo.getOrderPayTime());
                             zmvo.setDeliverySn(vo.getOrderDeliverySn());
                             zmvo.setDeliveryName(vo.getOrderDeliveryName());

+ 38 - 0
fs-admin/src/main/java/com/fs/hisStore/task/MallStoreTask.java

@@ -34,7 +34,11 @@ import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
 import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.service.*;
+import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
+import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
+import com.fs.huifuPay.service.HuiFuService;
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderPayment;
 import com.fs.pay.pay.dto.OrderQueryDTO;
 import com.fs.pay.service.IPayService;
 import com.fs.store.config.StoreConfig;
@@ -50,6 +54,7 @@ import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
 import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.Date;
@@ -160,6 +165,39 @@ public class MallStoreTask
 
     //@Autowired
     //private IFsUserOnlineStateService fsUserOnlineStateService;
+    @Autowired
+    private HuiFuService huiFuService;
+
+    // 订单银行回调数据丢失补偿
+    public void recoveryBankOrder() {
+        // 查询出来最近15分钟的订单 待支付 未退款
+        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectBankOrder();
+        if(list == null || list.isEmpty()) return;
+        for (FsStoreOrderScrm order : list) {
+            List<FsStorePaymentScrm> orderPayments = fsStorePaymentMapper.selectFsStorePaymentByOrderId(order.getId());
+            if(orderPayments == null || orderPayments.isEmpty()) continue;
+            for (FsStorePaymentScrm payment : orderPayments) {
+                V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
+                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
+                request.setOrgHfSeqId(payment.getTradeNo());
+                request.setAppId(payment.getAppId());
+                HuiFuQueryOrderResult o = null;
+                try {
+                    o = huiFuService.queryOrder(request);
+                } catch (Exception e) {
+                    log.error("查询失败:"+e.getMessage());
+                    continue;
+                }
+                log.info("汇付返回"+o);
+                if ("00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
+                    String[] orderSpilt=o.getOrg_req_seq_id().split("-");
+                    if ("store".equals(orderSpilt[0])) {
+                        orderService.payConfirm(1, null, orderSpilt[1], o.getOrg_hf_seq_id(), o.getOut_trans_id(), o.getParty_order_id());
+                    }
+                }
+            }
+        }
+    }
 
     public void PushErp() throws ParseException {
         List<Long> ids;

+ 7 - 7
fs-live-app/src/main/java/com/fs/live/task/Task.java

@@ -947,13 +947,13 @@ public class Task {
                 boolean needUpdate = false;
                 Integer newLogType = log.getLogType();
 
-                // ① 如果在线时长 <= 3分钟,修改 logType 为 4(看课中断)
-                if (onlineSeconds <= 180) { // 3分钟 = 180秒
-                    newLogType = 4;
-                    needUpdate = true;
-                }
-                // ③ 如果直播视频 >= 40分钟,在线时长 >= 30分钟,logType 设置为 2(完课)
-                else if (totalVideoDuration >= 2400 && onlineSeconds >= 1800) { // 40分钟 = 2400秒,30分钟 = 1800秒
+                // ① 如果在线时长 <= 3分钟,修改 logType 为 4(看课中断) lmx-这个逻辑不合理,不能这样判定看课中断
+//                if (onlineSeconds <= 180) { // 3分钟 = 180秒
+//                    newLogType = 4;
+//                    needUpdate = true;
+//                } else
+                    // ③ 如果直播视频 >= 40分钟,在线时长 >= 30分钟,logType 设置为 2(完课)
+                if (totalVideoDuration >= 2400 && onlineSeconds >= 1800) { // 40分钟 = 2400秒,30分钟 = 1800秒
                     newLogType = 2;
                     log.setFinishTime(now);
                     needUpdate = true;

+ 9 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodServiceImpl.java

@@ -146,6 +146,15 @@ public class FsUserCoursePeriodServiceImpl implements IFsUserCoursePeriodService
             coursePeriodDays.setStartDateTime(startDateTime);
             coursePeriodDays.setEndDateTime(endDateTime);
             coursePeriodDays.setLastJoinTime(lastJsonTime);
+
+            if(LocalDate.now().isBefore(coursePeriodDays.getStartDateTime().toLocalDate())){
+                coursePeriodDays.setStatus(0);
+            } else if(LocalDate.now().isAfter(coursePeriodDays.getStartDateTime().toLocalDate())){
+                coursePeriodDays.setStatus(2);
+            } else{
+                coursePeriodDays.setStatus(1);
+            }
+
             fsUserCoursePeriodDaysMapper.updateFsUserCoursePeriodDays(coursePeriodDays); // 更新数据库中的课程日期
         }
 

+ 22 - 21
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -47,6 +47,7 @@ import com.fs.course.service.IFsUserCompanyUserService;
 import com.fs.course.service.IFsUserCourseVideoService;
 import com.fs.course.vo.*;
 import com.fs.course.vo.newfs.*;
+import com.fs.enums.ExceptionCodeEnum;
 import com.fs.his.config.AppConfig;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserIntegralLogs;
@@ -707,11 +708,11 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
         //用户不存在唤起重新授权
         if (fsUser == null) {
-            return R.error(401, "未授权");
+            return R.error(ExceptionCodeEnum.USER_NOT_FOUND.getCode(), ExceptionCodeEnum.USER_NOT_FOUND.getDescription());
         }
 
         if (fsUser.getStatus() == 0) {
-            return R.error("会员被停用,无权限,请联系客服!");
+            return R.error(ExceptionCodeEnum.MEMBER_DISABLED.getCode(), ExceptionCodeEnum.MEMBER_DISABLED.getDescription());
         }
 //        if (param.getIsOpenCourse()!=null&&param.getIsOpenCourse()==1){
 //            FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByUserId(param.getUserId(), param.getVideoId());
@@ -757,7 +758,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         if (oneCompanyCourse && fsUser.getQwExtId() != null) {
             QwExternalContact qwExternalContact = qwExternalContactMapper.selectById(fsUser.getQwExtId());
             if (qwExternalContact.getCompanyUserId() != null && !qwExternalContact.getCompanyUserId().equals(param.getCompanyUserId())) {
-                return R.error(500, "该用户(" + fsUser.getUserId() + ")已成为其他销售会员");
+                return R.error(ExceptionCodeEnum.USER_ALREADY_OTHER_SALES_MEMBER.getCode(), ExceptionCodeEnum.USER_ALREADY_OTHER_SALES_MEMBER.getFormattedDescription(fsUser.getUserId()));
             }
         }
 
@@ -769,7 +770,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
             List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectQwExternalContactList(query);
             if (qwExternalContacts != null && !qwExternalContacts.isEmpty() && !Objects.equals(qwExternalContacts.get(0).getCompanyUserId(), param.getCompanyUserId())) {
                 String msgInfo = "该用户(" + fsUser.getUserId() + ")已在公司" + param.getCompanyId() + "成为其他销售会员";
-                return R.error(500, msgInfo);
+                return R.error(ExceptionCodeEnum.USER_COMPANY_OTHER_SALES_MEMBER.getCode(), ExceptionCodeEnum.USER_COMPANY_OTHER_SALES_MEMBER.getFormattedDescription(fsUser.getUserId(),param.getCompanyId()));
             }
         }
 
@@ -788,7 +789,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         } else {
             // 非法参数
             logger.warn("非法参数 isRoom: {}", isRoom);
-            return R.error("参数错误!");
+            return R.error(ExceptionCodeEnum.PARAM_ERROR.getCode(), ExceptionCodeEnum.PARAM_ERROR.getDescription());
         }
 
     }
@@ -798,13 +799,13 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
 //                "\t\t\t\t\t<div style=\"color: #999;font-size: 14px;font-weight: bold;\">添加伴学助手免费领取会员权限</div>";
         QwGroupChat qwGroupChat = qwGroupChatMapper.selectQwGroupChatByChatId(courseLink.getChatId());
         if (qwGroupChat == null) {
-            return R.error("群参数异常");
+            return R.error(ExceptionCodeEnum.GROUP_PARAM_ERROR.getCode(), ExceptionCodeEnum.GROUP_PARAM_ERROR.getDescription());
         }
         SopUserLogsInfo sopUserLogsInfo = new SopUserLogsInfo();
         sopUserLogsInfo.setChatId(courseLink.getChatId());
         List<QwGroupChatUser> qwGroupChatUsers = qwGroupChatUserMapper.selectByChatId(sopUserLogsInfo);
         if (qwGroupChatUsers == null || qwGroupChatUsers.isEmpty()) {
-            return R.error("群参数异常");
+            return R.error(ExceptionCodeEnum.GROUP_PARAM_ERROR.getCode(), ExceptionCodeEnum.GROUP_PARAM_ERROR.getDescription());
         }
         //群聊寻找用户新逻辑
         QwExternalContact qwExternalContact = null;
@@ -2523,10 +2524,10 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         //查询用户
         FsUser fsUser = fsUserMapper.selectFsUserById(param.getUserId());
         if (fsUser == null) {
-            return ResponseResult.fail(401, "当前用户信息不存在");
+            return ResponseResult.fail(ExceptionCodeEnum.USER_NOT_FOUND.getCode(), ExceptionCodeEnum.USER_NOT_FOUND.getDescription());
         }
         if (fsUser.getStatus() == 0) {
-            return ResponseResult.fail(503, "会员被停用,无权限,请联系客服!");
+            return ResponseResult.fail(ExceptionCodeEnum.MEMBER_DISABLED.getCode(), ExceptionCodeEnum.MEMBER_DISABLED.getDescription());
         }
         //公开课
         if (param.getIsOpenCourse() != null && param.getIsOpenCourse() == 1) {
@@ -2554,14 +2555,14 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         //判断该销售是否存在
         CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
         if (companyUser == null) {
-            return ResponseResult.fail(405, "当前销售不存在");
+            return ResponseResult.fail(ExceptionCodeEnum.SALES_NOT_FOUND.getCode(), ExceptionCodeEnum.SALES_NOT_FOUND.getDescription());
         }
 
         // 获取课程所属项目id
         FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
         Long courseProject = fsUserCourse.getProject();
         if (Objects.isNull(courseProject)) {
-            return ResponseResult.fail(504, "课程配置错误,项目归属为空,课程ID: " + param.getCourseId());
+            return ResponseResult.fail(ExceptionCodeEnum.COURSE_CONFIG_ERROR.getCode(),  ExceptionCodeEnum.COURSE_CONFIG_ERROR.getFormattedDescription(param.getCourseId()));
         }
         FsUserCoursePeriod fsUserCoursePeriod = fsUserCoursePeriodMapper.selectFsUserCoursePeriodById(param.getPeriodId());
         FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(fsUser.getUserId(), courseProject);
@@ -2574,7 +2575,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
                 Company company = companyService.selectCompanyById(param.getCompanyId());
 
                 if ((companyUser.getIsAllowedAllRegister() != null && companyUser.getIsAllowedAllRegister() != 1)) {
-                    return ResponseResult.fail(504, "当前销售禁止绑定会员,请联系销售!");
+                    return ResponseResult.fail(ExceptionCodeEnum.SALES_FORBIDDEN_BIND.getCode(), ExceptionCodeEnum.SALES_FORBIDDEN_BIND.getDescription());
                 }
                 // 使用 Stream API 检查是否包含 companyId
                 // 修正类型转换问题
@@ -2584,7 +2585,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
                         && Arrays.stream(fsUserCoursePeriod.getIsNeedRegisterMember().split(","))
                         .map(String::trim)
                         .anyMatch(id -> id.equals(String.valueOf(company.getCompanyId()))))) {
-                    return ResponseResult.fail(504, "请联系销售发送邀请链接成为会员!");
+                    return ResponseResult.fail(ExceptionCodeEnum.CONTACT_SALES_FOR_INVITATION.getCode(), ExceptionCodeEnum.CONTACT_SALES_FOR_INVITATION.getDescription());
                 }
                 int defaultStatus = (company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1;
                 userCompanyUser = userCompanyUserService.bindRelationship(param.getUserId(), courseProject, companyUser.getCompanyId(), companyUser.getUserId(), defaultStatus);
@@ -2595,7 +2596,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         if (!param.getCompanyUserId().equals(userCompanyUser.getCompanyUserId())) {
             log.error("进入::isAddCompanyUser 该用户fsUser={},companyUser={},param={}", fsUser, companyUser, param);
 
-            return ResponseResult.fail(500, "该用户(" + fsUser.getUserId() + ")已成为其他销售会员");
+            return ResponseResult.fail(ExceptionCodeEnum.USER_ALREADY_OTHER_SALES_MEMBER.getCode(), ExceptionCodeEnum.USER_ALREADY_OTHER_SALES_MEMBER.getFormattedDescription(fsUser.getUserId()));
         }
 
         // 如果开启了黑名单审核,需要提示
@@ -2606,9 +2607,9 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
 
         if (userCompanyUser.getStatus() == 2) {
             if ("福本源".equals(signProjectName)) {
-                return ResponseResult.fail(504, "服务暂时不可用,请联系管理员");
+                return ResponseResult.fail(ExceptionCodeEnum.SERVICE_UNAVAILABLE.getCode(), ExceptionCodeEnum.SERVICE_UNAVAILABLE.getDescription());
             } else {
-                return ResponseResult.fail(504, "已被拉黑,请联系管理员");
+                return ResponseResult.fail(ExceptionCodeEnum.USER_BLACKLISTED.getCode(), ExceptionCodeEnum.USER_BLACKLISTED.getDescription());
             }
         }
 
@@ -2617,14 +2618,14 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         FsCourseWatchLog watchCourseVideo = courseWatchLogMapper.getCourseWatchLogByUser(param.getUserId(), param.getVideoId(), param.getPeriodId());
 
         if (!isUserCoursePeriodValid(param)) {
-            return ResponseResult.fail(504, "请观看最新的课程项目");
+            return ResponseResult.fail(ExceptionCodeEnum.WATCH_LATEST_COURSE.getCode(), ExceptionCodeEnum.WATCH_LATEST_COURSE.getDescription());
         }
         // 项目看课数限制
         if (!EXCLUDE_PROJECTS.contains(signProjectName) && !CloudHostUtils.hasCloudHostName("弘德堂")) {
             log.error("进入了看课限制:传入参数:={},watchCourseVideo={}",param, watchCourseVideo);
             Integer logCount = fsUserCourseMapper.selectTodayCourseWatchLogCountByUserIdAndProjectId(param.getUserId(), courseProject);
             if (Objects.isNull(watchCourseVideo) && logCount > 0) {
-                return ResponseResult.fail(504, "超过项目看课数量限制");
+                return ResponseResult.fail(ExceptionCodeEnum.EXCEED_COURSE_LIMIT.getCode(), ExceptionCodeEnum.EXCEED_COURSE_LIMIT.getDescription());
             }
         }else {
             log.error("没有进入看课限制:传入参数:={},watchCourseVideo={}存在问题 ",param, watchCourseVideo);
@@ -2634,7 +2635,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
             if (!watchCourseVideo.getCompanyUserId().equals(param.getCompanyUserId())) {
                 //提示
                 log.error("数据库存在销售信息:{},分享得销售信息:{}", watchCourseVideo.getCompanyUserId(), param.getCompanyUserId());
-                return ResponseResult.fail(504, "已看过其他销售分享的此课程,不能重复观看");
+                return ResponseResult.fail(ExceptionCodeEnum.ALREADY_WATCHED_OTHER_SALES_COURSE.getCode(), ExceptionCodeEnum.ALREADY_WATCHED_OTHER_SALES_COURSE.getDescription());
             }
 
             FsCourseWatchLog updateLog = new FsCourseWatchLog();
@@ -3678,11 +3679,11 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
         //用户不存在唤起重新授权
         if (fsUser == null) {
-            return R.error(504, "未授权");
+            return R.error(ExceptionCodeEnum.USER_NOT_FOUND.getCode(), ExceptionCodeEnum.USER_NOT_FOUND.getDescription());
         }
 
         if (fsUser.getStatus() == 0) {
-            return R.error("会员被停用,无权限,请联系客服!");
+            return R.error(ExceptionCodeEnum.MEMBER_DISABLED.getCode(), ExceptionCodeEnum.MEMBER_DISABLED.getDescription());
         }
         return createWatchIsOpen(param);
     }

+ 54 - 0
fs-service/src/main/java/com/fs/enums/ExceptionCodeEnum.java

@@ -0,0 +1,54 @@
+package com.fs.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum ExceptionCodeEnum {
+
+    // ============ 用户相关错误 (400-419) ============
+    USER_NOT_FOUND(401, "当前用户信息不存在,请重新授权"),
+
+    // ============ 会员相关错误 (420-439) ============
+    USER_BLACKLISTED(421, "已被拉黑,请联系管理员"),
+
+    // ============ 销售相关错误 (440-459) ============
+    SALES_NOT_FOUND(441, "当前销售不存在"),
+    SALES_FORBIDDEN_BIND(442, "当前销售禁止绑定会员,请联系销售!"),
+    CONTACT_SALES_FOR_INVITATION(443, "请联系销售发送邀请链接成为会员!"),
+
+    // ============ 会员关系错误 (460-479) ============
+    MEMBER_DISABLED(461, "会员被停用,无权限,请联系客服!"),
+    USER_ALREADY_OTHER_SALES_MEMBER(462, "该用户(%s)已成为其他销售会员"),
+    USER_COMPANY_OTHER_SALES_MEMBER(463, "该用户(%s)已在公司%s成为其他销售会员"),
+
+    // ============ 课程相关错误 (480-499) ============
+    COURSE_CONFIG_ERROR(481, "课程配置错误,项目归属为空,课程ID: %s"),
+    WATCH_LATEST_COURSE(482, "请观看最新的课程项目"),
+    EXCEED_COURSE_LIMIT(483, "超过项目看课数量限制"),
+    ALREADY_WATCHED_OTHER_SALES_COURSE(484, "已看过其他销售分享的此课程,不能重复观看"),
+
+    // ============ 参数相关错误 (500-519) ============
+    PARAM_ERROR(501, "参数错误!"),
+    GROUP_PARAM_ERROR(502, "群参数异常"),
+    LIVE_PARAM_ERROR(503, "直播参数错误"),
+
+    // ============ 系统相关错误 (520-539) ============
+    SERVICE_UNAVAILABLE(521, "服务暂时不可用,请联系管理员");
+
+    private final Integer code;
+    private final String description;
+
+    ExceptionCodeEnum(Integer code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    /**
+     * 获取格式化后的描述信息
+     * @param args 格式化参数
+     * @return 格式化后的描述
+     */
+    public String getFormattedDescription(Object... args) {
+        return String.format(description, args);
+    }
+}

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java

@@ -255,7 +255,7 @@ public interface FsStoreAfterSalesScrmMapper
             " left join company c on c.company_id=s.company_id " +
             " left join company_user cu on cu.user_id=s.company_user_id " +
             " left join fs_store_payment_scrm fsps on fsps.business_order_id = o.id and fsps.status in (-1,1) " +
-            " where 1=1 and s.status = 4 and fsps.bank_transaction_id is not null " +
+            " where 1=1 and s.is_del = 0  and o.status = -2 and fsps.bank_transaction_id is not null " +
             "<if test =\"maps.hfOrderCode != null and  maps.hfOrderCode!='' \"> " +
             "and fsps.pay_code = #{maps.hfOrderCode} " +
             "</if>" +

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java

@@ -1417,4 +1417,8 @@ public interface FsStoreOrderScrmMapper
 
     @Update("update fs_store_order_scrm set `status`=-3 where order_code=#{orderCode}")
     int cancelOrderByCode(@Param("orderCode") String orderCode);
+
+
+    @Select("SELECT * FROM fs_store_order_scrm WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 MINUTE) and status = 0")
+    List<FsStoreOrderScrm> selectBankOrder();
 }

+ 10 - 8
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -732,14 +732,16 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             }
 
             // 佣金处理
-            if (order.getCompanyUserId() == -1L) {
-                companyService.addCompanyTuiLiveMoney(order);
-            } else {
-                // 目前是一级佣金
-                FsStoreProduct product = JSONUtil.toBean(order.getItemJson(), FsStoreProduct.class);
-                List<FsStoreProductAttrValueScrm> productAttrValues = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueByProductId(product.getProductId());
-                if (productAttrValues != null && !productAttrValues.isEmpty()) {
-                    userService.addTuiLiveMoney(order, productAttrValues);
+            if (order.getCompanyUserId() != null || order.getCompanyId() != null) {
+                if (order.getCompanyUserId() == -1L) {
+                    companyService.addCompanyTuiLiveMoney(order);
+                } else {
+                    // 目前是一级佣金
+                    FsStoreProduct product = JSONUtil.toBean(order.getItemJson(), FsStoreProduct.class);
+                    List<FsStoreProductAttrValueScrm> productAttrValues = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueByProductId(product.getProductId());
+                    if (productAttrValues != null && !productAttrValues.isEmpty()) {
+                        userService.addTuiLiveMoney(order, productAttrValues);
+                    }
                 }
             }
 

+ 15 - 8
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -13,6 +13,7 @@ import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.course.domain.FsCourseLink;
 import com.fs.course.service.impl.FsUserCourseVideoServiceImpl;
+import com.fs.enums.ExceptionCodeEnum;
 import com.fs.his.domain.FsUser;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.service.IFsUserService;
@@ -669,10 +670,10 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
         //用户不存在唤起重新授权
         if (fsUser == null) {
-            return R.error(401, "未授权");
+            return R.error(ExceptionCodeEnum.USER_NOT_FOUND.getCode(), ExceptionCodeEnum.USER_NOT_FOUND.getDescription());
         }
         if (fsUser.getStatus() == 0) {
-            return R.error("会员被停用,无权限,请联系客服!");
+            return R.error(ExceptionCodeEnum.MEMBER_DISABLED.getCode(), ExceptionCodeEnum.MEMBER_DISABLED.getDescription());
         }
         //未注册提示
         String noRegisterMsg = "由于您还未完成注册,请联系伴学助手完成注册即可观看!";
@@ -684,7 +685,7 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         } else if (null != param.getQwExternalId()) {
             return handleLivePerson(param,fsUser, noMemberMsg, noRegisterMsg);
         } else {
-            return R.error("直播参数错误");
+            return R.error(ExceptionCodeEnum.LIVE_PARAM_ERROR.getCode(), ExceptionCodeEnum.LIVE_PARAM_ERROR.getDescription());
         }
 
     }
@@ -874,6 +875,12 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     @Override
     @Async
     public void qwTagMarkByLiveWatchLog(Long liveId) {
+        //休眠2分钟 等待看课中断的所有看课记录状态被正确处理标记
+        try {
+            Thread.sleep(120000L);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
         log.info("处理直播间打标签: liveId={}", liveId);
         //查询直播间的标签配置
         List<LiveTagItemVO> liveTagConfig = liveTagConfigMapper.getLiveTagListByliveId(liveId);
@@ -1087,7 +1094,7 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         try {
 
             LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
-            
+
             if (liveWatchUser != null) {
                 if (liveWatchUser.getOnlineSeconds() == null || duration > liveWatchUser.getOnlineSeconds()) {
                     liveWatchUser.setOnlineSeconds(duration);
@@ -1116,25 +1123,25 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     public Long getTotalWatchDuration(Long liveId, Long userId) {
         try {
             long totalDuration = 0L;
-            
+
             // 1. 查询直播观看记录(liveFlag=1, replayFlag=0)
             LiveWatchUser liveRecord = baseMapper.selectByUniqueIndex(liveId, userId, 1, 0);
             if (liveRecord != null && liveRecord.getOnlineSeconds() != null) {
                 totalDuration += liveRecord.getOnlineSeconds();
             }
-            
+
             // 2. 查询回放观看记录(liveFlag=0, replayFlag=1)
             LiveWatchUser replayRecord = baseMapper.selectByUniqueIndex(liveId, userId, 0, 1);
             if (replayRecord != null && replayRecord.getOnlineSeconds() != null) {
                 totalDuration += replayRecord.getOnlineSeconds();
             }
-            
+
             log.debug("查询总观看时长: liveId={}, userId={}, liveDuration={}, replayDuration={}, total={}",
                     liveId, userId,
                     liveRecord != null ? liveRecord.getOnlineSeconds() : 0,
                     replayRecord != null ? replayRecord.getOnlineSeconds() : 0,
                     totalDuration);
-            
+
             return totalDuration;
         } catch (Exception e) {
             log.error("查询总观看时长失败: liveId={}, userId={}", liveId, userId, e);

+ 6 - 6
fs-service/src/main/resources/application-config-druid-shdn.yml

@@ -73,10 +73,10 @@ nuonuo:
 tencent_cloud_config:
   secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
   secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
-  bucket: jnlzjk-1323137866
+  bucket: shdn-1323137866
   app_id: 1323137866
   region: ap-chongqing
-  proxy: jnlzjk
+  proxy: shdn
 tmp_secret_config:
   secret_id: AKIDCj7NSNAovtqeJpBau8GZ4CGB71thXIxX
   secret_key: lTB5zwqqz7CNhzDOWivFWedgfTBgxgBT
@@ -85,10 +85,10 @@ tmp_secret_config:
   region: ap-chongqing
   proxy: fs
 cloud_host:
-  company_name: 济南联志健康
-  projectCode: LZJK
-  spaceName:
-  volcengineUrl: https://jnlzvolcengine.ylrztop.com
+  company_name: 上海德宁
+  projectCode: SHDN
+  spaceName: shdn-20251226
+  volcengineUrl: https://shdnjbvolcengine.ylrztop.com
 headerImg:
   imgUrl:
 

+ 2 - 0
fs-service/src/main/resources/mapper/his/FsUserIntegralLogsMapper.xml

@@ -58,6 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time,</if>
             <if test="businessType != null">business_type,</if>
             <if test="status != null">status,</if>
+            <if test="remark != null">remark,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="userId != null">#{userId},</if>
@@ -68,6 +69,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">#{createTime},</if>
             <if test="businessType != null">#{businessType},</if>
             <if test="status != null">#{status},</if>
+            <if test="remark != null">#{remark},</if>
          </trim>
     </insert>
 

+ 3 - 3
fs-service/src/main/resources/mapper/hisStore/MergedOrderMapper.xml

@@ -146,7 +146,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             AND csc.appid = #{maps.appId}
           </if>
         <if test="maps.hfshh != null and maps.hfshh != ''">
-            AND hfshh = #{maps.hfshh}
+            AND CONCAT('store-',sp_latest.pay_code) = #{maps.hfshh}
         </if>
           group by o.id
           UNION ALL
@@ -291,7 +291,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             AND csc.appid = #{maps.appId}
           </if>
         <if test="maps.hfshh != null and maps.hfshh != ''">
-            AND hfshh = #{maps.hfshh}
+            AND CONCAT('store-',sp_latest.pay_code) = #{maps.hfshh}
         </if>
         group by o.id
           UNION ALL
@@ -433,7 +433,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             AND DATE(o.delivery_send_time) BETWEEN SUBSTRING_INDEX(#{maps.deliverySendTimeRange}, '--', 1) AND SUBSTRING_INDEX(#{maps.deliverySendTimeRange}, '--', -1)
           </if>
         <if test="maps.hfshh != null and maps.hfshh != ''">
-            AND hfshh = #{maps.hfshh}
+            AND CONCAT('store-',sp_latest.pay_code) = #{maps.hfshh}
         </if>
         group by o.order_id
         ) AS merged_orders

+ 2 - 2
fs-service/src/main/resources/mapper/live/LiveAfterSalesMapper.xml

@@ -118,7 +118,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectLiveAfterSalesVoListExport" parameterType="com.fs.live.vo.LiveAfterSalesVo" resultType="com.fs.live.vo.LiveAfterSalesVo">
         select las.id, las.live_id, las.store_id, las.refund_amount,
         las.refund_type, las.reasons, las.explains, las.explain_img, las.delivery_code, las.delivery_sn, las.delivery_name, las.status, las.sales_status,
-        las.order_status, las.create_time, las.is_del, las.user_id, las.consignee, las.phone_number, las.address, las.company_id, las.company_user_id, las.dept_id,
+        las.order_status, lo.create_time, las.is_del, las.user_id, las.consignee, las.phone_number, las.address, las.company_id, las.company_user_id, las.dept_id,
         cu.nick_name as company_user_nick_name, c.company_name,lo.order_id,lo.order_code,lo.user_phone,lo.item_json,lo.pay_time as orderPayTime,
         lo.user_address,lo.user_name,lo.pay_price,lo.total_postage,lop.bank_serial_no,lo.delivery_sn as orderDeliveryId,lo.delivery_name as orderDeliveryName,
         lo.delivery_code as orderDeliverySn,lo.status as orderStatus,lop.bank_transaction_id,lo.pay_money,lop.pay_code as payCode
@@ -131,7 +131,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         left join live_order_item loi on loi.order_id = lo.order_id
         </if>
 
-        where 1=1 and las.status =4 and lop.bank_transaction_id is not null
+        where 1=1 and las.is_del = 0 and lo.status = -2 and lop.bank_transaction_id is not null
             <if test="hfOrderCode != null and hfOrderCode != ''"> and lop.pay_code = #{hfOrderCode}</if>
             <if test="liveId != null and liveId != ''"> and las.live_id = #{liveId}</if>
             <if test="companyUserNickName != null and companyUserNickName != ''"> and cu.nick_name like concat(#{companyUserNickName},'%')</if>

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

@@ -164,6 +164,9 @@ public class LiveCompletionPointsController extends AppBaseController {
                     ? record.getWatchDuration() : 0L;
             
             vo.setVideoDuration(videoDuration);
+            if (record != null) {
+                vo.setCompletionRate(record.getCompletionRate());
+            }
             vo.setWatchDuration(watchDuration);
             vo.setRemainingTime(Math.max(0, videoDuration - watchDuration));
             vo.setHasReceived(record != null && record.getReceiveStatus() != null && record.getReceiveStatus() == 1);

+ 4 - 0
fs-user-app/src/main/java/com/fs/app/vo/RemainingTimeVO.java

@@ -3,6 +3,7 @@ package com.fs.app.vo;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 /**
  * 剩余时长返回VO
@@ -23,5 +24,8 @@ public class RemainingTimeVO implements Serializable {
     
     /** 是否领取过 */
     private Boolean hasReceived;
+
+    /** 完课比例(%) */
+    private BigDecimal completionRate;
 }