瀏覽代碼

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_java

caoliqin 2 周之前
父節點
當前提交
9c97a60029
共有 52 個文件被更改,包括 542 次插入68 次删除
  1. 5 0
      fs-admin/src/main/java/com/fs/his/controller/FsCourseCouponController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java
  3. 9 4
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  4. 1 1
      fs-live-app/src/main/java/com/fs/live/task/Task.java
  5. 1 1
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  6. 4 1
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  7. 0 0
      fs-service/src/main/java/com/fs/company/service/impl/GeneralCustomerEntryServiceImpl.java
  8. 3 0
      fs-service/src/main/java/com/fs/config/ai/AiHostProper.java
  9. 1 1
      fs-service/src/main/java/com/fs/course/domain/FsCourseAnswerReward.java
  10. 8 0
      fs-service/src/main/java/com/fs/course/domain/FsCoursePlaySourceConfig.java
  11. 5 0
      fs-service/src/main/java/com/fs/course/domain/FsUserCourseVideo.java
  12. 2 2
      fs-service/src/main/java/com/fs/course/domain/LuckyBagCollectRecord.java
  13. 1 1
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseStudyMapper.java
  14. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseVideoRedPackageMapper.java
  15. 8 0
      fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java
  16. 8 0
      fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java
  17. 2 2
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  18. 9 0
      fs-service/src/main/java/com/fs/course/vo/FsCoursePlaySourceConfigVO.java
  19. 5 0
      fs-service/src/main/java/com/fs/course/vo/FsUserCourseVideoQVO.java
  20. 1 1
      fs-service/src/main/java/com/fs/crm/utils/CrmCustomerAiTagUtil.java
  21. 5 0
      fs-service/src/main/java/com/fs/his/domain/FsCourseCouponUser.java
  22. 4 0
      fs-service/src/main/java/com/fs/his/mapper/FsCourseCouponMapper.java
  23. 5 0
      fs-service/src/main/java/com/fs/his/mapper/FsCourseCouponUserMapper.java
  24. 4 1
      fs-service/src/main/java/com/fs/his/mapper/FsUserIntegralLogsMapper.java
  25. 17 0
      fs-service/src/main/java/com/fs/his/param/CourseFinishRewardParam.java
  26. 11 0
      fs-service/src/main/java/com/fs/his/service/IFsCourseCouponService.java
  27. 3 0
      fs-service/src/main/java/com/fs/his/service/IFsCourseCouponUserService.java
  28. 184 0
      fs-service/src/main/java/com/fs/his/service/impl/FsCourseCouponServiceImpl.java
  29. 30 0
      fs-service/src/main/java/com/fs/his/service/impl/FsCourseCouponUserServiceImpl.java
  30. 2 2
      fs-service/src/main/java/com/fs/his/service/impl/FsUserInvitedServiceImpl.java
  31. 15 0
      fs-service/src/main/java/com/fs/his/vo/CourseFinishRewardVO.java
  32. 1 1
      fs-service/src/main/java/com/fs/his/vo/GetFsIntegralCartDetailsVo.java
  33. 1 1
      fs-service/src/main/java/com/fs/his/vo/GetFsIntegralCartListVo.java
  34. 7 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreAfterSalesScrm.java
  35. 3 3
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderItemScrmMapper.java
  36. 4 2
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  37. 21 11
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  38. 2 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsMyStoreOrderListQueryVO.java
  39. 2 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreAfterSalesQueryVO.java
  40. 2 2
      fs-service/src/main/java/com/fs/live/domain/LiveUserRedRecord.java
  41. 22 22
      fs-service/src/main/java/com/fs/live/service/impl/LiveRedConfServiceImpl.java
  42. 1 1
      fs-service/src/main/java/com/fs/qw/service/impl/LuckyBagServiceImpl.java
  43. 3 1
      fs-service/src/main/resources/application-config-dev.yml
  44. 1 0
      fs-service/src/main/resources/application-config-druid-sxjz.yml
  45. 5 0
      fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  46. 5 1
      fs-service/src/main/resources/mapper/his/FsCourseCouponUserMapper.xml
  47. 6 2
      fs-service/src/main/resources/mapper/hisStore/FsStoreAfterSalesScrmMapper.xml
  48. 3 1
      fs-service/src/main/resources/mapper/qw/QwUserMapper.xml
  49. 43 0
      fs-user-app/src/main/java/com/fs/app/controller/FsCourseCouponController.java
  50. 18 0
      fs-user-app/src/main/java/com/fs/app/controller/SysConfigController.java
  51. 4 0
      fs-user-app/src/main/java/com/fs/app/controller/store/StoreAfterSalesScrmController.java
  52. 31 2
      fs-user-app/src/main/java/com/fs/app/controller/store/StoreProductController.java

+ 5 - 0
fs-admin/src/main/java/com/fs/his/controller/FsCourseCouponController.java

@@ -108,4 +108,9 @@ public class FsCourseCouponController extends BaseController
     {
         return toAjax(fsCourseCouponService.deleteFsCourseCouponByIds(ids));
     }
+
+    @GetMapping("/options")
+    public AjaxResult selectFsCourseCouponOptions(){
+        return AjaxResult.success(fsCourseCouponService.selectFsCourseCouponOptions());
+    }
 }

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

@@ -99,7 +99,7 @@ public class FsStoreHealthOrderScrmController extends BaseController {
         if(!StringUtils.isEmpty(param.getDeliverySendTimeRange())){
             param.setDeliverySendTimeList(param.getDeliverySendTimeRange().split("--"));
         }
-        param.setIsHealth("1");
+//        param.setIsHealth("1");
         List<FsStoreOrderVO> list = fsStoreOrderService.selectFsStoreOrderListVO(param);
         //金牛需求 区别其他项目 status = 6 (金牛代服管家) ,其他项目请避免使用订单状态status = 6
         TableDataInfo dataTable = getDataTable(list);

+ 9 - 4
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -681,14 +681,19 @@ public class FsStoreOrderScrmController extends BaseController {
             user.setPhone(ParseUtils.parsePhone(user.getPhone()));
         }
 
+
         if (order.getCompanyUserId() != null) {
             CompanyUser companyUser = companyUserService.selectCompanyUserByUserId(order.getCompanyUserId());
-            Company company = companyService.selectCompanyById(companyUser.getCompanyId());
-            order.setCompanyUserName(companyUser.getNickName());
-            order.setCompanyName(company.getCompanyName());
+            if (companyUser != null) {
+                Company company = companyService.selectCompanyById(companyUser.getCompanyId());
+                order.setCompanyUserName(companyUser.getNickName());
+                order.setCompanyName(company.getCompanyName());
+            }
         } else if (order.getCompanyId() != null) {
             Company company = companyService.selectCompanyById(order.getCompanyId());
-            order.setCompanyName(company.getCompanyName());
+            if (company != null) {
+                order.setCompanyName(company.getCompanyName());
+            }
         }
 
         if (order.getOrderType() != null && order.getOrderType() == 3) {

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

@@ -433,7 +433,7 @@ public class Task {
                 List<Long> userIds = onlineUser.stream().map(LiveWatchUser::getUserId).collect(Collectors.toList());
                 // 4.保存用户领取记录
                 saveUserRewardRecord(openRewardLive, userIds,config.getScoreAmount());
-                // 5.更新用户积分(芳华币
+                // 5.更新用户积分(积分
                 fsUserService.increaseIntegral(userIds,config.getScoreAmount());
                 // 6.发送websocket事件消息 通知用户自动领取成功
                 userIds.forEach(userId -> webSocketServer.sendIntegralMessage(openRewardLive.getLiveId(),userId,config.getScoreAmount()));

+ 1 - 1
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -869,7 +869,7 @@ public class WebSocketServer {
         sendMsgVo.setUserId(userId);
         sendMsgVo.setUserType(0L);
         sendMsgVo.setCmd("Integral");
-        sendMsgVo.setMsg("恭喜你成功获得观看奖励:" + scoreAmount + "芳华币");
+        sendMsgVo.setMsg("恭喜你成功获得观看奖励:" + scoreAmount + "积分");
         sendMsgVo.setData(String.valueOf(scoreAmount));
 
         if(Objects.isNull( session)) return;

+ 4 - 1
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -289,7 +289,10 @@ public class QwMsgController {
                 log.info("id:{}, 需要二次验证:"+wxWorkMsgResp.getJson(), id);
 
                 redisCache.setCacheObject("qrCodeUid:"+wxWorkMsgResp.getUuid(),100012,10, TimeUnit.MINUTES);
-
+                QwUser qwUser1 = qwUserMapper.selectQwUserById(id);
+                if(qwUser1.getUid().equals(wxWorkMsgResp.getUuid())){
+                    qwUserService.atMsg(qwUser1, "需要二次验证(在销售后台,企微员工页面点击二次验证)");
+                }
                 break;
             case 100005:
 

File diff suppressed because it is too large
+ 0 - 0
fs-service/src/main/java/com/fs/company/service/impl/GeneralCustomerEntryServiceImpl.java


+ 3 - 0
fs-service/src/main/java/com/fs/config/ai/AiHostProper.java

@@ -20,6 +20,9 @@ public class AiHostProper {
     @Value("${ipad.commonApi}")
     private String commonApi;
 
+    @Value("${ipad.aiApiV2:http://1.95.196.10:3000/api}")
+    private String aiApiV2;
+
 
 
 }

+ 1 - 1
fs-service/src/main/java/com/fs/course/domain/FsCourseAnswerReward.java

@@ -24,7 +24,7 @@ public class FsCourseAnswerReward {
     private List<RewardProduct> products;
 
     /**
-     * 本次获得的芳华币数量
+     * 本次获得的积分数量
      */
     private Integer availableCoins;
 

+ 8 - 0
fs-service/src/main/java/com/fs/course/domain/FsCoursePlaySourceConfig.java

@@ -109,4 +109,12 @@ public class FsCoursePlaySourceConfig {
      * 商户支付配置id
      */
     private Long merchantConfigId;
+    /**
+    * 客服电话
+    */
+    private Long customerNum;
+    /**
+    * 备案号
+    */
+    private String recordNumber;
 }

+ 5 - 0
fs-service/src/main/java/com/fs/course/domain/FsUserCourseVideo.java

@@ -142,6 +142,11 @@ public class FsUserCourseVideo extends BaseEntity
     /** 课程介绍图片URL */
     private String courseIntroImg;
 
+    /**
+     * 课程优惠券ID
+     */
+    private Long courseCouponId;
+
     @TableField(exist = false)
     private Integer showProduct; //1不展示疗法,0展示疗法
 

+ 2 - 2
fs-service/src/main/java/com/fs/course/domain/LuckyBagCollectRecord.java

@@ -60,8 +60,8 @@ public class LuckyBagCollectRecord extends BaseEntity{
     @Excel(name = "公司名称")
     private String companyName;
 
-    /** 芳华币数量 */
-    @Excel(name = "芳华币数量")
+    /** 积分数量 */
+    @Excel(name = "积分数量")
     private BigDecimal coinAmount;
 
     /** 发放时间 */

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

@@ -74,7 +74,7 @@ public interface FsUserCourseStudyMapper
             "<if test = ' maps.courseType != null and maps.courseType == 1 '> " +
             "and c.cate_id = (select cate_id from fs_user_course_category WHERE cate_name like '%央广原乡行%' AND cate_type = 1 limit 1) " +
             "</if>" +
-            "<if test = ' maps.courseType == null  '> " +
+            "<if test = ' maps.courseType == null  or maps.courseType == 0'> " +
             "and c.cate_id != (select cate_id from fs_user_course_category WHERE cate_name like '%央广原乡行%' AND cate_type = 1 limit 1) " +
             "</if>" +
             " order by s.study_id  "+

+ 3 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserCourseVideoRedPackageMapper.java

@@ -113,4 +113,7 @@ public interface FsUserCourseVideoRedPackageMapper
 
 
     Integer selectRedPacketByCompanyCount(@Param("videoId") Long videoId,@Param("companyId") Long companyId, @Param("periodId") Long periodId);
+
+    @Select("select * from fs_user_course_video_red_package where video_id =#{videoId} and company_id = #{companyId} and data_type = #{dataType}")
+    FsUserCourseVideoRedPackage selectRedPacketByVideoIdAndType(@Param("videoId") Long videoId,@Param("companyId") Long companyId,@Param("dataType") Integer dataType);
 }

+ 8 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java

@@ -57,4 +57,12 @@ public class FsCoursePlaySourceConfigCreateParam {
 
     @ApiModelProperty("小程序状态:0正常,1半封禁,2封禁")
     private Integer status;
+    /**
+    * 客服电话
+    */
+    private Long customerNum;
+    /**
+    * 备案号
+    */
+    private String recordNumber;
 }

+ 8 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java

@@ -58,4 +58,12 @@ public class FsCoursePlaySourceConfigEditParam {
 
     @ApiModelProperty("商户支付配置id")
     private Long merchantConfigId;
+    /**
+    * 客服电话
+    */
+    private Long customerNum;
+    /**
+    * 备案号
+    */
+    private String recordNumber;
 }

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

@@ -465,7 +465,7 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
             todayTotalIntegral=0;
         }
         if (todayTotalIntegral>=config.getIntegralByOneDay()){
-            return R.error("当天芳华币已达限额");
+            return R.error("当天积分已达限额");
         }
         int rate = (int)((double)param.getDuration() / video.getDuration() * 100);
         if (rate>=90){
@@ -493,7 +493,7 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
 //            integralLogs.setBusinessId(video.getVideoId().toString());
 //            integralLogs.setCreateTime(new Date());
 //            fsUserIntegralLogsMapper.insertFsUserIntegralLogs(integralLogs);
-//            return R.ok("恭喜您获得"+config.getIntegralCourse()+"芳华币");
+//            return R.ok("恭喜您获得"+config.getIntegralCourse()+"积分");
         }
         return R.error("观看进度不满百分之九十");
     }

+ 9 - 0
fs-service/src/main/java/com/fs/course/vo/FsCoursePlaySourceConfigVO.java

@@ -67,4 +67,13 @@ public class FsCoursePlaySourceConfigVO {
 
     @ApiModelProperty("小程序支付配置id")
     private Long merchantConfigId;
+
+    /**
+     * 客服电话
+     */
+    private Long customerNum;
+    /**
+     * 备案号
+     */
+    private String recordNumber;
 }

+ 5 - 0
fs-service/src/main/java/com/fs/course/vo/FsUserCourseVideoQVO.java

@@ -113,4 +113,9 @@ public class FsUserCourseVideoQVO extends BaseEntity {
 
     // 是否上架 0:上架,1:下架
     private Integer isOnPut;
+
+    /**
+     * 课程优惠券ID
+     */
+    private Long courseCouponId;
 }

+ 1 - 1
fs-service/src/main/java/com/fs/crm/utils/CrmCustomerAiTagUtil.java

@@ -145,7 +145,7 @@ public class CrmCustomerAiTagUtil {
             ChatService chatService = SpringUtils.getBean(ChatService.class);
             AiHostProper aiHost = SpringUtils.getBean(AiHostProper.class);
 
-            return chatService.initiatingTakeChat(param, aiHost.getAiApi(), appKey);
+            return chatService.initiatingTakeChat(param, aiHost.getAiApiV2(), appKey);
         } catch (Exception e) {
             throw new RuntimeException("AI服务调用失败", e);
         }

+ 5 - 0
fs-service/src/main/java/com/fs/his/domain/FsCourseCouponUser.java

@@ -43,5 +43,10 @@ public class FsCourseCouponUser extends BaseEntity{
     @Excel(name = "核销状态 0-未核销 1-已核销")
     private Integer status;
 
+    /**
+     * 课程小节ID
+     */
+    private Long videoId;
+
 
 }

+ 4 - 0
fs-service/src/main/java/com/fs/his/mapper/FsCourseCouponMapper.java

@@ -3,6 +3,7 @@ package com.fs.his.mapper;
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.his.domain.FsCourseCoupon;
+import org.apache.ibatis.annotations.Select;
 
 /**
  * 课程优惠券Mapper接口
@@ -58,4 +59,7 @@ public interface FsCourseCouponMapper extends BaseMapper<FsCourseCoupon>{
      * @return 结果
      */
     int deleteFsCourseCouponByIds(Long[] ids);
+
+    @Select("SELECT id,title FROM fs_course_coupon WHERE `status` = 1")
+    List<FsCourseCoupon> selectFsCourseCouponOptions();
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/mapper/FsCourseCouponUserMapper.java

@@ -3,6 +3,8 @@ package com.fs.his.mapper;
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.his.domain.FsCourseCouponUser;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 /**
  * 用户看课优惠券Mapper接口
@@ -58,4 +60,7 @@ public interface FsCourseCouponUserMapper extends BaseMapper<FsCourseCouponUser>
      * @return 结果
      */
     int deleteFsCourseCouponUserByIds(Long[] ids);
+
+    @Select("SELECT count(*) FROM fs_course_coupon_user WHERE user_id = #{userId}  AND coupon_id = #{couponId}")
+    Integer selectCountByUserIdAndCouponId(@Param("userId") Long userId,@Param("couponId") Long couponId);
 }

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

@@ -72,9 +72,12 @@ public interface FsUserIntegralLogsMapper
      */
     public int deleteFsUserIntegralLogsByIds(Long[] ids);
     @Select({"<script> " +
-            "select l.*,u.nick_name,u.phone from fs_user_integral_logs l LEFT JOIN fs_user u ON u.user_id=l.user_id "+
+            "select l.id,l.user_id,l.log_type,l.integral,l.balance,l.business_id,l.create_time,l.business_type,l.status,u.nick_name,u.phone " +
+            "from fs_user_integral_logs l " +
+            "LEFT JOIN fs_user u ON u.user_id=l.user_id "+
             " <where>  \n" +
             "            <if test=\"userId != null \"> and l.user_id = #{userId}</if>\n" +
+            "            <if test=\"nick_name != null \"> and u.nick_name = #{nickName}</if>\n" +
             "            <if test=\"logType != null  and logType != ''\"> and log_type = #{logType}</if>\n" +
             "            <if test=\"phone != null \"> and u.phone = #{phone}</if>\n" +
             "            <if test=\"businessId != null  and businessId != ''\"> and business_id = #{businessId}</if>\n" +

+ 17 - 0
fs-service/src/main/java/com/fs/his/param/CourseFinishRewardParam.java

@@ -0,0 +1,17 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+@Data
+public class CourseFinishRewardParam {
+
+    private Long companyId;
+
+    private Long periodId;
+
+    private Long userId;
+
+    private Long videoId;
+
+
+}

+ 11 - 0
fs-service/src/main/java/com/fs/his/service/IFsCourseCouponService.java

@@ -2,6 +2,7 @@ package com.fs.his.service;
 
 import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsCourseCoupon;
 
 /**
@@ -58,4 +59,14 @@ public interface IFsCourseCouponService extends IService<FsCourseCoupon>{
      * @return 结果
      */
     int deleteFsCourseCouponById(Long id);
+
+    List<FsCourseCoupon> selectFsCourseCouponOptions();
+
+    /**
+     * 发送课程优惠券
+     * @param videoId 小节Id
+     * @param userId 用户Id
+     */
+    R sendAutoCourseCoupon(Long videoId, Long userId,Long companyId);
+    R sendCourseCoupon(Long videoId, Long userId,Long companyId,Long periodId);
 }

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

@@ -2,6 +2,7 @@ package com.fs.his.service;
 
 import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
 import com.fs.his.domain.FsCourseCouponUser;
 
 /**
@@ -58,4 +59,6 @@ public interface IFsCourseCouponUserService extends IService<FsCourseCouponUser>
      * @return 结果
      */
     int deleteFsCourseCouponUserById(Long id);
+
+    R useCoupon(Long userId,Long couponUserId);
 }

+ 184 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsCourseCouponServiceImpl.java

@@ -1,13 +1,29 @@
 package com.fs.his.service.impl;
 
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
+
+import cn.hutool.json.JSONUtil;
+import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.course.config.CourseConfig;
+import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.course.domain.FsUserCourseVideoRedPackage;
+import com.fs.course.mapper.FsUserCourseVideoMapper;
+import com.fs.course.mapper.FsUserCourseVideoRedPackageMapper;
+import com.fs.his.domain.FsCourseCouponUser;
+import com.fs.his.mapper.FsCourseCouponUserMapper;
+import com.fs.his.vo.CourseFinishRewardVO;
+import com.fs.system.service.ISysConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.his.mapper.FsCourseCouponMapper;
 import com.fs.his.domain.FsCourseCoupon;
 import com.fs.his.service.IFsCourseCouponService;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 课程优惠券Service业务层处理
@@ -18,6 +34,17 @@ import com.fs.his.service.IFsCourseCouponService;
 @Service
 public class FsCourseCouponServiceImpl extends ServiceImpl<FsCourseCouponMapper, FsCourseCoupon> implements IFsCourseCouponService {
 
+    @Autowired
+    private FsCourseCouponUserMapper courseCouponUserMapper;
+
+    @Autowired
+    private FsUserCourseVideoMapper userCourseVideoMapper;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private FsUserCourseVideoRedPackageMapper fsUserCourseVideoRedPackageMapper;
     /**
      * 查询课程优惠券
      * 
@@ -92,4 +119,161 @@ public class FsCourseCouponServiceImpl extends ServiceImpl<FsCourseCouponMapper,
     {
         return baseMapper.deleteFsCourseCouponById(id);
     }
+
+    @Override
+    public List<FsCourseCoupon> selectFsCourseCouponOptions() {
+        return baseMapper.selectFsCourseCouponOptions();
+    }
+
+    //自动
+    @Override
+    @Transactional
+    public R sendAutoCourseCoupon(Long videoId, Long userId,Long companyId) {
+        CourseFinishRewardVO rewardVO = new CourseFinishRewardVO();
+
+        Integer integral = null;
+        BigDecimal amount = null;
+        String couponName = null;
+
+        boolean isSend = true;
+        //课程小节信息
+        FsUserCourseVideo courseVideo = userCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
+        if (courseVideo == null) {
+            return R.error("课程小节不存在");
+        }
+
+        //优惠券
+        FsCourseCoupon fsCourseCoupon = baseMapper.selectFsCourseCouponById(courseVideo.getCourseCouponId());
+        if (fsCourseCoupon != null) {
+            if (fsCourseCoupon.getStatus() != 1) {
+                isSend = false;
+            }
+            if (fsCourseCoupon.getRemainNumber() <= 0) {
+                isSend = false;
+            }
+            //用户领取优惠券总数
+            Integer count = courseCouponUserMapper.selectCountByUserIdAndCouponId(userId, courseVideo.getCourseCouponId());
+            if (count >= fsCourseCoupon.getLimitCount()) {
+                isSend = false;
+            }
+        } else {
+            isSend = false;
+        }
+
+        if (isSend) {
+            //发放优惠券
+            FsCourseCouponUser couponUser = new FsCourseCouponUser();
+            couponUser.setCouponId(courseVideo.getCourseCouponId());
+            couponUser.setUserId(userId);
+            couponUser.setStartTime(new Date());
+            couponUser.setLimitTime(fsCourseCoupon.getLimitTime());
+            couponUser.setCreateTime(new Date());
+            int i = courseCouponUserMapper.insertFsCourseCouponUser(couponUser);
+
+            //返回的优惠券名称
+            couponName = fsCourseCoupon.getTitle();
+            if (i > 0) {
+                FsCourseCoupon coupon = new FsCourseCoupon();
+                coupon.setId(courseVideo.getCourseCouponId());
+                coupon.setRemainNumber(fsCourseCoupon.getRemainNumber() - 1);
+                baseMapper.updateFsCourseCoupon(coupon);
+            }
+        }
+        // 获取配置信息
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        Integer rewardType = config.getRewardType();
+
+        if (rewardType == 1) {
+            FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByVideoIdAndType(videoId, companyId, 1);
+            if (redPackage != null && redPackage.getRedPacketMoney() != null) {
+                amount = redPackage.getRedPacketMoney();
+            } else if (courseVideo.getRedPacketMoney() != null) {
+                amount = courseVideo.getRedPacketMoney();
+            }
+        }
+        if (rewardType == 2) {
+            integral = config.getAnswerIntegral();
+        }
+        rewardVO.setCouponName(couponName);
+        rewardVO.setIntegral(integral);
+        rewardVO.setRedPacketMoney(amount);
+        return R.ok().put("data",rewardVO);
+    }
+
+    //手动
+    @Transactional
+    @Override
+    public R sendCourseCoupon(Long videoId, Long userId,Long companyId,Long periodId) {
+        CourseFinishRewardVO rewardVO = new CourseFinishRewardVO();
+
+        Integer integral = null;
+        BigDecimal amount = null;
+        String couponName = null;
+
+        boolean isSend = true;
+        //课程小节信息
+        FsUserCourseVideo courseVideo = userCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
+        if (courseVideo == null) {
+            return R.error("课程小节不存在");
+        }
+
+        //优惠券
+        FsCourseCoupon fsCourseCoupon = baseMapper.selectFsCourseCouponById(courseVideo.getCourseCouponId());
+        if (fsCourseCoupon != null) {
+            if (fsCourseCoupon.getStatus() != 1) {
+                isSend = false;
+            }
+            if (fsCourseCoupon.getRemainNumber() <= 0) {
+                isSend = false;
+            }
+            //用户领取优惠券总数
+            Integer count = courseCouponUserMapper.selectCountByUserIdAndCouponId(userId, courseVideo.getCourseCouponId());
+            if (count >= fsCourseCoupon.getLimitCount()) {
+                isSend = false;
+            }
+        } else {
+            isSend = false;
+        }
+
+        if (isSend) {
+            //发放优惠券
+            FsCourseCouponUser couponUser = new FsCourseCouponUser();
+            couponUser.setCouponId(courseVideo.getCourseCouponId());
+            couponUser.setUserId(userId);
+            couponUser.setStartTime(new Date());
+            couponUser.setLimitTime(fsCourseCoupon.getLimitTime());
+            couponUser.setCreateTime(new Date());
+            int i = courseCouponUserMapper.insertFsCourseCouponUser(couponUser);
+
+            //返回的优惠券名称
+            couponName = fsCourseCoupon.getTitle();
+            if (i > 0) {
+                FsCourseCoupon coupon = new FsCourseCoupon();
+                coupon.setId(courseVideo.getCourseCouponId());
+                coupon.setRemainNumber(fsCourseCoupon.getRemainNumber() - 1);
+                baseMapper.updateFsCourseCoupon(coupon);
+            }
+        }
+        // 获取配置信息
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        Integer rewardType = config.getRewardType();
+
+        if (rewardType == 1) {
+            FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(videoId,companyId,periodId);
+            if (redPackage != null && redPackage.getRedPacketMoney() != null) {
+                amount = redPackage.getRedPacketMoney();
+            } else if (courseVideo.getRedPacketMoney() != null) {
+                amount = courseVideo.getRedPacketMoney();
+            }
+        }
+        if (rewardType == 2) {
+            integral = config.getAnswerIntegral();
+        }
+        rewardVO.setCouponName(couponName);
+        rewardVO.setIntegral(integral);
+        rewardVO.setRedPacketMoney(amount);
+        return R.ok().put("data",rewardVO);
+    }
 }

+ 30 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsCourseCouponUserServiceImpl.java

@@ -1,6 +1,10 @@
 package com.fs.his.service.impl;
 
+import java.util.Date;
 import java.util.List;
+import java.util.Objects;
+
+import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -91,4 +95,30 @@ public class FsCourseCouponUserServiceImpl extends ServiceImpl<FsCourseCouponUse
     {
         return baseMapper.deleteFsCourseCouponUserById(id);
     }
+
+    @Override
+    public R useCoupon(Long userId, Long couponUserId) {
+        FsCourseCouponUser couponUser = baseMapper.selectFsCourseCouponUserById(couponUserId);
+        if (couponUser == null) {
+            return R.error("优惠券不存在");
+        }
+        if (couponUser.getStatus() != 0) {
+            return R.error("优惠券已使用");
+        }
+        if (!Objects.equals(couponUser.getUserId(), userId)) {
+            return R.error("优惠券不属于当前用户");
+        }
+        Date now = new Date();
+        if (now.after(couponUser.getLimitTime())) {
+            return R.error("优惠券已过期");
+        }
+        FsCourseCouponUser map = new FsCourseCouponUser();
+        map.setId(couponUser.getCouponId());
+        map.setStatus(1);
+        int i = baseMapper.updateById(map);
+        if (i > 0) {
+            return R.ok("优惠券使用成功");
+        }
+        return R.error("优惠券使用失败");
+    }
 }

+ 2 - 2
fs-service/src/main/java/com/fs/his/service/impl/FsUserInvitedServiceImpl.java

@@ -188,13 +188,13 @@ public class FsUserInvitedServiceImpl extends ServiceImpl<FsUserInvitedMapper, F
 //            }
 //        }
         //2.添加奖励
-        //2.1被邀请人获得2000芳华币
+        //2.1被邀请人获得2000积分
         FsUserAddIntegralTemplateParam invitedParam = new FsUserAddIntegralTemplateParam();
         invitedParam.setLogType(FsUserIntegralLogTypeEnum.TYPE_19.getValue());
         invitedParam.setUserId(invitedUserId);
         invitedParam.setBusinessId(userId.toString());
         R invitedR = integralLogsService.addIntegralTemplate(invitedParam);
-        //2.2邀请人A获得1000芳华币
+        //2.2邀请人A获得1000积分
         FsUserAddIntegralTemplateParam param = new FsUserAddIntegralTemplateParam();
         param.setUserId(userId);
         param.setLogType(FsUserIntegralLogTypeEnum.TYPE_18.getValue());

+ 15 - 0
fs-service/src/main/java/com/fs/his/vo/CourseFinishRewardVO.java

@@ -0,0 +1,15 @@
+package com.fs.his.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CourseFinishRewardVO {
+
+    private String couponName;
+
+    private BigDecimal redPacketMoney;
+
+    private Integer integral;
+}

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

@@ -27,7 +27,7 @@ public class GetFsIntegralCartDetailsVo {
     @ApiModelProperty("所有商品所需积分之和")
     private Long goodsIntegralTotal;
 
-    @ApiModelProperty("用户的芳华币总数")
+    @ApiModelProperty("用户的积分总数")
     private BigDecimal userIntegral;
 
     @ApiModelProperty("商品信息")

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

@@ -56,7 +56,7 @@ public class GetFsIntegralCartListVo {
     @ApiModelProperty("购买的商品数量")
     private Integer cartNum;
 
-    @ApiModelProperty("用户的芳华币总数")
+    @ApiModelProperty("用户的积分总数")
     private BigDecimal userIntegral;
 
     @ApiModelProperty("是否选中:1是,0否")

+ 7 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreAfterSalesScrm.java

@@ -146,6 +146,7 @@ public class FsStoreAfterSalesScrm extends BaseEntity
     /** 退款原因字典二级 ID */
     private Long reasonId2;
 
+
     /** 售后一级原因(文字,与 reason_id1 对应名称快照) */
     private String reasonLevel1Text;
 
@@ -180,4 +181,10 @@ public class FsStoreAfterSalesScrm extends BaseEntity
     @TableField(exist = false)
     private String bankTransactionId;
 
+    /**
+    * 订单类型
+    */
+    @TableField(exist = false)
+    private Integer orderType;
+
 }

+ 3 - 3
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderItemScrmMapper.java

@@ -76,7 +76,7 @@ public interface FsStoreOrderItemScrmMapper
     List<FsStoreOrderItemVO> selectFsStoreOrderItemListAndProductByOrderId(Long id);
 
     @Select({"<script> " +
-            "select i.*,o.user_id,u.nickname,psps.cost,o.pay_postage,o.total_num,o.status,fspcs.cate_name, o.real_name,o.user_phone,o.user_address,o.create_time,o.pay_time,o.delivery_sn,o.delivery_name,o.delivery_id, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber,o.upload_time ,CASE WHEN o.certificates IS NULL OR o.certificates = '' THEN 0 ELSE 1 END AS is_upload,p.title as package_name,cts.name as scheduleName,sp_latest.pay_money, sp_latest.bank_transaction_id as bankTransactionId, o.delivery_send_time," +
+            "select i.*,o.user_id,u.nick_name,psps.cost,o.pay_postage,o.total_num,o.status,fspcs.cate_name, o.real_name,o.user_phone,o.user_address,o.create_time,o.pay_time,o.delivery_sn,o.delivery_name,o.delivery_id, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber,o.upload_time ,CASE WHEN o.certificates IS NULL OR o.certificates = '' THEN 0 ELSE 1 END AS is_upload,p.title as package_name,cts.name as scheduleName,sp_latest.pay_money, sp_latest.bank_transaction_id as bankTransactionId, o.delivery_send_time," +
             " o.order_code, o.pay_price, o.pay_money, o.deduction_price,o.pay_delivery, o.order_type,psps.price " +
             ", CASE o.is_audit WHEN 1 THEN '是' ELSE '否' END AS isAudit " +
             ", sas.audit_remark as auditRemark, sas.reason_level1_text as reasonValue1, sas.reason_level2_text as reasonValue2 " +
@@ -125,7 +125,7 @@ public interface FsStoreOrderItemScrmMapper
             " and o.delivery_id =#{maps.deliveryId} " +
             "</if>" +
             "<if test = 'maps.nickname != null and  maps.nickname !=\"\"     '> " +
-            "and u.nickname like CONCAT('%',#{maps.nickname},'%') " +
+            "and u.nick_name like CONCAT('%',#{maps.nickname},'%') " +
             "</if>" +
             "<if test=\"maps.realName != null and  maps.realName !=''\">" +
             " and o.real_name like CONCAT('%',#{maps.realName},'%') " +
@@ -280,7 +280,7 @@ public interface FsStoreOrderItemScrmMapper
             " and o.delivery_id =#{maps.deliveryId} " +
             "</if>" +
             "<if test = 'maps.nickname != null and  maps.nickname !=\"\"     '> " +
-            "and u.nickname like CONCAT('%',#{maps.nickname},'%') " +
+            "and u.nick_name like CONCAT('%',#{maps.nickname},'%') " +
             "</if>" +
             "<if test=\"maps.realName != null and  maps.realName !=''\">" +
             " and o.real_name like CONCAT('%',#{maps.realName},'%') " +

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

@@ -53,7 +53,7 @@ public interface FsStoreOrderScrmMapper
      * @return 订单集合
      */
     public List<FsStoreOrderScrm> selectFsStoreOrderList(FsStoreOrderScrm fsStoreOrder);
-    
+
         /**
          * 查询待发放购物积分的订单列表
          */
@@ -479,7 +479,9 @@ public interface FsStoreOrderScrmMapper
     List<FsPromotionOrderVO> selectFsPromotionOrderListVO(@Param("maps")FsStoreOrderParam param);
 
     @Select({"<script> " +
-            "select o.id,o.order_code,o.item_json,o.pay_price,o.status,o.is_package,o.package_json,o.delivery_id,o.finish_time,o.company_id,o.company_user_id,o.live_id  from fs_store_order_scrm o  " +
+            "select o.id,o.order_code,o.item_json,o.pay_price,o.status,o.is_package,o.package_json,o.delivery_id,o.finish_time,o.company_id," +
+            "o.company_user_id,o.live_id,o.order_type " +
+            "from fs_store_order_scrm o  " +
             "where o.is_del=0 and o.is_sys_del=0 " +
             "<if test = 'maps.status != null and maps.status != \"\"     '> " +
             "and o.status =#{maps.status} " +

+ 21 - 11
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -154,6 +154,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.google.common.base.Joiner;
 import com.google.gson.Gson;
+import jodd.util.StringUtil;
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -644,6 +645,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     oldStatus = existing.getStatus();
                 }
             }
+            if (StringUtil.isNotBlank(fsStoreOrder.getDeliveryId())) {
+                StringBuilder stringBuilder = new StringBuilder();
+                FsExpressScrm fsExpressScrm = tryResolveExpressByLogisticCode(fsStoreOrder.getDeliveryId(), fsStoreOrder.getOrderCode(), stringBuilder);
+                fsStoreOrder.setDeliveryName(fsExpressScrm == null ? " ": fsExpressScrm.getName());
+                fsStoreOrder.setDeliverySn(fsExpressScrm == null ? " ": fsExpressScrm.getCode());
+            }
+
             int rows = fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder);
             if (rows > 0 && orderId != null && newStatus != null && (newStatus == 2 || newStatus == 3)
                     && (oldStatus == null || !oldStatus.equals(newStatus))) {
@@ -2291,18 +2299,20 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             if (express == null) {
                 express = selectExpressByOmsDeliverCode(deliverCode);
             }
+
+            if (kdnDeliverName.length() > 0) {
+                deliverName = kdnDeliverName.toString();
+            }
+            // 卓美需求,查询失败,也要修改订单号码
+            order.setDeliveryName(deliverName);
+            order.setDeliverySn(express == null ? "" :  express.getCode());
+            order.setDeliveryId(deliveryId);
+            order.setDeliverySendTime(new Date());
+            fsStoreOrderMapper.updateFsStoreOrder(order);
+            orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
+                    OrderLogEnum.DELIVERY_GOODS.getDesc());
+            //订阅物流回调
             if (express != null) {
-                if (kdnDeliverName.length() > 0) {
-                    deliverName = kdnDeliverName.toString();
-                }
-                order.setDeliveryName(deliverName);
-                order.setDeliverySn(express.getCode());
-                order.setDeliveryId(deliveryId);
-                order.setDeliverySendTime(new Date());
-                fsStoreOrderMapper.updateFsStoreOrder(order);
-                orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
-                        OrderLogEnum.DELIVERY_GOODS.getDesc());
-                //订阅物流回调
                 String lastFourNumber = "";
                 if (express.getCode().equals(ShipperCodeEnum.SF.getValue())  || express.getCode().equals(ShipperCodeEnum.ZTO.getValue())) {
                     lastFourNumber = order.getUserPhone();

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsMyStoreOrderListQueryVO.java

@@ -49,5 +49,7 @@ public class FsMyStoreOrderListQueryVO implements Serializable
 
     private Long liveId;
 
+    private Long orderType;
+
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreAfterSalesQueryVO.java

@@ -89,6 +89,8 @@ public class FsStoreAfterSalesQueryVO implements Serializable
 
     private Long liveId;
 
+    private Long orderType;
+
 
     List<FsStoreAfterSalesItemScrm> items;
 

+ 2 - 2
fs-service/src/main/java/com/fs/live/domain/LiveUserRedRecord.java

@@ -30,8 +30,8 @@ public class LiveUserRedRecord extends BaseEntity{
     @Excel(name = "中奖用户ID")
     private Long userId;
 
-    /** 芳华币数量 */
-    @Excel(name = "芳华币数量")
+    /** 积分数量 */
+    @Excel(name = "积分数量")
     private Long integral;
 
 

+ 22 - 22
fs-service/src/main/java/com/fs/live/service/impl/LiveRedConfServiceImpl.java

@@ -131,7 +131,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
             double score = localDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli();
             redisCache.redisTemplate.opsForZSet().add(cacheKey, String.valueOf(liveRedConf.getRedId()), score);
             redisCache.redisTemplate.expire(cacheKey, 30, TimeUnit.MINUTES);
-            
+
             // 将红包配置缓存到 Redis(用于高并发查询)
             String redConfCacheKey = REDPACKET_CONF_CACHE_KEY + liveRedConf.getRedId();
             redisCache.setCacheObject(redConfCacheKey, JSONUtil.toJsonStr(liveRedConf), liveRedConf.getDuration().intValue() + 5, TimeUnit.MINUTES);
@@ -243,7 +243,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
 //                * 4. 异步更新数据库
         String redisKey = String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_RED, red.getLiveId(), red.getRedId());
         String userIdStr = String.valueOf(red.getUserId());
-        
+
         // 1. 使用 Redis HSETNX 原子操作保证幂等性(每个用户只能领取一次)
         // 先尝试在 Redis 中标记用户已领取(原子操作,保证高并发安全)
         LiveUserRedRecord record = new LiveUserRedRecord();
@@ -251,7 +251,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
         record.setLiveId(red.getLiveId());
         record.setUserId(red.getUserId());
         record.setCreateTime(new Date());
-        
+
         // 使用 HSETNX 原子操作:如果字段不存在则设置,返回 true;如果已存在则返回 false
         Boolean claimed = redisCache.hashPutIfAbsent(redisKey, userIdStr, "claimed");
         if (Boolean.FALSE.equals(claimed)) {
@@ -261,13 +261,13 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
         } else {
             redisCache.expire(redisKey, 24, TimeUnit.HOURS);
         }
-        
+
         try {
             // 2. 从 Redis 读取红包配置(优先从缓存读取,提高响应速度)
             String redConfCacheKey = REDPACKET_CONF_CACHE_KEY + red.getRedId();
             Object confCache = redisCache.getCacheObject(redConfCacheKey);
             LiveRedConf conf = null;
-            
+
             if (confCache != null) {
                 try {
                     conf = JSONUtil.toBean(confCache.toString(), LiveRedConf.class);
@@ -276,7 +276,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                     log.warn("从 Redis 缓存解析红包配置失败,从数据库读取,redId: {}", red.getRedId(), e);
                 }
             }
-            
+
             // 如果 Redis 中没有配置,从数据库读取并缓存
             if (conf == null) {
                 conf = baseMapper.selectLiveRedConfByRedId(red.getRedId());
@@ -286,14 +286,14 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                     log.debug("从数据库读取红包配置并缓存到 Redis,redId: {}", red.getRedId());
                 }
             }
-            
+
             // 验证红包状态
             if (conf == null || conf.getRedStatus() != 1) {
                 // 回滚:删除 Redis 中的标记
                 redisCache.hashDelete(redisKey, userIdStr);
                 return R.error("手慢了,红包已结束~");
             }
-            
+
             // 3. 使用 Redis 原子操作减少剩余数量
             if (getRemaining(red.getRedId()) <= 0 || !decreaseRemainingLotsIfPossible(red.getRedId())) {
                 // 回滚:删除 Redis 中的标记
@@ -307,7 +307,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                 redisCache.deleteObject(redConfCacheKey);
                 return R.error("手慢了,红包已被抢完~");
             }
-            
+
             // 计算积分(平均分)
             Long integral = calculateIntegralAverage(conf);
             if (0L == integral) {
@@ -315,9 +315,9 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                 redisCache.hashDelete(redisKey, userIdStr);
                 return R.error("手慢了,红包被抢完了~");
             }
-            
+
             record.setIntegral(integral);
-            
+
             // 4. 更新用户积分(同步操作,保证数据一致性)
             BigDecimal balanceAmount = BigDecimal.valueOf(integral);
             int updateResult = fsUserScrmMapper.incrIntegral(red.getUserId(), balanceAmount);
@@ -330,22 +330,22 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                 log.error("更新用户余额失败,userId: {}, balance: {}", red.getUserId(), balanceAmount);
                 return R.error("更新用户余额失败");
             }
-            
+
             // 5. 更新 Redis 缓存中的记录(包含完整信息)
             record.setCreateTime(new Date());
             redisCache.hashPut(redisKey, userIdStr, JSONUtil.toJsonStr(record));
-            
+
             // 6. 异步更新数据库(提高响应速度,不阻塞用户)
             // 查询用户当前余额(用于积分日志)
             com.fs.hisStore.domain.FsUserScrm user = fsUserScrmMapper.selectFsUserById(red.getUserId());
             Long currentIntegral = user.getIntegral() != null ? user.getIntegral() : 0L;
-            
+
 
             final LiveUserRedRecord finalRecord = record;
             final LiveRedConf finalConf = conf;
             final Long finalIntegral = integral;
             final Long finalCurrentIntegral = currentIntegral;
-            
+
         try {
             // 插入红包记录
             userRedRecordMapper.insertLiveUserRedRecord(finalRecord);
@@ -368,11 +368,11 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
             log.error("异步更新数据库失败,userId: {}, redId: {}, integral: {}", red.getUserId(), red.getRedId(), finalIntegral, e);
         }
 
-            
 
-            
-            return R.ok("恭喜您成功抢到" + integral + "芳华币");
-            
+
+
+            return R.ok("恭喜您成功抢到" + integral + "积分");
+
         } catch (Exception e) {
             // 发生异常,回滚 Redis 标记
             redisCache.hashDelete(redisKey, userIdStr);
@@ -434,7 +434,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                 liveUserRedRecords = hashEntries.values().stream()
                         .map(value -> JSONUtil.toBean(JSONUtil.parseObj(value), LiveUserRedRecord.class))
                         .collect(Collectors.toList());
-                
+
                 // 过滤掉已经存在于数据库中的记录(避免重复增加积分)
                 List<LiveUserRedRecord> newRecords = new ArrayList<>();
                 for (LiveUserRedRecord liveUserRedRecord : liveUserRedRecords) {
@@ -443,13 +443,13 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
                     queryRecord.setUserId(liveUserRedRecord.getUserId());
                     queryRecord.setRedId(liveUserRedRecord.getRedId());
                     List<LiveUserRedRecord> existingRecords = userRedRecordMapper.selectLiveUserRedRecordList(queryRecord);
-                    
+
                     // 如果不存在,则添加到新记录列表
                     if (existingRecords == null || existingRecords.isEmpty()) {
                         newRecords.add(liveUserRedRecord);
                     }
                 }
-                
+
                 // 只插入新记录(这些记录是从 Redis 同步过来的,但还没有插入数据库)
                 // 注意:积分增加逻辑已移除,现在只能通过 claimRedPacket 方法领取红包并增加积分
                 if (CollUtil.isNotEmpty(newRecords)) {

+ 1 - 1
fs-service/src/main/java/com/fs/qw/service/impl/LuckyBagServiceImpl.java

@@ -135,7 +135,7 @@ public class LuckyBagServiceImpl implements ILuckyBagService
 
         FsUserIntegralLogs fsUserIntegralLogs = new FsUserIntegralLogs();
         fsUserIntegralLogs.setUserId(userId);
-        fsUserIntegralLogs.setLogType(30); // 福袋获取获得芳华币
+        fsUserIntegralLogs.setLogType(30); // 福袋获取获得积分
         fsUserIntegralLogs.setIntegral(coinAmount);
         fsUserIntegralLogs.setPhone(user.getPhone());
         fsUserIntegralLogs.setBalance(balance);

+ 3 - 1
fs-service/src/main/resources/application-config-dev.yml

@@ -126,6 +126,7 @@ ipad:
   aiApi: http://1.95.196.10:3000/api
   voiceApi:
   commonApi:
+  aiApiV2: http://1.95.196.10:3000/api
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:
@@ -138,7 +139,8 @@ jst:
   authorization_code: 666666
   shop_code: "18461733"
 weizou:
-  baseUrl: http://113.105.104.56:9620
+#  baseUrl: http://113.105.104.56:9620
+  baseUrl: https://test-api.weizou.com:9702/
 #  appId:
 #  appSecret:
 #  createName:

+ 1 - 0
fs-service/src/main/resources/application-config-druid-sxjz.yml

@@ -102,6 +102,7 @@ ipad:
   wxIpadUrl:
   voiceApi:
   commonApi:
+  aiApiV2: http://1.95.196.10:3000/api
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:

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

@@ -40,6 +40,7 @@
         <result property="projectId"    column="project_id"    />
         <result property="isFirst"    column="is_first"    />
         <result property="courseIntroImg"    column="course_intro_img"    />
+        <result property="courseCouponId"    column="course_coupon_id"    />
     </resultMap>
 
     <sql id="selectFsUserCourseVideoVo">
@@ -118,6 +119,7 @@
             <if test="jobId != null">job_id,</if>
             <if test="vid != null">vid,</if>
             <if test="courseIntroImg != null">course_intro_img,</if>
+            <if test="courseCouponId != null">course_coupon_id,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="fileId != null">#{fileId},</if>
@@ -163,6 +165,7 @@
             <if test="jobId != null">#{jobId},</if>
             <if test="vid != null">#{vid},</if>
             <if test="courseIntroImg != null">#{courseIntroImg},</if>
+            <if test="courseCouponId != null">#{courseCouponId},</if>
         </trim>
     </insert>
     <insert id="insertBatchFsUserCourseVideo" parameterType="FsUserCourseVideo" useGeneratedKeys="true" keyProperty="videoId">
@@ -259,6 +262,8 @@
             <if test="vid != null">vid = #{vid},</if>
             <if test="courseIntroImg != null">course_intro_img = #{courseIntroImg},</if>
             <if test="courseIntroImg == null">course_intro_img = null,</if>
+            <if test="courseCouponId != null">course_coupon_id = #{courseCouponId},</if>
+            <if test="courseCouponId == null">course_coupon_id = null,</if>
         </trim>
         where video_id = #{videoId}
     </update>

+ 5 - 1
fs-service/src/main/resources/mapper/his/FsCourseCouponUserMapper.xml

@@ -13,10 +13,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
         <result property="status"    column="status"    />
+        <result property="videoId"    column="video_id"    />
     </resultMap>
 
     <sql id="selectFsCourseCouponUserVo">
-        select id, coupon_id, user_id, limit_time, start_time, create_time, update_time, status from fs_course_coupon_user
+        select id, coupon_id, user_id, limit_time, start_time, create_time, update_time, status, video_id from fs_course_coupon_user
     </sql>
 
     <select id="selectFsCourseCouponUserList" parameterType="FsCourseCouponUser" resultMap="FsCourseCouponUserResult">
@@ -45,6 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
             <if test="status != null">status,</if>
+            <if test="videoId != null">video_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="couponId != null">#{couponId},</if>
@@ -54,6 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">#{createTime},</if>
             <if test="updateTime != null">#{updateTime},</if>
             <if test="status != null">#{status},</if>
+            <if test="videoId != null">#{videoId},</if>
          </trim>
     </insert>
 
@@ -67,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="status != null">status = #{status},</if>
+            <if test="videoId != null">video_id = #{videoId},</if>
         </trim>
         where id = #{id}
     </update>

+ 6 - 2
fs-service/src/main/resources/mapper/hisStore/FsStoreAfterSalesScrmMapper.xml

@@ -37,7 +37,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsStoreAfterSalesVo">
-        select id, order_code, refund_amount, service_type, reasons, explains, explain_img, shipper_code, delivery_sn, delivery_name, status, sales_status ,order_status, create_time, is_del, user_id, consignee, phone_number, address,company_id,company_user_id,is_package,package_json,reason_id1,reason_id2,reason_level1_text,reason_level2_text,audit_remark,audit_reason_name from fs_store_after_sales_scrm
+        select id, order_code, refund_amount, service_type, reasons, explains, explain_img, shipper_code, delivery_sn, delivery_name, status, sales_status
+               ,order_status, create_time, is_del, user_id, consignee, phone_number, address,company_id,company_user_id,is_package,package_json,reason_id1
+             ,reason_id2,reason_level1_text,reason_level2_text,audit_remark,audit_reason_name
+        from fs_store_after_sales_scrm
     </sql>
 
     <select id="selectFsStoreAfterSalesList" parameterType="FsStoreAfterSalesScrm" resultMap="FsStoreAfterSalesResult">
@@ -99,7 +102,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         a1.reason_level2_text,
         a1.audit_remark,
         a1.audit_reason_name,
-        a2.live_id as liveId
+        a2.live_id as liveId,
+        a2.order_type
         from fs_store_after_sales_scrm a1
         left join fs_store_order_scrm a2
         on a1.order_code = a2.order_code

+ 3 - 1
fs-service/src/main/resources/mapper/qw/QwUserMapper.xml

@@ -36,6 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="videoGetStatus"    column="video_get_status"    />
         <result property="updateTime"    column="update_time"    />
         <result property="aiStatus"    column="ai_status"    />
+        <result property="remark"    column="remark"    />
     </resultMap>
 
     <sql id="selectQwUserVo">
@@ -43,7 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                ipad_status,config_id,vid,uid,contact_way,app_key, qw_user_name, department,
                openid, company_id, company_user_id, corp_id, status, is_del, welcome_text,
                welcome_image, is_send_msg,app_key,qw_hook_id,fastGpt_role_id,login_status,
-               tool_status,login_code_url,version,update_time,ai_status from qw_user
+               tool_status,login_code_url,version,update_time,ai_status,remark from qw_user
         </sql>
 
     <select id="selectQwUserList" parameterType="QwUser" resultMap="QwUserResult">
@@ -189,6 +190,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isAuto != null">is_auto = #{isAuto},</if>
             <if test="videoGetStatus != null">video_get_status = #{videoGetStatus},</if>
             <if test="aiStatus != null">ai_status = #{aiStatus},</if>
+            <if test="remark != null">remark = #{remark},</if>
         </trim>
         where id = #{id}
     </update>

+ 43 - 0
fs-user-app/src/main/java/com/fs/app/controller/FsCourseCouponController.java

@@ -0,0 +1,43 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.his.param.CourseFinishRewardParam;
+import com.fs.his.service.IFsCourseCouponService;
+import io.swagger.annotations.Api;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api("课程优惠券接口")
+@RestController
+@RequestMapping(value="/app/courseCoupon")
+public class FsCourseCouponController extends AppBaseController {
+
+    Logger logger= LoggerFactory.getLogger(getClass());
+    @Autowired
+    private IFsCourseCouponService fsCourseCouponService;
+
+
+    @Login
+    @PostMapping("/sendAutoReward")
+    public R sendAutoCourseCoupon(@RequestBody CourseFinishRewardParam param){
+        long userId = Long.parseLong(getUserId());
+        param.setUserId(userId);
+        logger.info("发送自动课程优惠券参数:{}",param);
+        return fsCourseCouponService.sendAutoCourseCoupon(param.getVideoId(),param.getUserId(),param.getCompanyId());
+    }
+
+    @Login
+    @PostMapping("/sendReward")
+    public R sendCourseCoupon(@RequestBody CourseFinishRewardParam param){
+        long userId = Long.parseLong(getUserId());
+        param.setUserId(userId);
+        logger.info("发送课程优惠券参数:{}",param);
+        return fsCourseCouponService.sendCourseCoupon(param.getVideoId(),param.getUserId(),param.getCompanyId(),param.getPeriodId());
+    }
+}

+ 18 - 0
fs-user-app/src/main/java/com/fs/app/controller/SysConfigController.java

@@ -1,10 +1,13 @@
 package com.fs.app.controller;
 
 import com.fs.common.core.domain.R;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.service.impl.FsCoursePlaySourceConfigServiceImpl;
 import com.fs.his.param.FsDiagnosisListDParam;
 import com.fs.system.service.ISysConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -16,6 +19,9 @@ public class SysConfigController {
     @Autowired
     private ISysConfigService sysConfigService;
 
+    @Autowired
+    private FsCoursePlaySourceConfigServiceImpl selectConfigByKey;
+
 
     //获取APP推广信息
     @GetMapping("/getAppPromotion")
@@ -23,4 +29,16 @@ public class SysConfigController {
         String selectConfigByKey = sysConfigService.selectConfigByKey("app.config");
         return R.ok().put("data", selectConfigByKey);
     }
+
+    /**
+    * 根据appid 获取小程序的客服电话和备案号
+    */
+
+    @GetMapping("/getMiniCustomerNumAndRecordNum/{appId}")
+    public R getMiniCustomerNumAndRecordNum(@PathVariable("appId") String appId){
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = selectConfigByKey.selectCoursePlaySourceConfigByAppId(appId);
+
+        return R.ok().put("recordNumber", fsCoursePlaySourceConfig.getRecordNumber()).put("customerNum",fsCoursePlaySourceConfig.getCustomerNum());
+    }
 }
+

+ 4 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/StoreAfterSalesScrmController.java

@@ -103,6 +103,10 @@ public class StoreAfterSalesScrmController extends AppBaseController {
     @ApiOperation(value = "获取售后详情", notes = "获取售后详情")
     public R getAfterSalesDetails(@RequestParam("salesId") Long id) {
         FsStoreAfterSalesScrm sales=storeAfterSalesService.selectFsStoreAfterSalesById(id);
+
+        FsStoreOrderScrm fsStoreOrderScrm = orderService.selectFsStoreOrderByOrderCode(sales.getOrderCode());
+        sales.setOrderType(fsStoreOrderScrm.getOrderType());
+
         FsStoreAfterSalesItemScrm map=new FsStoreAfterSalesItemScrm();
         map.setStoreAfterSalesId(id);
         List<FsStoreAfterSalesItemScrm>  items=salesItemService.selectFsStoreAfterSalesItemList(map);

+ 31 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/StoreProductController.java

@@ -6,9 +6,11 @@ import com.fs.common.core.domain.R;
 import com.fs.common.utils.StringUtils;
 import com.fs.hisStore.domain.FsStoreProductAttrScrm;
 import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
+import com.fs.hisStore.domain.FsStoreProductPurchaseLimitScrm;
 import com.fs.hisStore.domain.FsStoreProductScrm;
 import com.fs.hisStore.service.IFsStoreProductAttrScrmService;
 import com.fs.hisStore.service.IFsStoreProductAttrValueScrmService;
+import com.fs.hisStore.service.IFsStoreProductPurchaseLimitScrmService;
 import com.fs.hisStore.service.IFsStoreProductScrmService;
 import com.fs.hisStore.vo.FsStoreProductListVO;
 import com.github.pagehelper.PageHelper;
@@ -35,6 +37,9 @@ public class StoreProductController extends AppBaseController {
     @Autowired
     private IFsStoreProductAttrScrmService attrService;
 
+    @Autowired
+    private IFsStoreProductPurchaseLimitScrmService purchaseLimitService;
+
     /**
      * 查询本公司下的商城产品列表
      */
@@ -71,6 +76,7 @@ public class StoreProductController extends AppBaseController {
      */
     @ApiOperation("查看商品详情")
     @GetMapping("/{productId}")
+    @Login
     public R getInfo(@PathVariable("productId") Long productId,
                      @RequestParam("companyId") Long companyId,
                      @RequestParam("companyUserId") Long companyUserId) {
@@ -86,10 +92,33 @@ public class StoreProductController extends AppBaseController {
         // 查询商品规格属性值
         List<FsStoreProductAttrScrm> productAttr=attrService.selectFsStoreProductAttrByProductId(product.getProductId());
         List<FsStoreProductAttrValueScrm> productValues=attrValueService.selectFsStoreProductAttrValueByProductId(product.getProductId());
-
+        // 查询限购信息
+        Integer remainingPurchaseLimit = null; // 剩余可购买数量
+        Integer purchasedNum = 0; // 已购买数量
+        if (product.getPurchaseLimit() != null && product.getPurchaseLimit() > 0) {
+            // 商品有限购,查询用户是否购买过
+            String userId = getUserId();
+            if (StringUtils.isNotEmpty(userId)) {
+                FsStoreProductPurchaseLimitScrm purchaseLimit = purchaseLimitService.selectByProductIdAndUserId(
+                        product.getProductId(), Long.parseLong(userId));
+                if (purchaseLimit != null) {
+                    purchasedNum = purchaseLimit.getNum();
+                }
+                // 计算剩余可购买数量
+                remainingPurchaseLimit = product.getPurchaseLimit() - purchasedNum;
+                if (remainingPurchaseLimit < 0) {
+                    remainingPurchaseLimit = 0;
+                }
+            } else {
+                // 未登录用户,剩余可购买数量等于限购数量
+                remainingPurchaseLimit = product.getPurchaseLimit();
+            }
+        }
         return R.ok().put("product", product)
                 .put("productAttr",productAttr)
-                .put("productValues",productValues);
+                .put("productValues",productValues)
+                .put("remainingPurchaseLimit", remainingPurchaseLimit) // 剩余可购买数量
+                .put("purchasedNum", purchasedNum);
     }
 
     /**

Some files were not shown because too many files changed in this diff