Преглед на файлове

Merge remote-tracking branch 'origin/master'

Guos преди 1 седмица
родител
ревизия
cb0d41af86
променени са 56 файла, в които са добавени 1808 реда и са изтрити 136 реда
  1. 139 0
      deploy.sh
  2. 114 0
      fs-admin/src/main/java/com/fs/his/controller/FsStoreActivityController.java
  3. 10 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  4. 94 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserExtractController.java
  5. 1 1
      fs-admin/src/main/resources/application.yml
  6. 3 0
      fs-live-app/src/main/java/com/fs/live/websocket/auth/WebSocketConfigurator.java
  7. 2 0
      fs-live-app/src/main/java/com/fs/live/websocket/constant/AttrConstant.java
  8. 2 1
      fs-live-app/src/main/java/com/fs/live/websocket/handle/LiveChatHandler.java
  9. 71 1
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  10. 1 1
      fs-live-app/src/main/resources/application.yml
  11. 9 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCompanyUserMapper.java
  12. 8 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCompanyUserService.java
  13. 5 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyUserServiceImpl.java
  14. 5 0
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  15. 4 4
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  16. 27 12
      fs-service/src/main/java/com/fs/hisStore/domain/FsUserBillScrm.java
  17. 2 2
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  18. 8 8
      fs-service/src/main/java/com/fs/hisStore/service/IFsUserBillScrmService.java
  19. 5 5
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  20. 9 3
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsUserBillScrmServiceImpl.java
  21. 8 8
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsUserExtractScrmServiceImpl.java
  22. 10 10
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsUserScrmServiceImpl.java
  23. 6 2
      fs-service/src/main/java/com/fs/live/domain/LiveCoupon.java
  24. 7 0
      fs-service/src/main/java/com/fs/live/domain/LiveData.java
  25. 8 0
      fs-service/src/main/java/com/fs/live/domain/LiveMsg.java
  26. 12 0
      fs-service/src/main/java/com/fs/live/domain/LiveWatchUser.java
  27. 11 0
      fs-service/src/main/java/com/fs/live/mapper/LiveCouponIssueUserMapper.java
  28. 4 2
      fs-service/src/main/java/com/fs/live/mapper/LiveDataMapper.java
  29. 8 0
      fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java
  30. 4 1
      fs-service/src/main/java/com/fs/live/mapper/LiveMsgMapper.java
  31. 4 2
      fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java
  32. 7 0
      fs-service/src/main/java/com/fs/live/service/ILiveCouponService.java
  33. 7 0
      fs-service/src/main/java/com/fs/live/service/ILiveGoodsService.java
  34. 2 1
      fs-service/src/main/java/com/fs/live/service/ILiveWatchUserService.java
  35. 47 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveAutoTaskServiceImpl.java
  36. 62 6
      fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java
  37. 52 12
      fs-service/src/main/java/com/fs/live/service/impl/LiveDataServiceImpl.java
  38. 5 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveGoodsServiceImpl.java
  39. 104 4
      fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java
  40. 25 10
      fs-service/src/main/java/com/fs/live/vo/LiveDashBoardDataVo.java
  41. 49 22
      fs-service/src/main/java/com/fs/qw/service/impl/QwWatchLogServiceImpl.java
  42. 131 0
      fs-service/src/main/java/com/fs/store/domain/FsStoreActivity.java
  43. 69 0
      fs-service/src/main/java/com/fs/store/mapper/FsStoreActivityMapper.java
  44. 66 0
      fs-service/src/main/java/com/fs/store/service/IFsStoreActivityService.java
  45. 106 0
      fs-service/src/main/java/com/fs/store/service/impl/FsStoreActivityServiceImpl.java
  46. 100 0
      fs-service/src/main/resources/application-config-druid-bjzm-test.yml
  47. 1 1
      fs-service/src/main/resources/application-config-druid-heyantang.yml
  48. 2 2
      fs-service/src/main/resources/application-config-druid-yxj.yml
  49. 158 0
      fs-service/src/main/resources/application-druid-bjzm-test.yml
  50. 2 2
      fs-service/src/main/resources/application-druid-yxj.yml
  51. 17 0
      fs-service/src/main/resources/mapper/course/FsUserCompanyUserMapper.xml
  52. 18 13
      fs-service/src/main/resources/mapper/hisStore/FsUserBillScrmMapper.xml
  53. 3 0
      fs-service/src/main/resources/mapper/hisStore/FsUserScrmMapper.xml
  54. 95 0
      fs-service/src/main/resources/mapper/store/FsStoreActivityMapper.xml
  55. 63 0
      fs-user-app/src/main/java/com/fs/app/controller/StoreActivityController.java
  56. 16 0
      fs-user-app/src/main/java/com/fs/app/controller/store/H5ScrmController.java

+ 139 - 0
deploy.sh

@@ -0,0 +1,139 @@
+#!/bin/bash
+
+# 各服务对应的远程服务器配置 北京卓美
+declare -A SERVER_CONFIG=(
+    # 服务名:IP地址
+    ["fs-live-app"]="114.132.218.150"
+)
+
+# 通用配置(所有服务器相同)
+REMOTE_USER="root"
+REMOTE_BASE_DIR="/home/software"
+
+# 本地 JAR 包路径
+LOCAL_FS_LIVE_SOCKET_JAR="./fs-live-app/target/fs-live-app.jar"
+
+# 函数:检查本地文件是否存在
+check_local_file() {
+    if [ ! -f "$1" ]; then
+        echo "错误: 本地文件 $1 不存在。"
+        exit 1
+    fi
+}
+
+# 停止远程服务器上可能正在运行的旧版本
+stop_remote_app() {
+    local remote_user=$1
+    local remote_host=$2
+    local app_name=$3
+
+    echo "正在停止 $remote_host 上的 $app_name 服务..."
+    ssh "$remote_user@$remote_host" "pkill -f $app_name || echo '没有找到运行中的进程'"
+}
+
+# 检查服务器连通性
+check_server_connectivity() {
+    local remote_user=$1
+    local remote_host=$2
+
+    if ! ssh -o ConnectTimeout=5 "$remote_user@$remote_host" "echo '连接成功'" &>/dev/null; then
+        echo "错误: 无法连接到服务器 $remote_host"
+        return 1
+    fi
+    return 0
+}
+
+# 部署单个 JAR 包到指定服务器
+deploy_jar() {
+    local local_jar=$1
+    local service_name=$2  # 服务名,用于确定目标服务器
+    local remote_dir=$3     # 远程目录名
+
+    # 获取服务对应的服务器IP
+    local remote_host="${SERVER_CONFIG[$service_name]}"
+    if [ -z "$remote_host" ]; then
+        echo "错误: 未找到服务 $service_name 的服务器配置"
+        return 1
+    fi
+
+    local app_name=$(basename "$local_jar" .jar)
+
+    echo "========================================"
+    echo "开始部署 $service_name 到服务器 $remote_host"
+    echo "本地文件: $local_jar"
+    echo "远程目录: $REMOTE_BASE_DIR/$remote_dir"
+    echo "========================================"
+
+    # 检查本地文件
+    check_local_file "$local_jar"
+
+    # 检查服务器连通性
+    if ! check_server_connectivity "$REMOTE_USER" "$remote_host"; then
+        return 1
+    fi
+
+    # 创建远程目录(如果不存在)
+    echo "创建远程目录..."
+    ssh "$REMOTE_USER@$remote_host" "mkdir -p $REMOTE_BASE_DIR/$remote_dir"
+
+    # 停止旧版本
+    stop_remote_app "$REMOTE_USER" "$remote_host" "$app_name"
+
+    # 上传 JAR 包
+    echo "上传 JAR 包..."
+    scp "$local_jar" "$REMOTE_USER@$remote_host:$REMOTE_BASE_DIR/$remote_dir/"
+
+    # 在后台启动 JAR 包
+    echo "启动服务..."
+    ssh -f "$REMOTE_USER@$remote_host" \
+    "cd $REMOTE_BASE_DIR/$remote_dir && \
+     nohup java -jar  -Dfile.encoding=UTF-8 $app_name.jar --spring.profiles.active=druid-bjzm --server.port=7114  \
+     >> $app_name.log 2>&1 &"
+
+    # 检查进程是否启动成功
+    if ssh "$REMOTE_USER@$remote_host" "pgrep -f $app_name" &>/dev/null; then
+        echo "✓ $service_name 部署成功到 $remote_host"
+    else
+        echo "✗ $service_name 启动失败,请检查日志: $REMOTE_BASE_DIR/$remote_dir/$app_name.log"
+        return 1
+    fi
+
+    echo ""
+}
+
+# 主要部署流程
+echo "开始多服务器分布式部署..."
+echo "部署配置:"
+for service in "${!SERVER_CONFIG[@]}"; do
+    echo "  $service -> ${SERVER_CONFIG[$service]}"
+done
+echo ""
+
+# 部署 fs-live-app
+deploy_jar "$LOCAL_FS_LIVE_SOCKET_JAR" "fs-live-app" "fs-live-app"
+
+# 部署 fs-sync (注意:这里使用了不同的JAR命名方式)
+#deploy_jar "$LOCAL_FS_SYNC_APP_JAR" "fs-sync" "fs-sync"
+
+echo "========================================"
+echo "分布式部署完成!"
+echo "各服务部署状态:"
+for service in "${!SERVER_CONFIG[@]}"; do
+    remote_host="${SERVER_CONFIG[$service]}"
+    echo "  $service -> $remote_host"
+done
+echo "========================================"
+
+# 可选:显示各服务进程状态
+#echo "服务进程状态检查:"
+#for service in "${!SERVER_CONFIG[@]}"; do
+#    remote_host="${SERVER_CONFIG[$service]}"
+#    app_name="$service"  # 简化处理,实际可能需要根据JAR文件名调整
+#    if ssh "$REMOTE_USER@$remote_host" "pgrep -f $app_name" &>/dev/null; then
+#        echo "  ✓ $service 在 $remote_host 上运行正常"
+#    else
+#        echo "  ✗ $service 在 $remote_host 上未运行"
+#    fi
+#done
+
+# 251105 0953

+ 114 - 0
fs-admin/src/main/java/com/fs/his/controller/FsStoreActivityController.java

@@ -0,0 +1,114 @@
+package com.fs.his.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.his.domain.FsPackage;
+import com.fs.his.service.IFsPackageService;
+import com.fs.store.domain.FsStoreActivity;
+import com.fs.store.service.IFsStoreActivityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 活动Controller
+ *
+ * @author fs
+ * @date 2022-11-18
+ */
+@RestController
+@RequestMapping("/his/storeActivity")
+public class FsStoreActivityController extends BaseController
+{
+    @Autowired
+    private IFsStoreActivityService fsStoreActivityService;
+    @Autowired
+    private IFsPackageService packageService;
+    /**
+     * 查询活动列表
+     */
+    @PreAuthorize("@ss.hasPermi('his:storeActivity:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsStoreActivity fsStoreActivity)
+    {
+        startPage();
+        List<FsStoreActivity> list = fsStoreActivityService.selectFsStoreActivityList(fsStoreActivity);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出活动列表
+     */
+    @PreAuthorize("@ss.hasPermi('his:storeActivity:export')")
+    @Log(title = "活动", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsStoreActivity fsStoreActivity)
+    {
+        List<FsStoreActivity> list = fsStoreActivityService.selectFsStoreActivityList(fsStoreActivity);
+        ExcelUtil<FsStoreActivity> util = new ExcelUtil<FsStoreActivity>(FsStoreActivity.class);
+        return util.exportExcel(list, "storeActivity");
+    }
+
+    /**
+     * 获取活动详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('his:storeActivity:query')")
+    @GetMapping(value = "/{activityId}")
+    public R getInfo(@PathVariable("activityId") Long activityId)
+    {
+        FsStoreActivity activity=fsStoreActivityService.selectFsStoreActivityById(activityId);
+        List<FsPackage> packages =new ArrayList<>();
+        String productIds = activity.getProductIds();
+        if(StringUtils.isNotBlank(productIds)){
+            Long[] list = Arrays.stream(productIds.split(","))
+                    .map(Long::valueOf)
+                    .toArray(Long[]::new);
+            packages = packageService.selectFsPackageListByIds(list);
+        }
+        return R.ok().put("activity",activity).put("packages",packages);
+    }
+
+    /**
+     * 新增活动
+     */
+    @PreAuthorize("@ss.hasPermi('his:storeActivity:add')")
+    @Log(title = "活动", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsStoreActivity fsStoreActivity)
+    {
+        return toAjax(fsStoreActivityService.insertFsStoreActivity(fsStoreActivity));
+    }
+
+    /**
+     * 修改活动
+     */
+    @PreAuthorize("@ss.hasPermi('his:storeActivity:edit')")
+    @Log(title = "活动", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsStoreActivity fsStoreActivity)
+    {
+        return toAjax(fsStoreActivityService.updateFsStoreActivity(fsStoreActivity));
+    }
+
+    /**
+     * 删除活动
+     */
+    @PreAuthorize("@ss.hasPermi('his:storeActivity:remove')")
+    @Log(title = "活动", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{activityIds}")
+    public AjaxResult remove(@PathVariable Long[] activityIds)
+    {
+        return toAjax(fsStoreActivityService.deleteFsStoreActivityByIds(activityIds));
+    }
+}

+ 10 - 0
fs-admin/src/main/java/com/fs/his/controller/FsUserController.java

@@ -403,5 +403,15 @@ public class FsUserController extends BaseController
         return userIntegralLogsService.addIntegralTemplate(integralTemplateParam);
     }
 
+    @PreAuthorize("@ss.hasPermi('his:user:unbind')")
+    @Log(title = "批量解绑会员(删除销售和会员的关系)", businessType = BusinessType.DELETE)
+    @DeleteMapping("/batchUnbind")
+    public AjaxResult batchUnbind(@RequestBody List<Long> userIds){
+        if(!userIds.isEmpty()){
+            return toAjax(userCompanyUserService.batchUnbind(userIds));
+        } else {
+            return error("请先选择会员");
+        }
+    }
 
 }

+ 94 - 0
fs-admin/src/main/java/com/fs/his/controller/FsUserExtractController.java

@@ -3,17 +3,35 @@ package com.fs.his.controller;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.IPUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.core.config.WxPayProperties;
+import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserExtract;
 import com.fs.his.param.FsUserExtractParam;
+import com.fs.his.service.IFsUserBillService;
 import com.fs.his.service.IFsUserExtractService;
+import com.fs.his.service.IFsUserService;
 import com.fs.his.vo.FsUserExtractVO;
+import com.fs.hisStore.enums.BillDetailEnum;
+import com.fs.hisStore.service.IFsUserBillScrmService;
+import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
+import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.EntPayService;
+import com.github.binarywang.wxpay.service.WxPayService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 /**
@@ -29,6 +47,17 @@ public class FsUserExtractController extends BaseController
     @Autowired
     private IFsUserExtractService fsUserExtractService;
 
+    @Autowired
+    private WxPayProperties wxPayProperties;
+    @Autowired
+    private IFsUserService fsUserService;
+
+    @Autowired
+    private WxPayService wxPayService;
+
+    @Autowired
+    private IFsUserBillScrmService billService;
+
     /**
      * 查询用户提现管理列表
      */
@@ -96,4 +125,69 @@ public class FsUserExtractController extends BaseController
     {
         return toAjax(fsUserExtractService.deleteFsUserExtractByExtractIds(extractIds));
     }
+
+
+
+    @PreAuthorize("@ss.hasPermi('his:userExtract:audit')")
+    @PostMapping("/audit")
+    @Transactional
+    public R audit(@RequestBody FsUserExtract fsUserExtract, HttpServletRequest servletRequest)
+    {
+        FsUserExtract extract=fsUserExtractService.selectFsUserExtractByExtractId(fsUserExtract.getExtractId());
+        if(extract.getStatus().equals(0)){
+            FsUser user=fsUserService.selectFsUserById(Long.valueOf(extract.getUserId()));
+            if(fsUserExtract.getStatus()==1){
+                WxPayConfig payConfig = new WxPayConfig();
+                payConfig.setAppId(wxPayProperties.getAppId());
+                payConfig.setMchId(wxPayProperties.getMchId());
+                payConfig.setMchKey(wxPayProperties.getMchKey());
+                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setKeyPath(null);
+                payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
+                wxPayService.setConfig(payConfig);
+                EntPayService entPayService=wxPayService.getEntPayService();
+                EntPayRequest request=new EntPayRequest();
+                request.setAppid(wxPayProperties.getAppId());
+                request.setMchId(wxPayProperties.getMchId());
+                request.setOpenid(user.getMaOpenId());
+                request.setCheckName("NO_CHECK");
+                request.setSpbillCreateIp(IPUtils.getIpAddr(servletRequest));
+                request.setReUserName(user.getRealName());
+                request.setPartnerTradeNo(extract.getExtractId().toString());
+                request.setDescription("会员提现");
+                request.setAmount(WxPayUnifiedOrderRequest.yuanToFen(extract.getExtractPrice().toString()));
+                try {
+                    EntPayResult result=entPayService.entPay(request);
+                    if(result.getResultCode().equals(0)){
+                        extract.setStatus(1L);
+                        fsUserExtractService.updateFsUserExtract(extract);
+                    }
+                    return R.ok();
+                } catch (WxPayException e) {
+                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                    e.printStackTrace();
+                    return R.error(e.getMessage());
+                }
+
+            }
+            else if(fsUserExtract.getStatus()==-1){
+                extract.setStatus(-1L);
+                extract.setFailMsg(fsUserExtract.getFailMsg());
+                fsUserExtractService.updateFsUserExtract(extract);
+                user.setNowMoney(user.getNowMoney().add(extract.getExtractPrice()));
+                fsUserService.updateFsUser(user);
+                //插入流水
+                billService.addBill(user.getUserId(), BillDetailEnum.CATEGORY_1.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),extract.getExtractPrice(),user.getNowMoney(),"提现申请驳回",extract.getExtractId().toString(),0l);
+                return R.ok();
+            }
+            else{
+                return R.error("非法操作");
+            }
+        }
+        else{
+            return R.error("非法操作");
+        }
+
+    }
 }

+ 1 - 1
fs-admin/src/main/resources/application.yml

@@ -4,7 +4,7 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: dev
+    active: druid-bjzm-test
 #    active: druid-hdt
 #    active: druid-yzt
 #    active: druid-sxjz-test

+ 3 - 0
fs-live-app/src/main/java/com/fs/live/websocket/auth/WebSocketConfigurator.java

@@ -52,6 +52,9 @@ public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {
         if (parameterMap.containsKey(AttrConstant.COMPANY_USER_ID)) {
             userProperties.put(AttrConstant.COMPANY_USER_ID, Long.valueOf(parameterMap.get(AttrConstant.COMPANY_USER_ID).get(0)));
         }
+        if (parameterMap.containsKey(AttrConstant.LOCATION)) {
+            userProperties.put(AttrConstant.LOCATION, parameterMap.get(AttrConstant.LOCATION).get(0));
+        }
 
         // 验证token
         if (parameterMap.containsKey(tokenKey)) {

+ 2 - 0
fs-live-app/src/main/java/com/fs/live/websocket/constant/AttrConstant.java

@@ -12,9 +12,11 @@ public class AttrConstant {
     public static final String SIGNATURE = "signature";
     public static final String COMPANY_ID = "companyId";
     public static final String COMPANY_USER_ID = "companyUserId";
+    public static final String LOCATION = "location";
 
     // 定义 AttributeKey 保存必要参数
     public static final AttributeKey<Long> ATTR_LIVE_ID = AttributeKey.valueOf(LIVE_ID);
     public static final AttributeKey<Long> ATTR_USER_ID = AttributeKey.valueOf(USER_ID);
     public static final AttributeKey<Long> ATTR_USER_TYPE = AttributeKey.valueOf(USER_TYPE);
+    public static final AttributeKey<String> ATTR_LOCATION = AttributeKey.valueOf(USER_TYPE);
 }

+ 2 - 1
fs-live-app/src/main/java/com/fs/live/websocket/handle/LiveChatHandler.java

@@ -58,6 +58,7 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
             Long liveId = ctx.channel().attr(AttrConstant.ATTR_LIVE_ID).get();
             Long userType = ctx.channel().attr(AttrConstant.ATTR_USER_TYPE).get();
 
+
             if (Objects.isNull(liveService.selectLiveByLiveId(liveId))) {
                 ctx.channel().writeAndFlush(new TextWebSocketFrame("Error: 未找到直播间")).addListener(ChannelFutureListener.CLOSE);
                 return;
@@ -70,7 +71,7 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
 
             if (userType == 0) {
                 // 加入房间
-                liveWatchUserService.join(liveId, userId);
+                liveWatchUserService.joinWithoutLocation(liveId, userId);
                 room.put(userId, ctx.channel());
 
                 FsUser fsUser = fsUserService.selectFsUserByUserId(userId);

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

@@ -72,6 +72,8 @@ public class WebSocketServer {
         long liveId = (long) userProperties.get("liveId");
         long userId = (long) userProperties.get("userId");
         long userType = (long) userProperties.get("userType");
+        String location = (String) userProperties.get("location");  // 获取location参数
+
         Live live = liveService.selectLiveByLiveId(liveId);
         if (live == null) {
             throw new BaseException("未找到直播间");
@@ -96,7 +98,7 @@ public class WebSocketServer {
                 throw new BaseException("用户信息错误");
             }
 
-            LiveWatchUser liveWatchUserVO = liveWatchUserService.join(liveId, userId);
+            LiveWatchUser liveWatchUserVO = liveWatchUserService.join(liveId, userId, location);
             room.put(userId, session);
             // 直播间浏览量 +1
             redisCache.incr(PAGE_VIEWS_KEY + liveId, 1);
@@ -262,6 +264,22 @@ public class WebSocketServer {
                             return;
                         }
 
+                        // 根据直播状态设置live_flag或replay_flag
+                        Live msgLive = liveService.selectLiveByLiveId(msg.getLiveId());
+                        if (msgLive != null && msgLive.getFinishTime() != null) {
+                            Date finishTime = java.sql.Timestamp.valueOf(msgLive.getFinishTime());
+                            if (new Date().after(finishTime)) {
+                                liveMsg.setReplayFlag(1);
+                                liveMsg.setLiveFlag(0);
+                            } else {
+                                liveMsg.setLiveFlag(1);
+                                liveMsg.setReplayFlag(0);
+                            }
+                        } else {
+                            liveMsg.setLiveFlag(1);
+                            liveMsg.setReplayFlag(0);
+                        }
+
                         liveMsgService.insertLiveMsg(liveMsg);
                     }
 
@@ -281,6 +299,23 @@ public class WebSocketServer {
                     liveMsg.setAvatar(msg.getAvatar());
                     liveMsg.setMsg(msg.getMsg());
                     liveMsg.setCreateTime(new Date());
+
+                    // 根据直播状态设置live_flag或replay_flag
+                    Live normalMsgLive = liveService.selectLiveByLiveId(msg.getLiveId());
+                    if (normalMsgLive != null && normalMsgLive.getFinishTime() != null) {
+                        Date finishTime = java.sql.Timestamp.valueOf(normalMsgLive.getFinishTime());
+                        if (new Date().after(finishTime)) {
+                            liveMsg.setReplayFlag(1);
+                            liveMsg.setLiveFlag(0);
+                        } else {
+                            liveMsg.setLiveFlag(1);
+                            liveMsg.setReplayFlag(0);
+                        }
+                    } else {
+                        liveMsg.setLiveFlag(1);
+                        liveMsg.setReplayFlag(0);
+                    }
+
                     liveMsgService.insertLiveMsg(liveMsg);
                     msg.setOn(true);
                     msg.setData(JSONObject.toJSONString(liveMsg));
@@ -302,6 +337,20 @@ public class WebSocketServer {
                     // 广播消息
                     broadcastMessage(liveId, JSONObject.toJSONString(R.ok().put("data", msg)));
                     break;
+                case "sendTopMsg":
+                    msg.setMsg(productionWordFilter.filter(msg.getMsg()).getFilteredText());
+                    if(StringUtils.isEmpty(msg.getMsg())) return;
+                    liveMsg = new LiveMsg();
+                    liveMsg.setLiveId(msg.getLiveId());
+                    liveMsg.setUserId(msg.getUserId());
+                    liveMsg.setNickName(msg.getNickName());
+                    liveMsg.setAvatar(msg.getAvatar());
+                    liveMsg.setMsg(msg.getMsg());
+                    msg.setOn(true);
+                    msg.setData(JSONObject.toJSONString(liveMsg));
+                    // 广播消息
+                    broadcastMessage(liveId, JSONObject.toJSONString(R.ok().put("data", msg)));
+                    break;
                 case "globalVisible":
                     msg.setOn(true);
                     liveWatchUserService.updateGlobalVisible(liveId, msg.getStatus());
@@ -629,6 +678,27 @@ public class WebSocketServer {
                 data.put("couponTime", liveCoupon.getCouponTime());
                 msg.setData(JSON.toJSONString(data));
                 liveCouponMapper.updateChangeShow(task.getLiveId(), liveCouponIssue.getId());
+            } else if (task.getTaskType() == 6L) {
+                // 上架/下架商品
+                msg.setCmd("goods");
+                JSONObject jsonObject = JSON.parseObject(task.getContent());
+                Long goodsId = jsonObject.getLong("goodsId");
+                Integer status = jsonObject.getInteger("status");
+                if (goodsId == null || status == null) {
+                    log.error("商品ID或状态为空");
+                    return;
+                }
+                // 更新商品上下架状态
+                liveGoodsService.updateLiveGoodsStatus(goodsId, status);
+                return ;
+                // 更新直播间配置缓存
+//                liveService.asyncToCacheLiveConfig(task.getLiveId());
+                // 查询商品信息并广播
+//                LiveGoodsVo liveGoodsVo = liveGoodsService.selectLiveGoodsVoByGoodsId(goodsId);
+//                if (liveGoodsVo != null) {
+//                    msg.setData(JSON.toJSONString(liveGoodsVo));
+//                    msg.setStatus(status);
+//                }
             }
             msg.setStatus(1);
             broadcastMessage(task.getLiveId(), JSONObject.toJSONString(R.ok().put("data", msg)));

+ 1 - 1
fs-live-app/src/main/resources/application.yml

@@ -6,4 +6,4 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: dev
+    active: druid-bjzm-test

+ 9 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserCompanyUserMapper.java

@@ -95,4 +95,13 @@ public interface FsUserCompanyUserMapper extends BaseMapper<FsUserCompanyUser>{
     List<Long> selectFsUserCompanyUserListByMap(@Param("param") Map<String, Object> param);
 
     List<FsUserCompanyUser> selectFsUserCompanyUserByIds(@Param("param") Map<String, Object> param);
+
+    /**
+     * 批量删除微信用户和销售关系
+     *
+     * @param userIds 需要删除的userId集合
+     * @return 删除的记录数
+     */
+    int batchDeleteByIds(@Param("userIds") List<Long> userIds);
+
 }

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

@@ -128,4 +128,12 @@ public interface IFsUserCompanyUserService extends IService<FsUserCompanyUser>{
      * @return Boolean
      */
     Boolean batchUpdateStatus(List<Long> ids, int status);
+
+    /**
+     * 解绑会员
+     * @auth caoliqin
+     * @param userIds 会员用户id
+     * @return
+     */
+    Integer batchUnbind(List<Long> userIds);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyUserServiceImpl.java

@@ -223,4 +223,9 @@ public class FsUserCompanyUserServiceImpl extends ServiceImpl<FsUserCompanyUserM
         }
         return baseMapper.batchUpdateStatus(ids, status) > 0;
     }
+
+    @Override
+    public Integer batchUnbind(List<Long> userIds) {
+        return baseMapper.batchDeleteByIds(userIds);
+    }
 }

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

@@ -159,6 +159,11 @@ public class FsUser extends BaseEntity
      * 企微销售ID
      * **/
     private Long qwUserId;
+
+
+    /** 推广上级用户ID */
+    private Long spreadUserId;
+
     public void setNickName(String nickname)
     {
         if(StringUtils.isNotEmpty(nickname)){

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

@@ -1235,11 +1235,11 @@ public class FsUserServiceImpl implements IFsUserService {
                 if (tuiUser != null) {
                     FsUser tuiUserMap = new FsUser();
                     tuiUserMap.setUserId(tuiUser.getUserId());
-                    tuiUserMap.setNowMoney(tuiUser.getNowMoney().add(new BigDecimal(bill.getNumber())));
-                    tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(new BigDecimal(bill.getNumber())));
+                    tuiUserMap.setNowMoney(tuiUser.getNowMoney().add(bill.getMoney()));
+                    tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(bill.getMoney()));
                     fsUserMapper.updateFsUser(tuiUserMap);
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(), 0, BillDetailEnum.TYPE_6.getDesc(), bill.getNumber().doubleValue(), tuiUserMap.getBrokeragePrice().doubleValue(), "订单分佣金", order.getId().toString(), bill.getTuiUserId());
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_1.getValue(), 1, BillDetailEnum.TYPE_5.getDesc(), bill.getNumber().doubleValue(), tuiUserMap.getNowMoney().doubleValue(), "订单分佣金", order.getId().toString(), bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(), 0, BillDetailEnum.TYPE_6.getDesc(), bill.getMoney(), tuiUserMap.getBrokeragePrice(), "订单分佣金", order.getId().toString(), bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_1.getValue(), 1, BillDetailEnum.TYPE_5.getDesc(), bill.getMoney(), tuiUserMap.getNowMoney(), "订单分佣金", order.getId().toString(), bill.getTuiUserId());
                 }
             }
         }

+ 27 - 12
fs-service/src/main/java/com/fs/hisStore/domain/FsUserBillScrm.java

@@ -4,9 +4,11 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
 
+import java.math.BigDecimal;
+
 /**
  * 用户账单对象 fs_user_bill
- * 
+ *
  * @author fs
  * @date 2022-04-30
  */
@@ -16,7 +18,7 @@ public class FsUserBillScrm extends BaseEntity
     private static final long serialVersionUID = 1L;
 
     /** 用户账单id */
-    private Long id;
+    private Long billId;
 
     /** 用户uid */
     @Excel(name = "用户uid")
@@ -44,11 +46,14 @@ public class FsUserBillScrm extends BaseEntity
 
     /** 明细数字 */
     @Excel(name = "明细数字")
-    private Double number;
+    private BigDecimal number;
+
+    @Excel(name = "金额")
+    private BigDecimal money;
 
     /** 剩余 */
     @Excel(name = "剩余")
-    private Double balance;
+    private BigDecimal balance;
 
     /** 0 = 带确定 1 = 有效 -1 = 无效 */
     @Excel(name = "0 = 带确定 1 = 有效 -1 = 无效")
@@ -56,6 +61,15 @@ public class FsUserBillScrm extends BaseEntity
 
     private Long tuiUserId;
 
+
+    public BigDecimal getMoney() {
+        return money;
+    }
+
+    public void setMoney(BigDecimal money) {
+        this.money = money;
+    }
+
     public Long getTuiUserId() {
         return tuiUserId;
     }
@@ -68,12 +82,13 @@ public class FsUserBillScrm extends BaseEntity
         return serialVersionUID;
     }
 
-    public Long getId() {
-        return id;
+    public Long getBillId() {
+        return billId;
     }
 
-    public void setId(Long id) {
-        this.id = id;
+    public FsUserBillScrm setBillId(Long billId) {
+        this.billId = billId;
+        return this;
     }
 
     public Long getUserId() {
@@ -124,19 +139,19 @@ public class FsUserBillScrm extends BaseEntity
         this.title = title;
     }
 
-    public Double getNumber() {
+    public BigDecimal getNumber() {
         return number;
     }
 
-    public void setNumber(Double number) {
+    public void setNumber(BigDecimal number) {
         this.number = number;
     }
 
-    public Double getBalance() {
+    public BigDecimal getBalance() {
         return balance;
     }
 
-    public void setBalance(Double balance) {
+    public void setBalance(BigDecimal balance) {
         this.balance = balance;
     }
 

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

@@ -509,9 +509,9 @@ public interface FsStoreOrderScrmMapper
     @Select("select * from fs_store_order_scrm where extend_order_id=#{extendOrderId}")
     FsStoreOrderScrm selectFsStoreOrderByExtendOrderId(String extendOrderId);
     @Select({"<script> " +
-            "select b.number as tui_price,b.bill_type,b.create_time,o.id as order_id,o.order_code,o.pay_price,u.nickname,u.avatar from fs_user_bill b inner join  fs_store_order_scrm o on b.business_id=o.id left join fs_user u on u.user_id=o.user_id  " +
+            "select b.money as tui_price,b.bill_type,b.create_time,o.id as order_id,o.order_code,o.pay_price,u.nickname,u.avatar from fs_user_bill b inner join  fs_store_order_scrm o on b.business_id=o.id left join fs_user u on u.user_id=o.user_id  " +
             "where b.user_id=#{userId} and b.category='brokerage_price'   " +
-            " order by b.id desc"+
+            " order by b.bill_id desc"+
             "</script>"})
     List<FsStoreOrderTuiVO> selectFsStoreOrderTuiListVO(String userId);
     @Select({"<script> " +

+ 8 - 8
fs-service/src/main/java/com/fs/hisStore/service/IFsUserBillScrmService.java

@@ -9,7 +9,7 @@ import com.fs.hisStore.vo.FsUserBillVO;
 
 /**
  * 用户账单Service接口
- * 
+ *
  * @author fs
  * @date 2022-04-03
  */
@@ -17,7 +17,7 @@ public interface IFsUserBillScrmService
 {
     /**
      * 查询用户账单
-     * 
+     *
      * @param id 用户账单ID
      * @return 用户账单
      */
@@ -25,7 +25,7 @@ public interface IFsUserBillScrmService
 
     /**
      * 查询用户账单列表
-     * 
+     *
      * @param fsUserBill 用户账单
      * @return 用户账单集合
      */
@@ -33,7 +33,7 @@ public interface IFsUserBillScrmService
 
     /**
      * 新增用户账单
-     * 
+     *
      * @param fsUserBill 用户账单
      * @return 结果
      */
@@ -41,7 +41,7 @@ public interface IFsUserBillScrmService
 
     /**
      * 修改用户账单
-     * 
+     *
      * @param fsUserBill 用户账单
      * @return 结果
      */
@@ -49,7 +49,7 @@ public interface IFsUserBillScrmService
 
     /**
      * 批量删除用户账单
-     * 
+     *
      * @param ids 需要删除的用户账单ID
      * @return 结果
      */
@@ -57,13 +57,13 @@ public interface IFsUserBillScrmService
 
     /**
      * 删除用户账单信息
-     * 
+     *
      * @param id 用户账单ID
      * @return 结果
      */
     public int deleteFsUserBillById(Long id);
 
-    void addBill(Long uid,String cate,Integer billType, String title, double number, double balance, String remark,String busId,Long tuiUserId);
+    void addBill(Long uid,String cate,Integer billType, String title, BigDecimal number, BigDecimal balance, String remark,String busId,Long tuiUserId);
 
 
     List<FsUserBillScrm> selectFsUserBillListQuery(FsUserBillQueryParam param);

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

@@ -905,7 +905,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             }
             //使用了积分扣积分
             if (dto.getUsedIntegral() > 0) {
-                this.decIntegral(userId, dto.getUsedIntegral(), dto.getDeductionPrice().doubleValue(), storeOrder.getId().toString());
+                this.decIntegral(userId, dto.getUsedIntegral(), dto.getDeductionPrice(), storeOrder.getId().toString());
             }
             //减库存加销量
             this.deStockIncSale(carts);
@@ -1109,11 +1109,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     /**
      * 积分抵扣
      */
-    private void decIntegral(Long uid, double usedIntegral, double deductionPrice, String busId) {
+    private void decIntegral(Long uid, double usedIntegral, BigDecimal deductionPrice, String busId) {
         userService.decIntegral(uid, usedIntegral);
         FsUserScrm user = userService.selectFsUserById(uid);
         //积分记录
-        billService.addBill(uid, BillDetailEnum.CATEGORY_2.getValue(), 0, BillDetailEnum.TYPE_1.getDesc(), usedIntegral, user.getIntegral().doubleValue(),
+        billService.addBill(uid, BillDetailEnum.CATEGORY_2.getValue(), 0, BillDetailEnum.TYPE_1.getDesc(), new BigDecimal(usedIntegral) ,new BigDecimal(user.getIntegral()),
                 "购买商品使用" + usedIntegral + "积分抵扣" + deductionPrice + "元", busId, 0l);
 
     }
@@ -2782,8 +2782,8 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         userService.updateFsUser(user);
         //增加流水
         billService.addBill(user.getUserId(), BillDetailEnum.CATEGORY_2.getValue(), 1, BillDetailEnum.TYPE_5.getDesc(),
-                order.getUseIntegral().doubleValue(),
-                newIntegral.doubleValue(),
+                order.getUseIntegral(),
+                newIntegral,
                 "购买商品失败,回退积分" + order.getUseIntegral(), order.getId().toString(), 0l);
         //更新订单回退积分
         FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();

+ 9 - 3
fs-service/src/main/java/com/fs/hisStore/service/impl/FsUserBillScrmServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.hisStore.service.impl;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 
 import cn.hutool.json.JSONUtil;
 import com.fs.common.utils.DateUtils;
@@ -55,7 +56,11 @@ public class FsUserBillScrmServiceImpl implements IFsUserBillScrmService
     @Override
     public List<FsUserBillScrm> selectFsUserBillList(FsUserBillScrm fsUserBill)
     {
-        return fsUserBillMapper.selectFsUserBillList(fsUserBill);
+        List<FsUserBillScrm> bills=fsUserBillMapper.selectFsUserBillList(fsUserBill);
+        Optional.ofNullable( bills).ifPresent(list -> list.forEach(bill -> {
+            bill.setNumber(bill.getMoney());
+        }));
+        return bills;
     }
 
     /**
@@ -109,13 +114,14 @@ public class FsUserBillScrmServiceImpl implements IFsUserBillScrmService
     }
 
     @Override
-    public void addBill(Long uid, String cate,Integer billType,String title, double number, double balance, String renark,String busId,Long tuiUserId) {
+    public void addBill(Long uid, String cate,Integer billType,String title, BigDecimal money, BigDecimal balance, String renark,String busId,Long tuiUserId) {
         FsUserBillScrm bill=new FsUserBillScrm();
         bill.setCategory(cate);
         bill.setBillType(billType);
         bill.setUserId(uid);
         bill.setTitle(title);
-        bill.setNumber(number);
+//        bill.setNumber(number);
+        bill.setMoney(money);
         bill.setBalance(balance);
         bill.setRemark(renark);
         bill.setBusinessId(busId);

+ 8 - 8
fs-service/src/main/java/com/fs/hisStore/service/impl/FsUserExtractScrmServiceImpl.java

@@ -22,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 用户提现Service业务层处理
- * 
+ *
  * @author fs
  * @date 2022-03-15
  */
@@ -37,7 +37,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
     private IFsUserBillScrmService billService;
     /**
      * 查询用户提现
-     * 
+     *
      * @param id 用户提现ID
      * @return 用户提现
      */
@@ -49,7 +49,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
 
     /**
      * 查询用户提现列表
-     * 
+     *
      * @param fsUserExtract 用户提现
      * @return 用户提现
      */
@@ -61,7 +61,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
 
     /**
      * 新增用户提现
-     * 
+     *
      * @param fsUserExtract 用户提现
      * @return 结果
      */
@@ -74,7 +74,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
 
     /**
      * 修改用户提现
-     * 
+     *
      * @param fsUserExtract 用户提现
      * @return 结果
      */
@@ -87,7 +87,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
 
     /**
      * 批量删除用户提现
-     * 
+     *
      * @param ids 需要删除的用户提现ID
      * @return 结果
      */
@@ -99,7 +99,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
 
     /**
      * 删除用户提现信息
-     * 
+     *
      * @param id 用户提现ID
      * @return 结果
      */
@@ -139,7 +139,7 @@ public class FsUserExtractScrmServiceImpl implements IFsUserExtractScrmService
         fsUserExtractMapper.insertFsUserExtract(extract);
         userMapper.updateFsUser(user);
         //插入流水
-        billService.addBill(user.getUserId(), BillDetailEnum.CATEGORY_1.getValue(),0,BillDetailEnum.TYPE_6.getDesc(),param.getExtractPrice().doubleValue(),user.getNowMoney().doubleValue(),"提现申请",extract.getId().toString(),0l);
+        billService.addBill(user.getUserId(), BillDetailEnum.CATEGORY_1.getValue(),0,BillDetailEnum.TYPE_6.getDesc(),param.getExtractPrice(),user.getNowMoney(),"提现申请",extract.getId().toString(),0l);
 
         return R.ok("提交成功,等待后台审核");
     }

+ 10 - 10
fs-service/src/main/java/com/fs/hisStore/service/impl/FsUserScrmServiceImpl.java

@@ -328,7 +328,7 @@ public class FsUserScrmServiceImpl implements IFsUserScrmService
                     tuiUserMap.setUserId(tuiUser.getUserId());
                     tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().add(brokerage));
                     fsUserMapper.updateFsUser(tuiUserMap);
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),brokerage.doubleValue(),tuiUserMap.getBrokeragePrice().doubleValue(),"订单返佣金",order.getId().toString(),order.getUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),brokerage,tuiUserMap.getBrokeragePrice(),"订单返佣金",order.getId().toString(),order.getUserId());
                 }
             }
             //二级返
@@ -340,7 +340,7 @@ public class FsUserScrmServiceImpl implements IFsUserScrmService
                         tuiUserTwoMap.setUserId(tuiUserTwo.getUserId());
                         tuiUserTwoMap.setBrokeragePrice(tuiUserTwo.getBrokeragePrice().add(brokerageTwo));
                         fsUserMapper.updateFsUser(tuiUserTwoMap);
-                        billService.addBill(tuiUserTwoMap.getUserId(), CATEGORY_3.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),brokerageTwo.doubleValue(),tuiUserTwoMap.getBrokeragePrice().doubleValue(),"订单返佣金",order.getId().toString(),tuiUser.getUserId());
+                        billService.addBill(tuiUserTwoMap.getUserId(), CATEGORY_3.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),brokerageTwo,tuiUserTwoMap.getBrokeragePrice(),"订单返佣金",order.getId().toString(),tuiUser.getUserId());
                     }
                     //三级
                     FsUserScrm tuiUserThree= fsUserMapper.selectFsUserById(tuiUserTwo.getSpreadUserId());
@@ -350,7 +350,7 @@ public class FsUserScrmServiceImpl implements IFsUserScrmService
                             tuiUserThreeMap.setUserId(tuiUserThree.getUserId());
                             tuiUserThreeMap.setBrokeragePrice(tuiUserThree.getBrokeragePrice().add(brokerageThree));
                             fsUserMapper.updateFsUser(tuiUserThreeMap);
-                            billService.addBill(tuiUserThreeMap.getUserId(), CATEGORY_3.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),brokerageThree.doubleValue(),tuiUserThreeMap.getBrokeragePrice().doubleValue(),"订单返佣金",order.getId().toString(),tuiUser.getUserId());
+                            billService.addBill(tuiUserThreeMap.getUserId(), CATEGORY_3.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),brokerageThree,tuiUserThreeMap.getBrokeragePrice(),"订单返佣金",order.getId().toString(),tuiUser.getUserId());
                         }
 
                     }
@@ -359,7 +359,7 @@ public class FsUserScrmServiceImpl implements IFsUserScrmService
             }
         }
         catch (Exception e){
-
+            log.error("分佣异常",e);
         }
     }
 
@@ -377,9 +377,9 @@ public class FsUserScrmServiceImpl implements IFsUserScrmService
                 if(tuiUser!=null){
                     FsUserScrm tuiUserMap=new FsUserScrm();
                     tuiUserMap.setUserId(tuiUser.getUserId());
-                    tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(new BigDecimal(bill.getNumber())));
+                    tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(bill.getMoney()));
                     fsUserMapper.updateFsUser(tuiUserMap);
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),0,BillDetailEnum.TYPE_6.getDesc(),bill.getNumber().doubleValue(),tuiUserMap.getBrokeragePrice().doubleValue(),"订单退佣金",order.getId().toString(),bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),0,BillDetailEnum.TYPE_6.getDesc(),bill.getMoney(),tuiUserMap.getBrokeragePrice(),"订单退佣金",order.getId().toString(),bill.getTuiUserId());
                 }
             }
         }
@@ -400,11 +400,11 @@ public class FsUserScrmServiceImpl implements IFsUserScrmService
                 if(tuiUser!=null){
                     FsUserScrm tuiUserMap=new FsUserScrm();
                     tuiUserMap.setUserId(tuiUser.getUserId());
-                    tuiUserMap.setNowMoney(tuiUser.getNowMoney().add(new BigDecimal(bill.getNumber())));
-                    tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(new BigDecimal(bill.getNumber())));
+                    tuiUserMap.setNowMoney(tuiUser.getNowMoney().add(bill.getMoney()));
+                    tuiUserMap.setBrokeragePrice(tuiUser.getBrokeragePrice().subtract(bill.getMoney()));
                     fsUserMapper.updateFsUser(tuiUserMap);
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),0,BillDetailEnum.TYPE_6.getDesc(),bill.getNumber().doubleValue(),tuiUserMap.getBrokeragePrice().doubleValue(),"订单分佣金",order.getId().toString(),bill.getTuiUserId());
-                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_1.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),bill.getNumber().doubleValue(),tuiUserMap.getNowMoney().doubleValue(),"订单分佣金",order.getId().toString(),bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_3.getValue(),0,BillDetailEnum.TYPE_6.getDesc(),bill.getMoney(),tuiUserMap.getBrokeragePrice(),"订单分佣金",order.getId().toString(),bill.getTuiUserId());
+                    billService.addBill(tuiUserMap.getUserId(), CATEGORY_1.getValue(),1,BillDetailEnum.TYPE_5.getDesc(),bill.getMoney(),tuiUserMap.getNowMoney(),"订单分佣金",order.getId().toString(),bill.getTuiUserId());
                 }
             }
         }

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

@@ -59,14 +59,18 @@ public class LiveCoupon extends BaseEntity
     @Excel(name = "套餐分类ids")
     private String packageCateIds;
 
-    /** 优惠券类型 0-通用 1-商品券 */
-    @Excel(name = "优惠券类型 0-通用 1-商品券")
+    /** 优惠券类型 0-通用 1-商品券 2-无门槛券 */
+    @Excel(name = "优惠券类型 0-通用 1-商品券 2-无门槛券")
     private Long type;
 
     /** 是否删除 */
     @Excel(name = "是否删除")
     private Integer isDel;
 
+    /** 限制领取次数(针对无门槛优惠券,每个用户可以领取的最大张数) */
+    @Excel(name = "限制领取次数")
+    private Integer limitReceiveCount;
+
     private Long id;
     private Integer isShow;
     private Long goodsId;

+ 7 - 0
fs-service/src/main/java/com/fs/live/domain/LiveData.java

@@ -76,5 +76,12 @@ public class LiveData{
     @Excel(name = "关注数")
     private Long followNum;
 
+    /** 回放观看人次 */
+    @Excel(name = "回放观看人次")
+    private Long replayViewNum;
+
+    /** 回放点赞数 */
+    @Excel(name = "回放点赞数")
+    private Long replayLikeNum;
 
 }

+ 8 - 0
fs-service/src/main/java/com/fs/live/domain/LiveMsg.java

@@ -44,4 +44,12 @@ public class LiveMsg extends BaseEntity {
 
     @TableField(exist = false)
     private Integer singleVisible;
+
+    /** 直播消息标记:0-否 1-是 */
+    @Excel(name = "直播消息标记")
+    private Integer liveFlag = 0;
+
+    /** 回放消息标记:0-否 1-是 */
+    @Excel(name = "回放消息标记")
+    private Integer replayFlag = 0;
 }

+ 12 - 0
fs-service/src/main/java/com/fs/live/domain/LiveWatchUser.java

@@ -50,4 +50,16 @@ public class LiveWatchUser extends BaseEntity {
     private String nickName;
     private String tabName;
 
+    /** 直播进入标记:0-否 1-是 */
+    @Excel(name = "直播进入标记")
+    private Integer liveFlag = 0;
+
+    /** 回放进入标记:0-否 1-是 */
+    @Excel(name = "回放进入标记")
+    private Integer replayFlag = 0;
+
+    /** 用户所在位置 */
+    @Excel(name = "用户所在位置")
+    private String location;
+
 }

+ 11 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveCouponIssueUserMapper.java

@@ -4,6 +4,8 @@ import java.util.List;
 import com.fs.live.domain.LiveCouponIssueUser;
 import com.fs.live.domain.LiveCouponUser;
 import com.fs.live.param.CouponPO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 /**
  * 优惠券用户领取记录Mapper接口
@@ -63,4 +65,13 @@ public interface LiveCouponIssueUserMapper
 
 
     List<LiveCouponUser> selectLiveCouponUserByCouponPO(CouponPO coupon);
+
+    /**
+     * 查询用户领取某个优惠券的次数
+     * @param userId 用户ID
+     * @param issueId 优惠券发放ID
+     * @return 领取次数
+     */
+    @Select("SELECT COUNT(1) FROM live_coupon_issue_user WHERE user_id = #{userId} AND issue_id = #{issueId} AND is_del = 0")
+    int countUserReceivedCoupon(@Param("userId") Long userId, @Param("issueId") Long issueId);
 }

+ 4 - 2
fs-service/src/main/java/com/fs/live/mapper/LiveDataMapper.java

@@ -131,8 +131,10 @@ public interface LiveDataMapper {
     List<Map<String, Object>> getCompanyChartData(@Param("chartStartDate") String chartStartDate,@Param("chartEndDate") String chartEndDate, @Param("format") String format,@Param("category") String category,@Param("companyId") Long companyId);
 
     @Select("SELECT " +
-            "    ld.total_views AS viewNum,                        " +
-            "    ld.likes AS likeNum                        " +
+            "    ld.total_views AS liveViewNum, " +
+            "    ld.replay_view_num AS replayViewNum, " +
+            "    ld.likes AS liveLikeNum, " +
+            "    ld.replay_like_num AS replayLikeNum " +
             "FROM " +
             "    live_data ld " +
             "where ld.live_id=#{liveId}")

+ 8 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java

@@ -149,4 +149,12 @@ public interface LiveGoodsMapper {
             "ELSE 0 END where live_id = #{liveId}" +
             "</script>"})
     void updateLiveIsShow(@Param("goodsId")Long goodsId,@Param("liveId") Long liveId);
+
+    /**
+     * 根据goodsId更新商品上下架状态
+     * @param goodsId 商品ID
+     * @param status 状态:1-上架 0-下架
+     */
+    @Update("update live_goods set is_show = #{status} where goods_id = #{goodsId}")
+    void updateLiveGoodsStatus(@Param("goodsId") Long goodsId, @Param("status") Integer status);
 }

+ 4 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveMsgMapper.java

@@ -77,7 +77,10 @@ public interface LiveMsgMapper
     @Select("select * from live_msg where live_id = #{liveId} order by create_time desc limit 30")
     List<LiveMsg> listRecentMsg(@Param("liveId")Long liveId);
 
-    @Select("SELECT count(1) as commentNum from live_msg where live_id = #{liveId}")
+    @Select("SELECT " +
+            "    SUM(CASE WHEN live_flag = 1 THEN 1 ELSE 0 END) AS liveCommentNum, " +
+            "    SUM(CASE WHEN replay_flag = 1 THEN 1 ELSE 0 END) AS replayCommentNum " +
+            "FROM live_msg WHERE live_id = #{liveId}")
     Map<String, Long> selectDashboardCount(@Param("liveId") Long liveId);
 
     List<LiveMsg> selectLiveMsgSingleList(LiveMsg liveMsg);

+ 4 - 2
fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java

@@ -120,8 +120,10 @@ public interface LiveWatchUserMapper {
 
     @Select("SELECT " +
             "    SUM(CASE WHEN online = 0 and msg_status = 0 THEN 1 ELSE 0 END) AS onlineNum, " +
-            "    SUM(CASE WHEN user_id > 0 THEN 1 ELSE 0 END) AS newUserNum, " +
-            "    SUM(CASE WHEN user_id > 0 THEN 1 ELSE 0 END) AS oldUserNum " +
+            "    SUM(CASE WHEN user_id > 0 AND live_flag = 1 THEN 1 ELSE 0 END) AS liveNewUserNum, " +
+            "    SUM(CASE WHEN user_id > 0 AND live_flag = 1 THEN 1 ELSE 0 END) AS liveOldUserNum, " +
+            "    SUM(CASE WHEN user_id > 0 AND replay_flag = 1 THEN 1 ELSE 0 END) AS replayNewUserNum, " +
+            "    SUM(CASE WHEN user_id > 0 AND replay_flag = 1 THEN 1 ELSE 0 END) AS replayOldUserNum " +
             "FROM " +
             "    live_watch_user where live_id=#{liveId}"
     )

+ 7 - 0
fs-service/src/main/java/com/fs/live/service/ILiveCouponService.java

@@ -88,4 +88,11 @@ public interface ILiveCouponService
     R curCoupon(CouponPO coupon);
 
     List<LiveCoupon> listOn(Long liveId);
+
+    /**
+     * 使用无门槛优惠券(新方法,跳过普通优惠券的校验逻辑)
+     * @param coupon 优惠券参数
+     * @return 结果
+     */
+    R useNoThresholdCoupon(CouponPO coupon);
 }

+ 7 - 0
fs-service/src/main/java/com/fs/live/service/ILiveGoodsService.java

@@ -124,4 +124,11 @@ public interface ILiveGoodsService {
     void updateLiveIsShow(Long goodsId, Long liveId);
 
     R getStoreByLiveId(Long liveId, String key, String userId);
+
+    /**
+     * 根据商品ID更新商品上下架状态
+     * @param goodsId 商品ID
+     * @param status 状态:1-上架 0-下架
+     */
+    void updateLiveGoodsStatus(Long goodsId, Integer status);
 }

+ 2 - 1
fs-service/src/main/java/com/fs/live/service/ILiveWatchUserService.java

@@ -75,7 +75,8 @@ public interface ILiveWatchUserService {
 
     LiveWatchUser getByLiveIdAndUserId(long liveId, long userId);
 
-    LiveWatchUser join(long liveId, long userId);
+    LiveWatchUser join(long liveId, long userId, String location);
+    LiveWatchUser joinWithoutLocation(long liveId, long userId);
     LiveWatchUser close(long liveId, long userId);
 
     /**

+ 47 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveAutoTaskServiceImpl.java

@@ -151,6 +151,30 @@ public class LiveAutoTaskServiceImpl implements ILiveAutoTaskService {
             liveCoupon.setGoodsId(liveCouponIssueRelation.getGoodsId());
             liveAutoTask.setContent(JSON.toJSONString(liveCoupon));
             baseMapper.insertLiveAutoTask(liveAutoTask);
+        } else if (liveAutoTask.getTaskType() == 6L) {
+            // 上架/下架商品
+            try {
+                com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(liveAutoTask.getContent());
+                Long goodsId = jsonObject.getLong("goodsId");
+                Integer status = jsonObject.getInteger("status");
+                if (goodsId == null) return R.error("商品ID不能为空");
+                if (status == null) return R.error("状态不能为空");
+
+                // 查询商品信息
+                LiveGoodsVo liveGoodsVo = goodsService.selectLiveGoodsVoByGoodsId(goodsId);
+                if(liveGoodsVo == null) return R.error("商品不存在");
+
+                // 保存商品信息和上下架状态
+                com.alibaba.fastjson.JSONObject content = new com.alibaba.fastjson.JSONObject();
+                content.put("goodsId", liveGoodsVo.getGoodsId());
+                content.put("productId", liveGoodsVo.getProductId());
+                content.put("productName", liveGoodsVo.getProductName());
+                content.put("status", status);
+                liveAutoTask.setContent(content.toJSONString());
+                baseMapper.insertLiveAutoTask(liveAutoTask);
+            } catch (Exception e) {
+                return R.error("内容格式错误,应为{\"goodsId\":123,\"status\":1}");
+            }
         } else if(liveAutoTask.getTaskType() == 3L){
             baseMapper.insertLiveAutoTask(liveAutoTask);
 
@@ -267,6 +291,29 @@ public class LiveAutoTaskServiceImpl implements ILiveAutoTaskService {
             liveCoupon.setGoodsId(liveCouponIssueRelation.getGoodsId());
             liveAutoTask.setContent(JSON.toJSONString(liveCoupon));
             return baseMapper.updateLiveAutoTask(liveAutoTask);
+        } else if (liveAutoTask.getTaskType() == 6L) {
+            // 上架/下架商品
+            try {
+                com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(liveAutoTask.getContent());
+                Long goodsId = jsonObject.getLong("goodsId");
+                Integer status = jsonObject.getInteger("status");
+                if (goodsId == null || status == null) return -1;
+
+                // 查询商品信息
+                LiveGoodsVo liveGoodsVo = goodsService.selectLiveGoodsVoByGoodsId(goodsId);
+                if(liveGoodsVo == null) return -1;
+
+                // 保存商品信息和上下架状态
+                com.alibaba.fastjson.JSONObject content = new com.alibaba.fastjson.JSONObject();
+                content.put("goodsId", liveGoodsVo.getGoodsId());
+                content.put("productId", liveGoodsVo.getProductId());
+                content.put("productName", liveGoodsVo.getProductName());
+                content.put("status", status);
+                liveAutoTask.setContent(content.toJSONString());
+                return baseMapper.updateLiveAutoTask(liveAutoTask);
+            } catch (Exception e) {
+                return -1;
+            }
         } else {
             return -1;
         }

+ 62 - 6
fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java

@@ -11,6 +11,7 @@ import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.live.domain.*;
+import com.fs.live.mapper.LiveCouponIssueUserMapper;
 import com.fs.live.mapper.LiveMapper;
 import com.fs.live.param.CouponPO;
 import com.fs.live.service.ILiveCouponIssueService;
@@ -48,6 +49,8 @@ public class LiveCouponServiceImpl implements ILiveCouponService
     private ILiveCouponUserService liveCouponUserService;
     @Autowired
     private ILiveCouponIssueService liveCouponIssueService;
+    @Autowired
+    private LiveCouponIssueUserMapper liveCouponIssueUserMapper;
 
     /**
      * 查询优惠券
@@ -196,18 +199,35 @@ public class LiveCouponServiceImpl implements ILiveCouponService
     @Override
     @Transactional
     public R claimCoupon(CouponPO coupon) {
-        Object o = redisCache.hashGet(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_COUPON, coupon.getLiveId(), coupon.getCouponIssueId()), String.valueOf(coupon.getUserId()));
-        if (ObjectUtil.isNotEmpty(o)) {
-            return R.error("您已经领取过优惠券了!");
-        }
         LiveCouponIssue issue = liveCouponMapper.selectLiveCouponIssueByLiveIdAndCouponId(coupon.getLiveId(), coupon.getCouponIssueId());
         if (coupon == null || issue.getStatus() != 1) {
             return R.error("优惠券不存在或者已下架!");
         }
-        Long decrement = redisCache.decrement(String.format(LiveKeysConstant.LIVE_COUPON_NUM , coupon.getCouponIssueId()));
 
         LiveCoupon liveCoupon = liveCouponMapper.selectLiveCouponById(issue.getCouponId());
+        if (liveCoupon == null) {
+            return R.error("优惠券配置不存在!");
+        }
 
+        // 判断是否为无门槛优惠券(type=2)
+        boolean isNoThresholdCoupon = liveCoupon.getType() != null && liveCoupon.getType() == 2L;
+
+        if (!isNoThresholdCoupon) {
+            // 普通优惠券:检查是否已领取
+            Object o = redisCache.hashGet(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_COUPON, coupon.getLiveId(), coupon.getCouponIssueId()), String.valueOf(coupon.getUserId()));
+            if (ObjectUtil.isNotEmpty(o)) {
+                return R.error("您已经领取过优惠券了!");
+            }
+        } else {
+            // 无门槛优惠券:检查领取次数是否超过限制
+            int receivedCount = liveCouponIssueUserMapper.countUserReceivedCoupon(coupon.getUserId(), issue.getId());
+            Integer limitCount = liveCoupon.getLimitReceiveCount() != null ? liveCoupon.getLimitReceiveCount() : 1;
+            if (receivedCount >= limitCount) {
+                return R.error("您已达到该优惠券的领取次数上限!");
+            }
+        }
+
+        Long decrement = redisCache.decrement(String.format(LiveKeysConstant.LIVE_COUPON_NUM , coupon.getCouponIssueId()));
 
         if (decrement < 0L) {
             issue.setStatus(-1);
@@ -243,7 +263,12 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         userRecord.setType("live-"+coupon.getLiveId());
         liveCouponUserService.insertLiveCouponUser(userRecord);
         liveCouponIssueUserService.insertLiveCouponIssueUser(record);
-        redisCache.hashPut(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_COUPON, coupon.getLiveId(), coupon.getCouponIssueId()), String.valueOf(coupon.getUserId()), JSONUtil.toJsonStr(record));
+
+        // 对于非无门槛优惠券,记录到Redis(防止重复领取)
+        if (!isNoThresholdCoupon) {
+            redisCache.hashPut(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_COUPON, coupon.getLiveId(), coupon.getCouponIssueId()), String.valueOf(coupon.getUserId()), JSONUtil.toJsonStr(record));
+        }
+
         return R.ok("恭喜您抢到优惠券");
     }
 
@@ -264,6 +289,37 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         return liveCouponMapper.listOn(liveId);
     }
 
+    /**
+     * 使用无门槛优惠券(新方法,跳过普通优惠券的校验逻辑)
+     */
+    @Override
+    @Transactional
+    public R useNoThresholdCoupon(CouponPO coupon) {
+//        // 查询优惠券信息
+//        LiveCouponUser liveCouponUser = liveCouponUserService.selectLiveCouponUserById(coupon.getCouponUserId());
+//        if (liveCouponUser == null) {
+//            return R.error("优惠券不存在!");
+//        }
+//
+//        // 检查优惠券是否已使用
+//        if (liveCouponUser.getStatus() == 1) {
+//            return R.error("优惠券已使用!");
+//        }
+//
+//        // 检查优惠券是否已过期
+//        if (liveCouponUser.getIsFail() == 0) {
+//            return R.error("优惠券已过期!");
+//        }
+//
+//        // 标记优惠券为已使用
+//        liveCouponUser.setStatus(1);
+//        liveCouponUser.setUpdateTime(DateUtils.getNowDate());
+//        liveCouponUserService.updateLiveCouponUser(liveCouponUser);
+//
+//        return R.ok("优惠券使用成功").put("couponPrice", liveCouponUser.getCouponPrice());
+        return null;
+    }
+
 
 
 }

+ 52 - 12
fs-service/src/main/java/com/fs/live/service/impl/LiveDataServiceImpl.java

@@ -72,21 +72,61 @@ public class LiveDataServiceImpl implements ILiveDataService {
     /* 直播大屏展示 数据接口 */
     @Override
     public R dashboardData(Long liveId) {
-        Map<String,BigDecimal> map1 = liveWatchUserMapper.selectDashboardCount(liveId);
-        Map<String,Integer> map2 = baseMapper.selectDashboardCount(liveId);
-        Map<String, Long> map3 = liveMsgMapper.selectDashboardCount(liveId);
-        Map<String,BigDecimal> map4 = liveUserFirstEntryMapper.selectDashboardCount(liveId);
+        // 查询用户统计数据(直播和回放)
+        Map<String, BigDecimal> watchUserMap = liveWatchUserMapper.selectDashboardCount(liveId);
+        // 查询观看和点赞数据(直播和回放)
+        Map<String, Integer> liveDataMap = baseMapper.selectDashboardCount(liveId);
+        // 查询评论数据(直播和回放)
+        Map<String, Long> msgMap = liveMsgMapper.selectDashboardCount(liveId);
+        // 查询分享和直接访问数据
+        Map<String, BigDecimal> firstEntryMap = liveUserFirstEntryMapper.selectDashboardCount(liveId);
+        
         LiveDashBoardDataVo result = new LiveDashBoardDataVo();
-        result.setOnlineNum(map1 == null ? BigDecimal.valueOf(0) : map1.getOrDefault("onlineNum", BigDecimal.valueOf(0)));
-        result.setOldUserNum(map1 == null ? BigDecimal.valueOf(0) :map1.getOrDefault("oldUserNum", BigDecimal.valueOf(0)));
-        result.setNewUserNum(map1 == null ? BigDecimal.valueOf(0) :map1.getOrDefault("newUserNum", BigDecimal.valueOf(0)));
-        result.setViewNum(map2 == null ? 0 :map2.getOrDefault("viewNum", 0));
-        result.setLikeNum(map2 == null ? 0 :map2.getOrDefault("likeNum", 0));
-        result.setCommentNum(map3 == null ? 0L :map3.getOrDefault("commentNum", 0L));
-        result.setShareUrlNum(map4 == null ? BigDecimal.valueOf(0) :map4.getOrDefault("shareUrlNum", BigDecimal.valueOf(0)));
-        result.setDirectAccessNum(map4 == null ? BigDecimal.valueOf(0) :map4.getOrDefault("directAccessNum", BigDecimal.valueOf(0)));
+        
+        // 在线人数
+        result.setOnlineNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+            watchUserMap.getOrDefault("onlineNum", BigDecimal.valueOf(0)));
+        
+        // 直播用户数据
+        result.setLiveNewUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+            watchUserMap.getOrDefault("liveNewUserNum", BigDecimal.valueOf(0)));
+        result.setLiveOldUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+            watchUserMap.getOrDefault("liveOldUserNum", BigDecimal.valueOf(0)));
+        
+        // 回放用户数据
+        result.setReplayNewUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+            watchUserMap.getOrDefault("replayNewUserNum", BigDecimal.valueOf(0)));
+        result.setReplayOldUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+            watchUserMap.getOrDefault("replayOldUserNum", BigDecimal.valueOf(0)));
+        
+        // 直播观看和点赞数据
+        result.setLiveViewNum(liveDataMap == null ? 0 : 
+            liveDataMap.getOrDefault("liveViewNum", 0));
+        result.setLiveLikeNum(liveDataMap == null ? 0 : 
+            liveDataMap.getOrDefault("liveLikeNum", 0));
+        
+        // 回放观看和点赞数据
+        result.setReplayViewNum(liveDataMap == null ? 0 : 
+            liveDataMap.getOrDefault("replayViewNum", 0));
+        result.setReplayLikeNum(liveDataMap == null ? 0 : 
+            liveDataMap.getOrDefault("replayLikeNum", 0));
+        
+        // 直播和回放评论数据
+        result.setLiveCommentNum(msgMap == null ? 0L : 
+            msgMap.getOrDefault("liveCommentNum", 0L));
+        result.setReplayCommentNum(msgMap == null ? 0L : 
+            msgMap.getOrDefault("replayCommentNum", 0L));
+        
+        // 分享和直接访问数据
+        result.setShareUrlNum(firstEntryMap == null ? BigDecimal.valueOf(0) : 
+            firstEntryMap.getOrDefault("shareUrlNum", BigDecimal.valueOf(0)));
+        result.setDirectAccessNum(firstEntryMap == null ? BigDecimal.valueOf(0) : 
+            firstEntryMap.getOrDefault("directAccessNum", BigDecimal.valueOf(0)));
+        
+        // 邀请用户列表
         List<LiveUserFirstVo> liveUserFirstVos = liveUserFirstEntryMapper.selectDashboardInviteCount(liveId);
         result.setInviteUserList(liveUserFirstVos);
+        
         return R.ok().put("data", result);
     }
 

+ 5 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveGoodsServiceImpl.java

@@ -161,6 +161,11 @@ public class LiveGoodsServiceImpl  implements ILiveGoodsService {
         baseMapper.updateLiveIsShow(goodsId, liveId);
     }
 
+    @Override
+    public void updateLiveGoodsStatus(Long goodsId, Integer status) {
+        baseMapper.updateLiveGoodsStatus(goodsId, status);
+    }
+
     @Override
     public R getStoreByLiveId(Long liveId, String key, String userId) {
         LiveGoods liveGoods = new LiveGoods();

+ 104 - 4
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -9,11 +9,15 @@ import com.fs.common.constant.LiveKeysConstant;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.his.domain.FsUser;
 import com.fs.his.service.IFsUserService;
 import com.fs.live.domain.Live;
+import com.fs.live.domain.LiveVideo;
 import com.fs.live.domain.LiveWatchUser;
 import com.fs.live.mapper.LiveWatchUserMapper;
+import com.fs.live.mapper.LiveMapper;
+import com.fs.live.mapper.LiveVideoMapper;
 import com.fs.live.service.ILiveWatchUserService;
 import com.fs.live.vo.LiveWatchUserStatistics;
 import com.fs.live.vo.LiveWatchUserVO;
@@ -42,6 +46,10 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     private IFsUserService fsUserService;
     @Autowired
     private LiveWatchUserMapper baseMapper;
+    @Autowired
+    private LiveMapper liveMapper;
+    @Autowired
+    private LiveVideoMapper liveVideoMapper;
 
 
     /**
@@ -144,12 +152,37 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     }
 
     @Override
-    public LiveWatchUser join(long liveId, long userId) {
+    public LiveWatchUser join(long liveId, long userId, String location) {
         LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
         FsUser fsUserVO = fsUserService.selectFsUserByUserId(userId);
+        Date now = DateUtils.getNowDate();
+
+        // 查询直播间信息
+        Live live = liveMapper.selectLiveByLiveId(liveId);
+
+        // 判断用户进入时间:如果进入时间大于直播结束时间,说明是回放
+        boolean isReplay = false;
+        if (live != null && live.getFinishTime() != null) {
+            Date finishTime = java.sql.Timestamp.valueOf(live.getFinishTime());
+            isReplay = now.after(finishTime);
+        }
+
         if(liveWatchUser != null) {
-            liveWatchUser.setUpdateTime(DateUtils.getNowDate());
+            liveWatchUser.setUpdateTime(now);
             liveWatchUser.setOnline(0);
+
+            // 更新location
+            if (StringUtils.isNotEmpty(location)) {
+                liveWatchUser.setLocation(location);
+            }
+
+            // 更新进入标记
+            if (isReplay) {
+                liveWatchUser.setReplayFlag(1);
+            } else {
+                liveWatchUser.setLiveFlag(1);
+            }
+
             baseMapper.updateLiveWatchUser(liveWatchUser);
         }else{
             liveWatchUser = new LiveWatchUser();
@@ -158,8 +191,75 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
             liveWatchUser.setAvatar(fsUserVO.getAvatar());
             liveWatchUser.setMsgStatus(0);
             liveWatchUser.setOnline(0);
-            liveWatchUser.setCreateTime(DateUtils.getNowDate());
-            liveWatchUser.setUpdateTime(DateUtils.getNowDate());
+            liveWatchUser.setLocation(location);
+
+            // 设置进入标记
+            if (isReplay) {
+                liveWatchUser.setReplayFlag(1);
+                liveWatchUser.setLiveFlag(0);
+            } else {
+                liveWatchUser.setLiveFlag(1);
+                liveWatchUser.setReplayFlag(0);
+            }
+
+            liveWatchUser.setCreateTime(now);
+            liveWatchUser.setUpdateTime(now);
+            baseMapper.insertLiveWatchUser(liveWatchUser);
+        }
+        liveWatchUser.setAvatar(fsUserVO.getAvatar());
+        liveWatchUser.setNickName(fsUserVO.getNickname());
+        String hashKey  = String.format(LiveKeysConstant.LIVE_WATCH_USERS, liveId);
+        redisCache.hashPut(hashKey, String.valueOf(userId), JSON.toJSONString(liveWatchUser));
+        return liveWatchUser;
+    }
+
+    @Override
+    public LiveWatchUser joinWithoutLocation(long liveId, long userId) {
+        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
+        FsUser fsUserVO = fsUserService.selectFsUserByUserId(userId);
+        Date now = DateUtils.getNowDate();
+
+        // 查询直播间信息
+        Live live = liveMapper.selectLiveByLiveId(liveId);
+
+        // 判断用户进入时间:如果进入时间大于直播结束时间,说明是回放
+        boolean isReplay = false;
+        if (live != null && live.getFinishTime() != null) {
+            Date finishTime = java.sql.Timestamp.valueOf(live.getFinishTime());
+            isReplay = now.after(finishTime);
+        }
+
+        if(liveWatchUser != null) {
+            liveWatchUser.setUpdateTime(now);
+            liveWatchUser.setOnline(0);
+
+            // 更新进入标记
+            if (isReplay) {
+                liveWatchUser.setReplayFlag(1);
+            } else {
+                liveWatchUser.setLiveFlag(1);
+            }
+
+            baseMapper.updateLiveWatchUser(liveWatchUser);
+        }else{
+            liveWatchUser = new LiveWatchUser();
+            liveWatchUser.setLiveId(liveId);
+            liveWatchUser.setUserId(userId);
+            liveWatchUser.setAvatar(fsUserVO.getAvatar());
+            liveWatchUser.setMsgStatus(0);
+            liveWatchUser.setOnline(0);
+
+            // 设置进入标记
+            if (isReplay) {
+                liveWatchUser.setReplayFlag(1);
+                liveWatchUser.setLiveFlag(0);
+            } else {
+                liveWatchUser.setLiveFlag(1);
+                liveWatchUser.setReplayFlag(0);
+            }
+
+            liveWatchUser.setCreateTime(now);
+            liveWatchUser.setUpdateTime(now);
             baseMapper.insertLiveWatchUser(liveWatchUser);
         }
         liveWatchUser.setAvatar(fsUserVO.getAvatar());

+ 25 - 10
fs-service/src/main/java/com/fs/live/vo/LiveDashBoardDataVo.java

@@ -11,20 +11,35 @@ public class LiveDashBoardDataVo {
     // 在线人数 liveWatchUser
     private BigDecimal onlineNum;
 
-    // 观看人数 liveData
-    private Integer viewNum;
+    // 直播观看人数 liveData (原viewNum,现在区分直播)
+    private Integer liveViewNum;
 
-    // 点赞数量 liveData
-    private Integer likeNum;
+    // 回放观看人数 liveData
+    private Integer replayViewNum;
 
-    // 评论数量 liveMsg
-    private Long commentNum;
+    // 直播点赞数量 liveData (原likeNum,现在区分直播)
+    private Integer liveLikeNum;
 
-    // 新用户数量 liveWatchUser
-    private BigDecimal newUserNum;
+    // 回放点赞数量 liveData
+    private Integer replayLikeNum;
 
-    // 老用户数量 liveWatchUser
-    private BigDecimal oldUserNum;
+    // 直播评论数量 liveMsg
+    private Long liveCommentNum;
+
+    // 回放评论数量 liveMsg
+    private Long replayCommentNum;
+
+    // 直播新用户数量 liveWatchUser
+    private BigDecimal liveNewUserNum;
+
+    // 回放新用户数量 liveWatchUser
+    private BigDecimal replayNewUserNum;
+
+    // 直播老用户数量 liveWatchUser
+    private BigDecimal liveOldUserNum;
+
+    // 回放老用户数量 liveWatchUser
+    private BigDecimal replayOldUserNum;
 
     // 分享链接来源数量 liveUserFirstEntry
     private BigDecimal shareUrlNum;

+ 49 - 22
fs-service/src/main/java/com/fs/qw/service/impl/QwWatchLogServiceImpl.java

@@ -31,6 +31,7 @@ import com.fs.store.service.cache.IFsUserCacheService;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.hc.openapi.tool.util.StringUtils;
 import org.apache.commons.collections4.CollectionUtils;
+import org.jetbrains.annotations.Nullable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -149,17 +150,13 @@ public class QwWatchLogServiceImpl extends ServiceImpl<QwWatchLogMapper, QwWatch
     @Override
     public List<QwWatchLogStatisticsListVO> selectQwWatchLogStatisticsListVOExport(FsCourseWatchLogListParam param) {
         List<Long> deptIds = param.getDeptIds();
-        if (deptIds !=null && !deptIds.isEmpty()){
-            List<CompanyDept> companyDeptList  = companyDeptMapper.selectCompanyDeptByIds(deptIds);
-            if (companyDeptList!=null && !companyDeptList.isEmpty()){
-                for (CompanyDept c : companyDeptList) {
-                    if (c.getParentId() == 0L) {
-                        param.setDeptId(null);
-                        param.setDeptIds(null);
-                        break;
-                    }
-                }
-            }
+        List<Long> allDeptIds = getAllDeptIds(deptIds);
+        if (allDeptIds == null){
+            param.setDeptId(null);
+            param.setDeptIds(null);
+        } else if (!allDeptIds.isEmpty()){
+            param.setDeptIds(allDeptIds);
+            param.setDeptId(null);
         } else {
             CompanyDept companyDept = companyDeptMapper.selectCompanyDeptById(param.getDeptId());
             if (ObjectUtils.isNotEmpty(companyDept)&&companyDept.getParentId()==0L){
@@ -225,23 +222,20 @@ public class QwWatchLogServiceImpl extends ServiceImpl<QwWatchLogMapper, QwWatch
     @Override
     public TableDataInfo selectQwWatchLogStatisticsListVO(QwWatchLogStatisticsListParam param) {
         List<Long> deptIds = param.getDeptIds();
-        if (deptIds !=null && !deptIds.isEmpty()){
-            List<CompanyDept> companyDeptList  = companyDeptMapper.selectCompanyDeptByIds(deptIds);
-            if (companyDeptList!=null && !companyDeptList.isEmpty()){
-                for (CompanyDept c : companyDeptList) {
-                    if (c.getParentId() == 0L) {
-                        param.setDeptId(null);
-                        param.setDeptIds(null);
-                        break;
-                    }
-                }
-            }
+        List<Long> allDeptIds = getAllDeptIds(deptIds);
+        if (allDeptIds == null){
+            param.setDeptId(null);
+            param.setDeptIds(null);
+        } else if (!allDeptIds.isEmpty()){
+            param.setDeptIds(allDeptIds);
+            param.setDeptId(null);
         } else {
             CompanyDept companyDept = companyDeptMapper.selectCompanyDeptById(param.getDeptId());
             if (ObjectUtils.isNotEmpty(companyDept)&&companyDept.getParentId()==0L){
                 param.setDeptId(null);
             }
         }
+
         TableDataInfo rspData = new TableDataInfo();
         rspData.setCode(HttpStatus.SUCCESS);
         rspData.setMsg("查询成功");
@@ -277,6 +271,39 @@ public class QwWatchLogServiceImpl extends ServiceImpl<QwWatchLogMapper, QwWatch
         return rspData;
     }
 
+    /**
+     * 根据部门id查询所有子部门
+     * @param deptIds
+     * @return
+     */
+    private @Nullable List<Long> getAllDeptIds( List<Long> deptIds) {
+        List<Long> allDeptIds = new ArrayList<>();
+        if (deptIds == null || deptIds.isEmpty()){
+            return allDeptIds;
+        } else {
+            allDeptIds.addAll(deptIds);
+        }
+        while (true){
+            if (deptIds.isEmpty()){
+                break;
+            }
+            List<CompanyDept> companyDeptList  = companyDeptMapper.selectCompanyDeptByIds(deptIds);
+            if (companyDeptList.isEmpty()){
+               break;
+            }
+            deptIds = new ArrayList<>();
+            for (CompanyDept c : companyDeptList) {
+                List<Long> ids = companyDeptMapper.selectCompanyDeptByParentId(c.getDeptId());
+                allDeptIds.addAll(ids);
+                deptIds.addAll(ids);
+                if (c.getParentId() == 0L) {
+                    return null;
+                }
+            }
+        }
+        return allDeptIds;
+    }
+
     /**
      * 查询进线统计,排除掉转接的数据
      * @param param

+ 131 - 0
fs-service/src/main/java/com/fs/store/domain/FsStoreActivity.java

@@ -0,0 +1,131 @@
+package com.fs.store.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+
+/**
+ * 活动对象 fs_store_activity
+ * 
+ * @author fs
+ * @date 2022-11-18
+ */
+public class FsStoreActivity extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long activityId;
+
+    /** 标题 */
+    @Excel(name = "标题")
+    private String title;
+
+    /** 描述 */
+    @Excel(name = "描述")
+    private String descs;
+
+    /** 封面图 */
+    @Excel(name = "封面图")
+    private String logoUrl;
+
+    /** 活动图 */
+    @Excel(name = "活动图")
+    private String images;
+
+    /** 活动商品 */
+    @Excel(name = "活动商品")
+    private String productIds;
+
+    /** 活动内容 */
+    @Excel(name = "活动内容")
+    private String content;
+
+    /** 状态 0禁用 1启用 */
+    @Excel(name = "状态 0禁用 1启用")
+    private Integer status;
+
+    private Integer shareNumber;
+
+    public Integer getShareNumber() {
+        return shareNumber;
+    }
+
+    public void setShareNumber(Integer shareNumber) {
+        this.shareNumber = shareNumber;
+    }
+
+    public String getDescs() {
+        return descs;
+    }
+
+    public void setDescs(String descs) {
+        this.descs = descs;
+    }
+
+    public void setActivityId(Long activityId)
+    {
+        this.activityId = activityId;
+    }
+
+    public Long getActivityId() 
+    {
+        return activityId;
+    }
+    public void setTitle(String title) 
+    {
+        this.title = title;
+    }
+
+    public String getTitle() 
+    {
+        return title;
+    }
+
+    public void setLogoUrl(String logoUrl) 
+    {
+        this.logoUrl = logoUrl;
+    }
+
+    public String getLogoUrl() 
+    {
+        return logoUrl;
+    }
+    public void setImages(String images) 
+    {
+        this.images = images;
+    }
+
+    public String getImages() 
+    {
+        return images;
+    }
+    public void setProductIds(String productIds) 
+    {
+        this.productIds = productIds;
+    }
+
+    public String getProductIds() 
+    {
+        return productIds;
+    }
+    public void setContent(String content) 
+    {
+        this.content = content;
+    }
+
+    public String getContent() 
+    {
+        return content;
+    }
+    public void setStatus(Integer status) 
+    {
+        this.status = status;
+    }
+
+    public Integer getStatus() 
+    {
+        return status;
+    }
+
+
+}

+ 69 - 0
fs-service/src/main/java/com/fs/store/mapper/FsStoreActivityMapper.java

@@ -0,0 +1,69 @@
+package com.fs.store.mapper;
+
+import com.fs.store.domain.FsStoreActivity;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * 活动Mapper接口
+ *
+ * @author fs
+ * @date 2022-11-18
+ */
+public interface FsStoreActivityMapper
+{
+    /**
+     * 查询活动
+     *
+     * @param activityId 活动ID
+     * @return 活动
+     */
+    public FsStoreActivity selectFsStoreActivityById(Long activityId);
+
+    /**
+     * 查询活动列表
+     *
+     * @param fsStoreActivity 活动
+     * @return 活动集合
+     */
+    public List<FsStoreActivity> selectFsStoreActivityList(FsStoreActivity fsStoreActivity);
+
+    /**
+     * 新增活动
+     *
+     * @param fsStoreActivity 活动
+     * @return 结果
+     */
+    public int insertFsStoreActivity(FsStoreActivity fsStoreActivity);
+
+    /**
+     * 修改活动
+     *
+     * @param fsStoreActivity 活动
+     * @return 结果
+     */
+    public int updateFsStoreActivity(FsStoreActivity fsStoreActivity);
+
+    /**
+     * 删除活动
+     *
+     * @param activityId 活动ID
+     * @return 结果
+     */
+    public int deleteFsStoreActivityById(Long activityId);
+
+    /**
+     * 批量删除活动
+     *
+     * @param activityIds 需要删除的数据ID
+     * @return 结果
+     */
+    public int deleteFsStoreActivityByIds(Long[] activityIds);
+    @Select("select * from fs_store_activity where status=1 order by activity_id desc limit 1")
+    FsStoreActivity selectFsStoreActivityByTop();
+
+    @Update("update fs_store_activity set share_number=share_number+1 where activity_id=#{activityId} ")
+    int addShare(Long activityId);
+}

+ 66 - 0
fs-service/src/main/java/com/fs/store/service/IFsStoreActivityService.java

@@ -0,0 +1,66 @@
+package com.fs.store.service;
+
+import com.fs.store.domain.FsStoreActivity;
+
+import java.util.List;
+
+/**
+ * 活动Service接口
+ *
+ * @author fs
+ * @date 2022-11-18
+ */
+public interface IFsStoreActivityService
+{
+    /**
+     * 查询活动
+     *
+     * @param activityId 活动ID
+     * @return 活动
+     */
+    public FsStoreActivity selectFsStoreActivityById(Long activityId);
+
+    /**
+     * 查询活动列表
+     *
+     * @param fsStoreActivity 活动
+     * @return 活动集合
+     */
+    public List<FsStoreActivity> selectFsStoreActivityList(FsStoreActivity fsStoreActivity);
+
+    /**
+     * 新增活动
+     *
+     * @param fsStoreActivity 活动
+     * @return 结果
+     */
+    public int insertFsStoreActivity(FsStoreActivity fsStoreActivity);
+
+    /**
+     * 修改活动
+     *
+     * @param fsStoreActivity 活动
+     * @return 结果
+     */
+    public int updateFsStoreActivity(FsStoreActivity fsStoreActivity);
+
+    /**
+     * 批量删除活动
+     *
+     * @param activityIds 需要删除的活动ID
+     * @return 结果
+     */
+    public int deleteFsStoreActivityByIds(Long[] activityIds);
+
+    /**
+     * 删除活动信息
+     *
+     * @param activityId 活动ID
+     * @return 结果
+     */
+    public int deleteFsStoreActivityById(Long activityId);
+
+    FsStoreActivity selectFsStoreActivityByTop();
+
+    int addShare(Long activityId);
+}

+ 106 - 0
fs-service/src/main/java/com/fs/store/service/impl/FsStoreActivityServiceImpl.java

@@ -0,0 +1,106 @@
+package com.fs.store.service.impl;
+
+import com.fs.common.utils.DateUtils;
+import com.fs.store.domain.FsStoreActivity;
+import com.fs.store.mapper.FsStoreActivityMapper;
+import com.fs.store.service.IFsStoreActivityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 活动Service业务层处理
+ *
+ * @author fs
+ * @date 2022-11-18
+ */
+@Service
+public class FsStoreActivityServiceImpl implements IFsStoreActivityService
+{
+    @Autowired
+    private FsStoreActivityMapper fsStoreActivityMapper;
+
+    /**
+     * 查询活动
+     *
+     * @param activityId 活动ID
+     * @return 活动
+     */
+    @Override
+    public FsStoreActivity selectFsStoreActivityById(Long activityId)
+    {
+        return fsStoreActivityMapper.selectFsStoreActivityById(activityId);
+    }
+
+    /**
+     * 查询活动列表
+     *
+     * @param fsStoreActivity 活动
+     * @return 活动
+     */
+    @Override
+    public List<FsStoreActivity> selectFsStoreActivityList(FsStoreActivity fsStoreActivity)
+    {
+        return fsStoreActivityMapper.selectFsStoreActivityList(fsStoreActivity);
+    }
+
+    /**
+     * 新增活动
+     *
+     * @param fsStoreActivity 活动
+     * @return 结果
+     */
+    @Override
+    public int insertFsStoreActivity(FsStoreActivity fsStoreActivity)
+    {
+        fsStoreActivity.setCreateTime(DateUtils.getNowDate());
+        return fsStoreActivityMapper.insertFsStoreActivity(fsStoreActivity);
+    }
+
+    /**
+     * 修改活动
+     *
+     * @param fsStoreActivity 活动
+     * @return 结果
+     */
+    @Override
+    public int updateFsStoreActivity(FsStoreActivity fsStoreActivity)
+    {
+        return fsStoreActivityMapper.updateFsStoreActivity(fsStoreActivity);
+    }
+
+    /**
+     * 批量删除活动
+     *
+     * @param activityIds 需要删除的活动ID
+     * @return 结果
+     */
+    @Override
+    public int deleteFsStoreActivityByIds(Long[] activityIds)
+    {
+        return fsStoreActivityMapper.deleteFsStoreActivityByIds(activityIds);
+    }
+
+    /**
+     * 删除活动信息
+     *
+     * @param activityId 活动ID
+     * @return 结果
+     */
+    @Override
+    public int deleteFsStoreActivityById(Long activityId)
+    {
+        return fsStoreActivityMapper.deleteFsStoreActivityById(activityId);
+    }
+
+    @Override
+    public FsStoreActivity selectFsStoreActivityByTop() {
+        return fsStoreActivityMapper.selectFsStoreActivityByTop();
+    }
+
+    @Override
+    public int addShare(Long activityId) {
+        return fsStoreActivityMapper.addShare(activityId);
+    }
+}

+ 100 - 0
fs-service/src/main/resources/application-config-druid-bjzm-test.yml

@@ -0,0 +1,100 @@
+baidu:
+  token: 12313231232
+  back-domain: https://www.xxxx.com
+#配置
+logging:
+  level:
+    org.springframework.web: INFO
+    com.github.binarywang.demo.wx.cp: DEBUG
+    me.chanjar.weixin: DEBUG
+wx:
+  miniapp:
+    configs:
+      - appid: wx94951f52d3ac5e25   #北京存在文化
+        secret: bfe27b20c6e3c4232a1d4ef36228e84b #北京存在文化
+        token: Ncbnd7lJvkripxxna6NAWCxCrvC
+        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+        msgDataFormat: JSON
+  cp:
+    corpId: wwa46ffb9ff6ac35b8 #企业ID北京存在文化
+    appConfigs:
+      - agentId: 1000070       #北京存在文化
+        secret: pu2EFz6gY2Fo2K-aRUxLPaAkKIaMJJRp8ES9JdpHkp4 #北京存在文化
+        token: PPKOdAlCoMO
+        aesKey: PKvaxtpSv8NGpfTDm7VUHIK8Wok2ESyYX24qpXJAdMP
+  pay:
+    appId:  #微信公众号或者小程序等的appid
+    mchId:  #微信支付商户号
+    mchKey:  #微信支付商户密钥
+    subAppId:  #服务商模式下的子商户公众账号ID
+    subMchId:  #服务商模式下的子商户号
+    keyPath: c:\\cert\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
+    notifyUrl: https://userapp.his.runtzh.com/app/wxpay/wxPayNotify
+  mp:
+    useRedis: false
+    redisConfig:
+      host: 127.0.0.1
+      port: 6379
+      timeout: 2000
+    configs:
+      - appId: wxc8534f3a7c4f306c # 第一个公众号的appid  //公众号名称:德瑞康
+        secret: 7a4bac8d7628c2adf70575628826e2b8 # 公众号的appsecret--德瑞康
+        token: PPKOdAlCoMO # 接口配置里的Token值
+        aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+aifabu:  #爱链接
+  appKey: 7b471be905ab17e00f3b858c6710dd117601d008
+watch:
+  watchUrl: watch.ylrzcloud.com/prod-api
+  #  account: tcloud
+  #  password: mdf-m2h_6yw2$hq
+  account1: ccif #866655060138751
+  password1: cp-t5or_6xw7$mt
+  account2: tcloud #rt500台
+  password2: mdf-m2h_6yw2$hq
+  account3: whr
+  password3: v9xsKuqn_$d2y
+
+fs :
+  jwt:
+    # 加密秘钥
+    secret: f4e2e52021218f86b67cde581c0f9eb5
+    # token有效时长,7天,单位秒
+    expire: 31536000
+    header: AppToken
+  commonApi: http://172.16.16.6:7771
+  h5CommonApi: http://172.16.16.6:7771
+nuonuo:
+  key: 10924508
+  secret: A2EB20764D304D16
+
+# 存储捅配置
+tencent_cloud_config:
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: bjzm-1323137866
+  app_id: 1323137866
+  region: ap-guangzhou
+  proxy: bjzm
+tmp_secret_config:
+  secret_id: AKIDCj7NSNAovtqeJpBau8GZ4CGB71thXIxX
+  secret_key: lTB5zwqqz7CNhzDOWivFWedgfTBgxgBT
+  bucket: fs-1319721001
+  app_id: 1319721001
+  region: ap-chongqing
+  proxy: fs
+cloud_host:
+  company_name: 北京卓美
+  projectCode: BJZM
+headerImg:
+  imgUrl:
+
+ipad:
+  ipadUrl: http://ipad.cdwjyyh.com
+  aiApi: 1212121212
+  voiceApi:
+  commonApi:
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:
+
+

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

@@ -79,7 +79,7 @@ tencent_cloud_config:
   proxy: cdhyt
 cloud_host:
   company_name: 鹤颜堂
-  projectCode: HEYANTANG
+  projectCode: CDHYT
 headerImg:
   imgUrl: https
 ipad:

+ 2 - 2
fs-service/src/main/resources/application-config-druid-yxj.yml

@@ -75,10 +75,10 @@ nuonuo:
 tencent_cloud_config:
   secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
   secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
-  bucket: syysy-1323137866
+  bucket: yxj-1323137866
   app_id: 1323137866
   region: ap-chongqing
-  proxy: syysy
+  proxy: yxj
 cloud_host:
   company_name: 易行健
   projectCode: whyxj

+ 158 - 0
fs-service/src/main/resources/application-druid-bjzm-test.yml

@@ -0,0 +1,158 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-bjzm-test,common
+    # redis 配置
+    redis:
+        host: 127.0.0.1
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 10s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 100
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+#        clickhouse:
+#            type: com.alibaba.druid.pool.DruidDataSource
+#            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+#            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+#            username: rt_2024
+#            password: Yzx_19860213
+#            initialSize: 10
+#            maxActive: 100
+#            minIdle: 10
+#            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                  url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  username: root
+                  password: Ylrz_1q2w3e4r5t6y
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: localhost:8080
+    producer:
+        group: my-producer-group
+        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
+        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+    consumer:
+        group: common-group
+        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
+        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+openIM:
+    secret: openIM123
+    userID: imAdmin
+    url: https://localhost/api
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: true
+#是否使用新im
+im:
+    type: NONE
+

+ 2 - 2
fs-service/src/main/resources/application-druid-yxj.yml

@@ -168,6 +168,6 @@ openIM:
 im:
     type: OPENIM
 #是否为新商户,新商户不走mpOpenId
-isNewWxMerchant: true
-enableRedPackAccount: 0
+isNewWxMerchant: false
+enableRedPackAccount: 1
 

+ 17 - 0
fs-service/src/main/resources/mapper/course/FsUserCompanyUserMapper.xml

@@ -194,4 +194,21 @@
         </where>
     </select>
 
+    <!-- 批量删除微信用户和销售关系 -->
+    <delete id="batchDeleteByIds">
+        DELETE FROM fs_user_company_user
+        WHERE
+        <choose>
+            <when test="userIds != null and userIds.size() > 0">
+                    user_id IN
+                <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
+                    #{userId}
+                </foreach>
+            </when>
+            <otherwise>
+                user_id = 0
+            </otherwise>
+        </choose>
+    </delete>
+
 </mapper>

+ 18 - 13
fs-service/src/main/resources/mapper/hisStore/FsUserBillScrmMapper.xml

@@ -3,9 +3,9 @@
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.hisStore.mapper.FsUserBillScrmMapper">
-    
+
     <resultMap type="FsUserBillScrm" id="FsUserBillResult">
-        <result property="id"    column="id"    />
+        <result property="billId"    column="bill_id"    />
         <result property="userId"    column="user_id"    />
         <result property="businessId"    column="business_id"    />
         <result property="category"    column="category"    />
@@ -13,6 +13,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="type"    column="type"    />
         <result property="title"    column="title"    />
         <result property="number"    column="number"    />
+        <result property="money"    column="money"    />
         <result property="balance"    column="balance"    />
         <result property="remark"    column="remark"    />
         <result property="createTime"    column="create_time"    />
@@ -22,12 +23,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsUserBillVo">
-        select id, user_id, business_id, category, bill_type, type, title, number, balance, remark, create_time, update_time, status,tui_user_id from fs_user_bill
+        select bill_id, user_id, business_id, money,category, bill_type, type, title, number, balance, remark, create_time, update_time, status,tui_user_id from fs_user_bill
     </sql>
 
     <select id="selectFsUserBillList" parameterType="FsUserBillScrm" resultMap="FsUserBillResult">
         <include refid="selectFsUserBillVo"/>
-        <where>  
+        <where>
             <if test="userId != null "> and user_id = #{userId}</if>
             <if test="businessId != null  and businessId != ''"> and business_id = #{businessId}</if>
             <if test="category != null  and category != ''"> and category = #{category}</if>
@@ -36,17 +37,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="title != null  and title != ''"> and title = #{title}</if>
             <if test="number != null "> and number = #{number}</if>
             <if test="balance != null "> and balance = #{balance}</if>
+            <if test="money != null "> and money = #{money}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="tuiUserId != null "> and tui_user_id = #{tuiUserId}</if>
         </where>
     </select>
-    
+
     <select id="selectFsUserBillById" parameterType="Long" resultMap="FsUserBillResult">
         <include refid="selectFsUserBillVo"/>
-        where id = #{id}
+        where bill_id = #{id}
     </select>
-        
-    <insert id="insertFsUserBill" parameterType="FsUserBillScrm" useGeneratedKeys="true" keyProperty="id">
+
+    <insert id="insertFsUserBill" parameterType="FsUserBillScrm" useGeneratedKeys="true" keyProperty="billId">
         insert into fs_user_bill
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="userId != null">user_id,</if>
@@ -62,6 +64,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">update_time,</if>
             <if test="status != null">status,</if>
             <if test="tuiUserId != null">tui_user_id,</if>
+            <if test="money != null">money,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="userId != null">#{userId},</if>
@@ -77,6 +80,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">#{updateTime},</if>
             <if test="status != null">#{status},</if>
             <if test="tuiUserId != null">#{tuiUserId},</if>
+            <if test="money != null">#{money},</if>
          </trim>
     </insert>
 
@@ -95,20 +99,21 @@ 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="money != null">money = #{money},</if>
             <if test="tuiUserId != null">tui_user_id = #{tuiUserId},</if>
         </trim>
-        where id = #{id}
+        where bill_id = #{id}
     </update>
 
     <delete id="deleteFsUserBillById" parameterType="Long">
-        delete from fs_user_bill where id = #{id}
+        delete from fs_user_bill where bill_id = #{id}
     </delete>
 
     <delete id="deleteFsUserBillByIds" parameterType="String">
-        delete from fs_user_bill where id in 
+        delete from fs_user_bill where bill_id in
         <foreach item="id" collection="array" open="(" separator="," close=")">
             #{id}
         </foreach>
     </delete>
-    
-</mapper>
+
+</mapper>

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

@@ -560,6 +560,9 @@
             <if test="qwExtId != null">qw_ext_id = #{qwExtId},</if>
             <if test="companyId != null">company_id = #{companyId},</if>
             <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
+            <if test="isPromoter != null">is_promoter = #{isPromoter},</if>
+            <if test="spreadUserId != null">spread_user_id = #{spreadUserId},</if>
+            <if test="brokeragePrice != null">brokerage_price = #{brokeragePrice},</if>
         </trim>
         where user_id = #{userId}
     </update>

+ 95 - 0
fs-service/src/main/resources/mapper/store/FsStoreActivityMapper.xml

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.store.mapper.FsStoreActivityMapper">
+
+    <resultMap type="FsStoreActivity" id="FsStoreActivityResult">
+        <result property="activityId"    column="activity_id"    />
+        <result property="title"    column="title"    />
+        <result property="descs"    column="descs"    />
+        <result property="logoUrl"    column="logo_url"    />
+        <result property="images"    column="images"    />
+        <result property="productIds"    column="product_ids"    />
+        <result property="content"    column="content"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="status"    column="status"    />
+        <result property="shareNumber"    column="share_number"    />
+    </resultMap>
+
+    <sql id="selectFsStoreActivityVo">
+        select activity_id, title, descs, logo_url, images, product_ids, content, create_time, status,share_number from fs_store_activity
+    </sql>
+
+    <select id="selectFsStoreActivityList" parameterType="FsStoreActivity" resultMap="FsStoreActivityResult">
+        <include refid="selectFsStoreActivityVo"/>
+        <where>
+            <if test="title != null  and title != ''"> and title = #{title}</if>
+            <if test="logoUrl != null  and logoUrl != ''"> and logo_url = #{logoUrl}</if>
+            <if test="images != null  and images != ''"> and images = #{images}</if>
+            <if test="productIds != null  and productIds != ''"> and product_ids = #{productIds}</if>
+            <if test="content != null  and content != ''"> and content = #{content}</if>
+            <if test="status != null "> and status = #{status}</if>
+        </where>
+        order by activity_id desc
+    </select>
+
+    <select id="selectFsStoreActivityById" parameterType="Long" resultMap="FsStoreActivityResult">
+        <include refid="selectFsStoreActivityVo"/>
+        where activity_id = #{activityId}
+    </select>
+
+    <insert id="insertFsStoreActivity" parameterType="FsStoreActivity" useGeneratedKeys="true" keyProperty="activityId">
+        insert into fs_store_activity
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="title != null">title,</if>
+            <if test="descs != null">descs,</if>
+            <if test="logoUrl != null">logo_url,</if>
+            <if test="images != null">images,</if>
+            <if test="productIds != null">product_ids,</if>
+            <if test="content != null">content,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="status != null">status,</if>
+            <if test="shareNumber != null">share_number,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="title != null">#{title},</if>
+            <if test="descs != null">#{descs},</if>
+            <if test="logoUrl != null">#{logoUrl},</if>
+            <if test="images != null">#{images},</if>
+            <if test="productIds != null">#{productIds},</if>
+            <if test="content != null">#{content},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="status != null">#{status},</if>
+            <if test="shareNumber != null">#{shareNumber},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsStoreActivity" parameterType="FsStoreActivity">
+        update fs_store_activity
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="title != null">title = #{title},</if>
+            <if test="descs != null">descs = #{descs},</if>
+            <if test="logoUrl != null">logo_url = #{logoUrl},</if>
+            <if test="images != null">images = #{images},</if>
+            <if test="productIds != null">product_ids = #{productIds},</if>
+            <if test="content != null">content = #{content},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="shareNumber != null">share_number = #{shareNumber},</if>
+        </trim>
+        where activity_id = #{activityId}
+    </update>
+
+    <delete id="deleteFsStoreActivityById" parameterType="Long">
+        delete from fs_store_activity where activity_id = #{activityId}
+    </delete>
+
+    <delete id="deleteFsStoreActivityByIds" parameterType="String">
+        delete from fs_store_activity where activity_id in
+        <foreach item="activityId" collection="array" open="(" separator="," close=")">
+            #{activityId}
+        </foreach>
+    </delete>
+
+</mapper>

+ 63 - 0
fs-user-app/src/main/java/com/fs/app/controller/StoreActivityController.java

@@ -0,0 +1,63 @@
+package com.fs.app.controller;
+
+
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsPackage;
+import com.fs.his.service.IFsPackageService;
+import com.fs.store.domain.FsStoreActivity;
+import com.fs.store.service.IFsStoreActivityService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+@Api("活动接口")
+@RestController
+@RequestMapping(value="/app/activity")
+public class StoreActivityController extends  AppBaseController {
+
+    @Autowired
+    private IFsStoreActivityService activityService;
+
+    @Autowired
+    private IFsPackageService packageService;
+
+    @ApiOperation("获取活动")
+    @GetMapping("/getStoreActivity")
+    public R getStoreActivity( HttpServletRequest request){
+        FsStoreActivity activity=activityService.selectFsStoreActivityByTop();
+        return R.ok().put("activity",activity);
+    }
+
+
+    @ApiOperation("获取活动详情")
+    @GetMapping("/getStoreActivityDetails")
+    public R getStoreActivityDetails(@RequestParam(value = "activityId")Long activityId, HttpServletRequest request){
+        FsStoreActivity activity=activityService.selectFsStoreActivityById(activityId);
+        List<FsPackage> products =new ArrayList<>();
+        String productIds = activity.getProductIds();
+        if(StringUtils.isNotBlank(productIds)){
+            Long[] list = Arrays.stream(productIds.split(","))
+                    .map(Long::valueOf)
+                    .toArray(Long[]::new);
+            products = packageService.selectFsPackageListByIds(list);
+        }
+        return R.ok().put("activity",activity).put("products",products);
+    }
+    @ApiOperation("分享")
+    @PostMapping("/share")
+    public R share(@RequestParam(value = "activityId")Long activityId, HttpServletRequest request){
+        activityService.addShare(activityId);
+        return R.ok();
+    }
+
+
+
+}

+ 16 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/H5ScrmController.java

@@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 
 @Controller
@@ -31,6 +32,21 @@ public class H5ScrmController
         //return R.ok().put("userAgreement", config.getUserRegister());
         return mv;
     }
+    @GetMapping("/userAgreementNew")
+    @ResponseBody
+    public String userAgreementNew(){
+        String json=configService.selectConfigByKey("store.agreement");
+        AgreementConfig config= JSONUtil.toBean(json, AgreementConfig.class);
+        return config.getUserAgreement();
+    }
+    @GetMapping("/privacyPolicyNew")
+    @ResponseBody
+    public String privacyPolicyNew( )
+    {
+        String json=configService.selectConfigByKey("store.agreement");
+        AgreementConfig config= JSONUtil.toBean(json, AgreementConfig.class);
+        return config.getPrivacyPolicy();
+    }
     @GetMapping("/privacyPolicy")
     public ModelAndView privacyPolicy( )
     {