瀏覽代碼

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

caoliqin 1 天之前
父節點
當前提交
02ae662552
共有 34 個文件被更改,包括 469 次插入104 次删除
  1. 139 0
      deploy - test.sh
  2. 1 1
      fs-ad-new-api/src/main/java/com/fs/app/controller/CallbackController.java
  3. 47 27
      fs-ad-new-api/src/main/java/com/fs/app/controller/WeChatController.java
  4. 1 0
      fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeServiceImpl.java
  5. 1 0
      fs-ad-new-api/src/main/resources/application.yml
  6. 15 1
      fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java
  7. 2 1
      fs-admin/src/main/java/com/fs/live/controller/OrderController.java
  8. 10 2
      fs-company/src/main/java/com/fs/company/controller/live/LiveController.java
  9. 12 3
      fs-company/src/main/java/com/fs/company/controller/live/LiveDataController.java
  10. 1 0
      fs-company/src/main/java/com/fs/company/controller/live/OrderController.java
  11. 1 1
      fs-live-app/src/main/java/com/fs/live/task/Task.java
  12. 2 2
      fs-live-app/src/main/java/com/fs/live/websocket/auth/WebSocketConfigurator.java
  13. 1 8
      fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java
  14. 11 7
      fs-service/src/main/java/com/fs/live/service/impl/LiveDataServiceImpl.java
  15. 2 7
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  16. 1 2
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  17. 1 1
      fs-service/src/main/java/com/fs/live/vo/LiveUserDetailExportVO.java
  18. 16 11
      fs-service/src/main/java/com/fs/live/vo/MergedOrderExportVO.java
  19. 2 0
      fs-service/src/main/java/com/fs/live/vo/MergedOrderVO.java
  20. 18 0
      fs-service/src/main/java/com/fs/newAdv/controller/AdvMiniConfigController.java
  21. 58 0
      fs-service/src/main/java/com/fs/newAdv/domain/AdvMiniConfig.java
  22. 2 2
      fs-service/src/main/java/com/fs/newAdv/domain/PromotionAccount.java
  23. 2 2
      fs-service/src/main/java/com/fs/newAdv/integration/client/advertiser/BaiduApiClient.java
  24. 44 6
      fs-service/src/main/java/com/fs/newAdv/integration/client/advertiser/TencentApiClient.java
  25. 18 0
      fs-service/src/main/java/com/fs/newAdv/mapper/AdvMiniConfigMapper.java
  26. 16 0
      fs-service/src/main/java/com/fs/newAdv/service/IAdvMiniConfigService.java
  27. 1 1
      fs-service/src/main/java/com/fs/newAdv/service/ILeadService.java
  28. 20 0
      fs-service/src/main/java/com/fs/newAdv/service/impl/AdvMiniConfigServiceImpl.java
  29. 6 4
      fs-service/src/main/java/com/fs/newAdv/service/impl/LeadServiceImpl.java
  30. 1 1
      fs-service/src/main/java/com/fs/newAdv/vo/AccessTokenByAuthCodeVo.java
  31. 7 4
      fs-service/src/main/resources/mapper/hisStore/MergedOrderMapper.xml
  32. 2 2
      fs-service/src/main/resources/mapper/live/LiveCompletionPointsRecordMapper.xml
  33. 7 7
      fs-service/src/main/resources/mapper/live/LiveDataMapper.xml
  34. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/store/WxUserScrmController.java

+ 139 - 0
deploy - test.sh

@@ -0,0 +1,139 @@
+#!/bin/bash
+
+# 各服务对应的远程服务器配置 公司本地
+declare -A SERVER_CONFIG=(
+    # 服务名:IP地址
+    ["fs-live-app"]="129.28.193.135"
+)
+
+# 通用配置(所有服务器相同)
+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 -Xms1g -Xmx2g -XX:+UseG1GC -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 $app_name.jar --spring.profiles.active=druid-ylrz --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

+ 1 - 1
fs-ad-new-api/src/main/java/com/fs/app/controller/CallbackController.java

@@ -111,7 +111,7 @@ public class CallbackController {
         IAccessTokenClient tokenClient = (IAccessTokenClient) apiClient;
         IAccessTokenClient tokenClient = (IAccessTokenClient) apiClient;
         AccessTokenVo accessToken = tokenClient.getAccessTokenByAuthCode(AccessTokenByAuthCodeVo
         AccessTokenVo accessToken = tokenClient.getAccessTokenByAuthCode(AccessTokenByAuthCodeVo
                 .builder()
                 .builder()
-                .userId(byId.getAdAccountId())
+                .adAccountId(byId.getAdAccountId())
                 .appId(byId.getAppId())
                 .appId(byId.getAppId())
                 .authCode(authCode)
                 .authCode(authCode)
                 .appSecret(byId.getAppSecret())
                 .appSecret(byId.getAppSecret())

+ 47 - 27
fs-ad-new-api/src/main/java/com/fs/app/controller/WeChatController.java

@@ -4,9 +4,12 @@ import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.app.facade.CallbackProcessingFacadeService;
 import com.fs.app.facade.CallbackProcessingFacadeService;
 import com.fs.common.constant.SystemConstant;
 import com.fs.common.constant.SystemConstant;
 import com.fs.common.result.Result;
 import com.fs.common.result.Result;
+import com.fs.newAdv.domain.AdvMiniConfig;
+import com.fs.newAdv.service.IAdvMiniConfigService;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,7 +18,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 
 
+import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
 /**
 /**
@@ -34,34 +39,49 @@ public class WeChatController {
     @Autowired
     @Autowired
     private WxMaProperties properties;
     private WxMaProperties properties;
 
 
+    @Autowired
+    private IAdvMiniConfigService advMiniConfigService;
+
     @GetMapping("/getSchemeUrl")
     @GetMapping("/getSchemeUrl")
     public Result<String> getSchemeUrl(@RequestParam(value = "traceId") String traceId) {
     public Result<String> getSchemeUrl(@RequestParam(value = "traceId") String traceId) {
-        String appId = "wx0447a16ef6199f03";
-        String secret = "f063fcd818e31d4c89013a67f5123990";
-        HttpResponse execute2 = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token")
-                .form("grant_type", "client_credential")
-                .form("appid", appId)
-                .form("secret", secret)
-                .timeout(SystemConstant.API_TIMEOUT)
-                .execute();
-        JSONObject obj = JSONObject.parseObject(execute2.body());
-        String access_token = obj.getString("access_token");
-
-        Map<String, Object> map = new HashMap<>();
-        Map<String, Object> map2 = new HashMap<>();
-        map2.put("path", "/pages/shopping/productDetails");
-        map2.put("query", "traceId=" + traceId);
-        //map2.put("env_version", "trial");
-        map.put("jump_wxa", map2);
-        map.put("is_expire", false);
-        HttpResponse execute = HttpRequest.post("https://api.weixin.qq.com/wxa/generatescheme?access_token=" + access_token)
-                .header("Content-Type", "application/json")
-                .body(JSONUtil.toJsonStr(map))
-                .timeout(SystemConstant.API_TIMEOUT)
-                .execute();
-        log.info("getSchemeUrl:{}", execute.body());
-        obj = JSONObject.parseObject(execute.body());
-        //response.addHeader("Access-Control-Allow-Origin", "*");
-        return Result.success(obj.getString("openlink"));
+        List<AdvMiniConfig> list = advMiniConfigService.list(new LambdaQueryWrapper<AdvMiniConfig>()
+                .eq(AdvMiniConfig::getStatus, 1));
+        for (AdvMiniConfig advMiniConfig : list) {
+            try {
+                String access_token = advMiniConfig.getAccessToken();
+                // 判断token是否过期
+                if (advMiniConfig.getExpiresIn().isBefore(LocalDateTime.now().plusMinutes(10))) {
+                    HttpResponse execute2 = HttpRequest.get("https://api.weixin.qq.com/cgi-bin/token")
+                            .form("grant_type", "client_credential")
+                            .form("appid", advMiniConfig.getAppId())
+                            .form("secret", advMiniConfig.getAppSecret())
+                            .timeout(SystemConstant.API_TIMEOUT)
+                            .execute();
+                    JSONObject obj = JSONObject.parseObject(execute2.body());
+                    access_token = obj.getString("access_token");
+                    advMiniConfig.setAccessToken(access_token);
+                    advMiniConfigService.updateById(advMiniConfig);
+                }
+                Map<String, Object> map = new HashMap<>();
+                Map<String, Object> map2 = new HashMap<>();
+                map2.put("path", "pages/home/productList");
+                map2.put("query", "traceId=" + traceId);
+                map2.put("env_version", "trial");
+                map.put("jump_wxa", map2);
+                map.put("is_expire", false);
+                HttpResponse execute = HttpRequest.post("https://api.weixin.qq.com/wxa/generatescheme?access_token=" + access_token)
+                        .header("Content-Type", "application/json")
+                        .body(JSONUtil.toJsonStr(map))
+                        .timeout(SystemConstant.API_TIMEOUT)
+                        .execute();
+                log.info("getSchemeUrl:{}", execute.body());
+                JSONObject jsonObject = JSONObject.parseObject(execute.body());
+                //response.addHeader("Access-Control-Allow-Origin", "*");
+                return Result.success(jsonObject.getString("openlink"));
+            }catch (Exception e){
+                log.error("getSchemeUrl error:{}",advMiniConfig.getAppId(), e);
+            }
+        }
+        return Result.success("");
     }
     }
 }
 }

+ 1 - 0
fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeServiceImpl.java

@@ -221,6 +221,7 @@ public class CallbackProcessingFacadeServiceImpl implements CallbackProcessingFa
                                                Integer allocationRule,
                                                Integer allocationRule,
                                                Long allocationRuleId,
                                                Long allocationRuleId,
                                                Lead byTraceId) {
                                                Lead byTraceId) {
+
         // 二维码
         // 二维码
         String qrCode = "";
         String qrCode = "";
         if (allocationRule == 1) {
         if (allocationRule == 1) {

+ 1 - 0
fs-ad-new-api/src/main/resources/application.yml

@@ -7,3 +7,4 @@ spring:
     active: dev
     active: dev
 #    active: druid-ylrz
 #    active: druid-ylrz
 
 
+#

+ 15 - 1
fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java

@@ -8,6 +8,8 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.framework.web.service.TokenService;
 import com.fs.live.domain.LiveData;
 import com.fs.live.domain.LiveData;
 import com.fs.live.param.LiveDataParam;
 import com.fs.live.param.LiveDataParam;
 import com.fs.live.service.ILiveDataService;
 import com.fs.live.service.ILiveDataService;
@@ -29,6 +31,8 @@ public class LiveDataController extends BaseController {
 
 
     @Autowired
     @Autowired
     private ILiveDataService liveDataService;
     private ILiveDataService liveDataService;
+    @Autowired
+    private TokenService tokenService;
 
 
     /**
     /**
      * 直播数据页面卡片数据
      * 直播数据页面卡片数据
@@ -128,11 +132,21 @@ public class LiveDataController extends BaseController {
     /**
     /**
      * 查询直播间用户详情列表(SQL方式)
      * 查询直播间用户详情列表(SQL方式)
      * @param liveId 直播间ID
      * @param liveId 直播间ID
+     * @param pageNum 页码
+     * @param pageSize 每页大小
      * @return 用户详情列表
      * @return 用户详情列表
      */
      */
     @PreAuthorize("@ss.hasPermi('liveData:liveData:query')")
     @PreAuthorize("@ss.hasPermi('liveData:liveData:query')")
     @GetMapping("/getLiveUserDetailListBySql")
     @GetMapping("/getLiveUserDetailListBySql")
-    public R getLiveUserDetailListBySql(@RequestParam Long liveId) {
+    public R getLiveUserDetailListBySql(@RequestParam Long liveId,
+                                        @RequestParam(defaultValue = "1") Integer pageNum,
+                                        @RequestParam(defaultValue = "100") Integer pageSize) {
+        // 限制最大每页查询条数为1000
+        if (pageSize > 1000) {
+            pageSize = 1000;
+        }
+
+        PageHelper.startPage(pageNum, pageSize);
         return liveDataService.getLiveUserDetailListBySql(liveId,null,null);
         return liveDataService.getLiveUserDetailListBySql(liveId,null,null);
     }
     }
 
 

+ 2 - 1
fs-admin/src/main/java/com/fs/live/controller/OrderController.java

@@ -262,7 +262,8 @@ public class OrderController extends BaseController
             // 时间信息
             // 时间信息
             exportVO.setCreateTime(vo.getCreateTime());
             exportVO.setCreateTime(vo.getCreateTime());
             exportVO.setPayTime(vo.getPayTime());
             exportVO.setPayTime(vo.getPayTime());
-            
+            exportVO.setHfshh(vo.getHfshh());
+
             // 物流信息
             // 物流信息
             exportVO.setDeliverySn(vo.getDeliveryCode()); // 快递公司编号,合并订单暂无此字段
             exportVO.setDeliverySn(vo.getDeliveryCode()); // 快递公司编号,合并订单暂无此字段
             exportVO.setDeliveryName(vo.getDeliveryName()); // 快递公司,合并订单暂无此字段
             exportVO.setDeliveryName(vo.getDeliveryName()); // 快递公司,合并订单暂无此字段

+ 10 - 2
fs-company/src/main/java/com/fs/company/controller/live/LiveController.java

@@ -15,6 +15,7 @@ import com.fs.company.domain.CompanyUser;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.service.TokenService;
 import com.fs.framework.service.TokenService;
+import com.fs.his.domain.FsPayConfig;
 import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
 import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
 import com.fs.huifuPay.service.HuiFuService;
 import com.fs.huifuPay.service.HuiFuService;
@@ -28,7 +29,10 @@ import com.fs.live.service.ILiveCompanyCodeService;
 import com.fs.live.service.ILiveOrderService;
 import com.fs.live.service.ILiveOrderService;
 import com.fs.live.service.ILiveService;
 import com.fs.live.service.ILiveService;
 import com.fs.live.vo.LiveListVo;
 import com.fs.live.vo.LiveListVo;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
 import com.fs.system.oss.OSSFactory;
 import com.fs.system.oss.OSSFactory;
+import com.fs.wx.miniapp.config.WxMaProperties;
 import com.google.common.reflect.TypeToken;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
 import com.google.gson.Gson;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
@@ -343,6 +347,9 @@ public class LiveController extends BaseController
         }
         }
     }
     }
 
 
+    @Autowired
+    private WxMaProperties properties;
+
     @ApiOperation("生成微信小程序码")
     @ApiOperation("生成微信小程序码")
     @GetMapping("/getWxaCodeUnLimit")
     @GetMapping("/getWxaCodeUnLimit")
     @PreAuthorize("@ss.hasPermi('live:live:edit')")
     @PreAuthorize("@ss.hasPermi('live:live:edit')")
@@ -350,9 +357,10 @@ public class LiveController extends BaseController
         String url="https://api.weixin.qq.com/cgi-bin/stable_token";
         String url="https://api.weixin.qq.com/cgi-bin/stable_token";
         HashMap<String, String> map = new HashMap<>();
         HashMap<String, String> map = new HashMap<>();
         map.put("grant_type","client_credential");
         map.put("grant_type","client_credential");
+
         // 百域承品
         // 百域承品
-        map.put("appid","wx44beed5640bcb1ba");
-        map.put("secret","1bfcfa420f741801575a74d94752d014");
+        map.put("appid",properties.getConfigs().get(0).getAppid());
+        map.put("secret",properties.getConfigs().get(0).getSecret());
         String accessToken = HttpUtils.endApi(url, null, map);
         String accessToken = HttpUtils.endApi(url, null, map);
         // 创建Gson对象
         // 创建Gson对象
         Gson gson = new Gson();
         Gson gson = new Gson();

+ 12 - 3
fs-company/src/main/java/com/fs/company/controller/live/LiveDataController.java

@@ -55,17 +55,26 @@ public class LiveDataController extends BaseController
     /**
     /**
      * 查询直播间用户详情列表(SQL方式)
      * 查询直播间用户详情列表(SQL方式)
      * @param liveId 直播间ID
      * @param liveId 直播间ID
+     * @param pageNum 页码
+     * @param pageSize 每页大小
      * @return 用户详情列表
      * @return 用户详情列表
      */
      */
     @PreAuthorize("@ss.hasPermi('liveData:liveData:query')")
     @PreAuthorize("@ss.hasPermi('liveData:liveData:query')")
     @GetMapping("/getLiveUserDetailListBySql")
     @GetMapping("/getLiveUserDetailListBySql")
-    public R getLiveUserDetailListBySql(@RequestParam Long liveId, HttpServletRequest request) {
+    public R getLiveUserDetailListBySql(@RequestParam Long liveId, 
+                                        @RequestParam(defaultValue = "1") Integer pageNum,
+                                        @RequestParam(defaultValue = "100") Integer pageSize,
+                                        HttpServletRequest request) {
+        // 限制最大每页查询条数为1000
+        if (pageSize > 1000) {
+            pageSize = 1000;
+        }
+        PageHelper.startPage(pageNum, pageSize);
         CompanyUser user = tokenService.getLoginUser(request).getUser();
         CompanyUser user = tokenService.getLoginUser(request).getUser();
         if ("00".equals(user.getUserType())) {
         if ("00".equals(user.getUserType())) {
             return liveDataService.getLiveUserDetailListBySql(liveId,user.getCompanyId(),null);
             return liveDataService.getLiveUserDetailListBySql(liveId,user.getCompanyId(),null);
         }
         }
-        return liveDataService.getLiveUserDetailListBySql(liveId,user.getCompanyId(),user.getUserId());
-    }
+        return liveDataService.getLiveUserDetailListBySql(liveId,user.getCompanyId(),user.getUserId());    }
 
 
     /**
     /**
      * 查询直播间详情数据(查询数据服务器处理方式)
      * 查询直播间详情数据(查询数据服务器处理方式)

+ 1 - 0
fs-company/src/main/java/com/fs/company/controller/live/OrderController.java

@@ -270,6 +270,7 @@ public class OrderController extends BaseController
             // 公司和销售信息
             // 公司和销售信息
             exportVO.setCompanyName(vo.getCompanyName());
             exportVO.setCompanyName(vo.getCompanyName());
             exportVO.setCompanyUserNickName(vo.getCompanyUserNickName());
             exportVO.setCompanyUserNickName(vo.getCompanyUserNickName());
+            exportVO.setHfshh(vo.getHfshh());
 
 
             // 套餐信息
             // 套餐信息
             exportVO.setPackageName(null); // 套餐名称,合并订单暂无此字段
             exportVO.setPackageName(null); // 套餐名称,合并订单暂无此字段

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

@@ -171,7 +171,7 @@ public class Task {
                 }
                 }
                 // 清理小程序缓存 和 直播标签缓存
                 // 清理小程序缓存 和 直播标签缓存
                 String cacheKey = String.format(LiveKeysConstant.LIVE_DATA_CACHE, live.getLiveId());
                 String cacheKey = String.format(LiveKeysConstant.LIVE_DATA_CACHE, live.getLiveId());
-                redisCache.setCacheObject(cacheKey,live,1,TimeUnit.HOURS);
+                redisCache.deleteObject(cacheKey);
                 liveWatchUserService.clearLiveFlagCache(live.getLiveId());
                 liveWatchUserService.clearLiveFlagCache(live.getLiveId());
                 // 将开启的直播间信息写入Redis缓存,用于打标签定时任务
                 // 将开启的直播间信息写入Redis缓存,用于打标签定时任务
                 try {
                 try {

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

@@ -56,10 +56,10 @@ public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {
             userProperties.put(AttrConstant.LOCATION, parameterMap.get(AttrConstant.LOCATION).get(0));
             userProperties.put(AttrConstant.LOCATION, parameterMap.get(AttrConstant.LOCATION).get(0));
         }
         }
         if (parameterMap.containsKey(AttrConstant.QW_USER_ID)) {
         if (parameterMap.containsKey(AttrConstant.QW_USER_ID)) {
-            userProperties.put(AttrConstant.QW_USER_ID, parameterMap.get(AttrConstant.QW_USER_ID).get(0));
+            userProperties.put(AttrConstant.QW_USER_ID, Long.valueOf(parameterMap.get(AttrConstant.QW_USER_ID).get(0)));
         }
         }
         if (parameterMap.containsKey(AttrConstant.EXTERNAL_CONTACT_ID)) {
         if (parameterMap.containsKey(AttrConstant.EXTERNAL_CONTACT_ID)) {
-            userProperties.put(AttrConstant.EXTERNAL_CONTACT_ID, parameterMap.get(AttrConstant.EXTERNAL_CONTACT_ID).get(0));
+            userProperties.put(AttrConstant.EXTERNAL_CONTACT_ID, Long.valueOf(parameterMap.get(AttrConstant.EXTERNAL_CONTACT_ID).get(0)));
         }
         }
 
 
         // 验证token
         // 验证token

+ 1 - 8
fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java

@@ -554,6 +554,7 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
         if (!liveAfterSales.getStatus().equals(AfterStatusEnum.STATUS_3.getValue())) {
         if (!liveAfterSales.getStatus().equals(AfterStatusEnum.STATUS_3.getValue())) {
             throw new CustomException("非法操作");
             throw new CustomException("非法操作");
         }
         }
+        liveAfterSales.setRefundAmount(param.getRefundAmount());
         return liveOrderService.refundOrderMoney(liveAfterSales.getOrderId(),liveAfterSales);
         return liveOrderService.refundOrderMoney(liveAfterSales.getOrderId(),liveAfterSales);
     }
     }
 
 
@@ -915,14 +916,6 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
                 orderMap.setStatus(order.getStatus());
                 orderMap.setStatus(order.getStatus());
                 liveOrderService.updateLiveOrder(orderMap);
                 liveOrderService.updateLiveOrder(orderMap);
                 liveOrderItemService.updateFsStoreOrderCode(order.getOrderId(), orderSn);
                 liveOrderItemService.updateFsStoreOrderCode(order.getOrderId(), orderSn);
-                //生成新的订单
-                List<LiveOrderPayment> payments = liveOrderPaymentMapper.selectLiveOrderPaymentByPay(5, order.getOrderId());
-                for (LiveOrderPayment payment : payments) {
-                    LiveOrderPayment livePayment = new LiveOrderPayment();
-                    livePayment.setPaymentId(payment.getPaymentId());
-                    livePayment.setBusinessCode(orderSn);
-                    liveOrderPaymentMapper.updateLiveOrderPayment(livePayment);
-                }
                 liveOrderService.createOmsOrder(order.getOrderId());
                 liveOrderService.createOmsOrder(order.getOrderId());
             }
             }
         }
         }

+ 11 - 7
fs-service/src/main/java/com/fs/live/service/impl/LiveDataServiceImpl.java

@@ -26,6 +26,8 @@ import com.fs.his.mapper.FsUserMapper;
 import com.fs.hisStore.domain.FsStoreProductScrm;
 import com.fs.hisStore.domain.FsStoreProductScrm;
 import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
 import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
+
+import com.github.pagehelper.PageInfo;
 import io.swagger.models.auth.In;
 import io.swagger.models.auth.In;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
@@ -697,7 +699,13 @@ public class LiveDataServiceImpl implements ILiveDataService {
     @Override
     @Override
     public R getLiveUserDetailListBySql(Long liveId, Long companyId, Long companyUserId ) {
     public R getLiveUserDetailListBySql(Long liveId, Long companyId, Long companyUserId ) {
         List<LiveUserDetailVo> userDetailList = liveDataMapper.selectLiveUserDetailListBySql(liveId, companyId, companyUserId);
         List<LiveUserDetailVo> userDetailList = liveDataMapper.selectLiveUserDetailListBySql(liveId, companyId, companyUserId);
-        return R.ok().put("data", userDetailList);
+        // 使用 PageInfo 获取分页信息
+        PageInfo<LiveUserDetailVo> pageInfo = new PageInfo<>(userDetailList);
+        R data = R.ok().put("data", userDetailList);
+        if (pageInfo != null) {
+            data.put("total", pageInfo.getTotal());
+        }
+        return data;
     }
     }
 
 
     @Override
     @Override
@@ -1088,6 +1096,8 @@ public class LiveDataServiceImpl implements ILiveDataService {
             return new ArrayList<>();
             return new ArrayList<>();
         }
         }
 
 
+
+
         // 转换为导出VO列表
         // 转换为导出VO列表
         List<LiveUserDetailExportVO> exportList = new ArrayList<>();
         List<LiveUserDetailExportVO> exportList = new ArrayList<>();
         for (LiveUserDetailVo userDetail : userDetailList) {
         for (LiveUserDetailVo userDetail : userDetailList) {
@@ -1114,12 +1124,6 @@ public class LiveDataServiceImpl implements ILiveDataService {
             exportVO.setCompanyName(userDetail.getCompanyName());
             exportVO.setCompanyName(userDetail.getCompanyName());
             exportVO.setSalesName(userDetail.getSalesName());
             exportVO.setSalesName(userDetail.getSalesName());
 
 
-            // 是否完课(根据观看时长判断,假设30分钟以上为完课)
-            if (totalSeconds >= 1800) {
-                exportVO.setIsCompleted("是");
-            } else {
-                exportVO.setIsCompleted("否");
-            }
 
 
             exportList.add(exportVO);
             exportList.add(exportVO);
         }
         }

+ 2 - 7
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -710,12 +710,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
                         liveOrderPaymentMapper.updateLiveOrderPayment(paymentMap);
                         liveOrderPaymentMapper.updateLiveOrderPayment(paymentMap);
                         order = baseMapper.selectFsUserVipOrderByOrderCode(storePayment.getBusinessCode());
                         order = baseMapper.selectFsUserVipOrderByOrderCode(storePayment.getBusinessCode());
                         if(order==null || !order.getStatus().equals(OrderInfoEnum.STATUS_0.getValue())){
                         if(order==null || !order.getStatus().equals(OrderInfoEnum.STATUS_0.getValue())){
-                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                            return "";
-                        }
-                        if (order != null && !order.getIsPay().equals(0)) {
-                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                            return "";
+                            throw new CustomException("当前订单未找到或者订单状态不为待支付! paycode:"+payCode);
                         }
                         }
                     }
                     }
                 }
                 }
@@ -1559,7 +1554,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
                         log.info("退款:" + refund);
                         log.info("退款:" + refund);
                         if (refund != null && ("00000000".equals(refund.getResp_code()) || "00000100".equals(refund.getResp_code()))
                         if (refund != null && ("00000000".equals(refund.getResp_code()) || "00000100".equals(refund.getResp_code()))
                                 && ("S".equals(refund.getTrans_stat()) || "P".equals(refund.getTrans_stat()))) {
                                 && ("S".equals(refund.getTrans_stat()) || "P".equals(refund.getTrans_stat()))) {
-                            payment.setRefundMoney(payment.getPayMoney());
+                            payment.setRefundMoney(refundAmount);
                             payment.setStatus(-1);
                             payment.setStatus(-1);
                             payment.setRefundTime(new Date());
                             payment.setRefundTime(new Date());
                             liveOrderPaymentMapper.updateLiveOrderPayment(payment);
                             liveOrderPaymentMapper.updateLiveOrderPayment(payment);

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

@@ -320,7 +320,7 @@ public class LiveServiceImpl implements ILiveService
     @Override
     @Override
     public R subNotifyLive(LiveNotifyParam param) {
     public R subNotifyLive(LiveNotifyParam param) {
         LiveMiniprogramSubNotifyTask notifyTask = new LiveMiniprogramSubNotifyTask();
         LiveMiniprogramSubNotifyTask notifyTask = new LiveMiniprogramSubNotifyTask();
-        notifyTask.setPage("/pages_course/living.html?liveId=" + param.getLiveId());
+        notifyTask.setPage("pages_course/living?liveId=" + param.getLiveId());
         notifyTask.setTaskName("直播间预约提醒");
         notifyTask.setTaskName("直播间预约提醒");
         notifyTask.setTemplateId(param.getTemplateId());
         notifyTask.setTemplateId(param.getTemplateId());
         Long userId = param.getUserId();
         Long userId = param.getUserId();
@@ -341,7 +341,6 @@ public class LiveServiceImpl implements ILiveService
         }
         }
 
 
         notifyTask.setTouser(maOpenId);
         notifyTask.setTouser(maOpenId);
-        notifyTask.setPage(String.valueOf(1));
 
 
         notifyTask.setCreateTime(LocalDateTime.now());
         notifyTask.setCreateTime(LocalDateTime.now());
         // 状态等待执行
         // 状态等待执行

+ 1 - 1
fs-service/src/main/java/com/fs/live/vo/LiveUserDetailExportVO.java

@@ -49,7 +49,7 @@ public class LiveUserDetailExportVO {
     private String salesName;
     private String salesName;
 
 
     /** 是否完课 */
     /** 是否完课 */
-    @Excel(name = "是否完课")
+//    @Excel(name = "是否完课")
     private String isCompleted;
     private String isCompleted;
 
 
 }
 }

+ 16 - 11
fs-service/src/main/java/com/fs/live/vo/MergedOrderExportVO.java

@@ -48,13 +48,25 @@ public class MergedOrderExportVO implements Serializable
     private Integer totalNum;
     private Integer totalNum;
 
 
     /** 产品价格 */
     /** 产品价格 */
-    @Excel(name = "产品价格")
+//    @Excel(name = "产品价格")
     private BigDecimal price;
     private BigDecimal price;
 
 
     /** 成本价 */
     /** 成本价 */
     @Excel(name = "成本价")
     @Excel(name = "成本价")
     private BigDecimal cost;
     private BigDecimal cost;
 
 
+    /** 商品金额 */
+    @Excel(name = "商品金额")
+    private BigDecimal totalPrice;
+
+    /** 应付金额 */
+    @Excel(name = "应付金额")
+    private BigDecimal payPrice;
+
+    /** 实付金额 */
+    @Excel(name = "实付金额")
+    private BigDecimal payMoney;
+
     /** 结算价 */
     /** 结算价 */
     @Excel(name = "结算价")
     @Excel(name = "结算价")
     private BigDecimal FPrice;
     private BigDecimal FPrice;
@@ -137,18 +149,11 @@ public class MergedOrderExportVO implements Serializable
     /** 银行交易流水号 */
     /** 银行交易流水号 */
     @Excel(name = "银行交易流水号")
     @Excel(name = "银行交易流水号")
     private String bankTransactionId;
     private String bankTransactionId;
+    /** 汇付商户订单号 */
+    @Excel(name = "汇付商户订单号")
+    private String hfshh;
 
 
-    /** 商品金额 */
-    @Excel(name = "商品金额")
-    private BigDecimal totalPrice;
 
 
-    /** 应付金额 */
-    @Excel(name = "应付金额")
-    private BigDecimal payPrice;
-
-    /** 实付金额 */
-    @Excel(name = "实付金额")
-    private BigDecimal payMoney;
 
 
 
 
 }
 }

+ 2 - 0
fs-service/src/main/java/com/fs/live/vo/MergedOrderVO.java

@@ -109,6 +109,8 @@ public class MergedOrderVO implements Serializable
 
 
     /** 订单类型:1-销售订单,2-商城订单,3-直播订单 */
     /** 订单类型:1-销售订单,2-商城订单,3-直播订单 */
     private Integer orderType;
     private Integer orderType;
+//    汇付商户订单号
+    private String hfshh;
 
 
     /** 订单类型名称 */
     /** 订单类型名称 */
     private String orderTypeName;
     private String orderTypeName;

+ 18 - 0
fs-service/src/main/java/com/fs/newAdv/controller/AdvMiniConfigController.java

@@ -0,0 +1,18 @@
+package com.fs.newAdv.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 广告微信小程序配置 前端控制器
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@RestController
+@RequestMapping("/advMiniConfig")
+public class AdvMiniConfigController {
+
+}

+ 58 - 0
fs-service/src/main/java/com/fs/newAdv/domain/AdvMiniConfig.java

@@ -0,0 +1,58 @@
+package com.fs.newAdv.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 广告微信小程序配置
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@Getter
+@Setter
+@TableName("adv_mini_config")
+@ApiModel(value = "AdvMiniConfig对象", description = "广告微信小程序配置")
+public class AdvMiniConfig extends Model<AdvMiniConfig> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId("id")
+    private Integer id;
+
+    @TableField("app_id")
+    private String appId;
+
+    @TableField("app_secret")
+    private String appSecret;
+
+    @TableField("access_token")
+    private String accessToken;
+
+    @ApiModelProperty("小程序状态1启用 0停用")
+    @TableField("status")
+    private Integer status;
+
+    @ApiModelProperty("过期时间")
+    @TableField("expires_in")
+    private LocalDateTime expiresIn;
+
+    @TableField("create_time")
+    private LocalDateTime createTime;
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+}

+ 2 - 2
fs-service/src/main/java/com/fs/newAdv/domain/PromotionAccount.java

@@ -71,9 +71,9 @@ public class PromotionAccount implements Serializable {
     private Integer apiSwitch;
     private Integer apiSwitch;
 
 
     /**
     /**
-     * 推广账户密码(加密存储)
+     * 推拓展字段
      */
      */
-    private String accountPassword;
+    private String extendedField;
     /**
     /**
      * 1线上 2线下
      * 1线上 2线下
      */
      */

+ 2 - 2
fs-service/src/main/java/com/fs/newAdv/integration/client/advertiser/BaiduApiClient.java

@@ -123,7 +123,7 @@ public class BaiduApiClient extends AbstractApiClient implements IAccessTokenCli
         Map<String, Object> map = new HashMap<>();
         Map<String, Object> map = new HashMap<>();
         Map<String, Object> header = new HashMap<>();
         Map<String, Object> header = new HashMap<>();
         header.put("accessToken", account.getAccessToken());
         header.put("accessToken", account.getAccessToken());
-        header.put("userName", account.getAccountShortName());
+        header.put("userName", account.getExtendedField());
         map.put("header", header);
         map.put("header", header);
         Map<String, Object> body = new HashMap<>();
         Map<String, Object> body = new HashMap<>();
         // 基础信息
         // 基础信息
@@ -197,7 +197,7 @@ public class BaiduApiClient extends AbstractApiClient implements IAccessTokenCli
             requestMap.put("secretKey", codeVo.getAppSecret());
             requestMap.put("secretKey", codeVo.getAppSecret());
             requestMap.put("authCode", codeVo.getAuthCode());
             requestMap.put("authCode", codeVo.getAuthCode());
             requestMap.put("grantType", "access_token");
             requestMap.put("grantType", "access_token");
-            requestMap.put("userId", codeVo.getUserId());
+            requestMap.put("userId", codeVo.getAdAccountId());
             // 发送HTTP请求
             // 发送HTTP请求
             return HttpRequest.post(ACCESS_TOKEN_URL)
             return HttpRequest.post(ACCESS_TOKEN_URL)
                     .header("Content-Type", "application/json")
                     .header("Content-Type", "application/json")

+ 44 - 6
fs-service/src/main/java/com/fs/newAdv/integration/client/advertiser/TencentApiClient.java

@@ -1,6 +1,8 @@
 package com.fs.newAdv.integration.client.advertiser;
 package com.fs.newAdv.integration.client.advertiser;
 
 
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
 import com.fs.common.constant.SystemConstant;
 import com.fs.common.constant.SystemConstant;
@@ -15,11 +17,9 @@ import com.fs.newAdv.vo.AccessTokenVo;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 /**
 /**
  * 腾讯广点通API客户端
  * 腾讯广点通API客户端
@@ -34,6 +34,7 @@ public class TencentApiClient extends AbstractApiClient implements IAccessTokenC
 
 
     private static final String CONVERSION_API_URL = "https://api.e.qq.com/user_actions/add";
     private static final String CONVERSION_API_URL = "https://api.e.qq.com/user_actions/add";
     private static final String TOKEN_API_URL = "https://api.e.qq.com/oauth/token";
     private static final String TOKEN_API_URL = "https://api.e.qq.com/oauth/token";
+    private static final String REPORTS_API_URL = "https://api.e.qq.com/v3.0/daily_reports/get?access_token=%s&timestamp=%s&nonce=%s";
 
 
     /**
     /**
      * 回传转化数据
      * 回传转化数据
@@ -84,7 +85,44 @@ public class TencentApiClient extends AbstractApiClient implements IAccessTokenC
 
 
     @Override
     @Override
     public SiteStatistics getDataReport(PromotionAccount account, String ideaId, String startDate, String endDate) {
     public SiteStatistics getDataReport(PromotionAccount account, String ideaId, String startDate, String endDate) {
-        return null;
+        // 构建请求参数
+        Map<String, Object> body = new HashMap<>();
+        // 基础信息
+        //报告名称: 信息流整体账户报告
+        //reportType: 2172649
+        //支持的时间单位: HOUR DAY WEEK MONTH SUMMARY
+        //支持的最大时间区间: 824天
+        body.put("account_id", account.getAdAccountId());
+        body.put("level", "REPORT_LEVEL_ADGROUP");
+        Map<String, Object> date_range = new HashMap<>();
+        date_range.put("start_date", startDate);
+        date_range.put("end_date", endDate);
+        body.put("date_range", date_range);
+
+        Map<String, Object> filtering = new HashMap<>();
+        filtering.put("field", "dynamic_creative_id");
+        filtering.put("operator", "IN");
+        filtering.put("values", Arrays.asList(ideaId));
+        body.put("filtering", date_range);
+
+        log.info("腾讯数据请求参数:{}", JSONUtil.toJsonStr(body));
+        HttpResponse execute = HttpRequest.get(String.format(REPORTS_API_URL, account.getAccessToken(), new Date().getTime(), SnowflakeUtil.randomUUID()))
+                .form(body)
+                .timeout(SystemConstant.API_TIMEOUT)
+                .execute();
+        JSONObject jsonObject = JSONUtil.parseObj(execute.body());
+        log.info("腾讯数据返回结果:{}", execute.body());
+        JSONObject data = jsonObject.getJSONObject("body").getJSONObject("data");
+        JSONArray rows = data.getJSONArray("list");
+        JSONObject jsonObject1 = rows.getJSONObject(0);
+        SiteStatistics siteStatistics = new SiteStatistics();
+        siteStatistics.setImpressionCount(Integer.valueOf(jsonObject1.getStr("view_count")));
+        siteStatistics.setClickCount(Integer.valueOf(jsonObject1.getStr("valid_click_count")));
+        siteStatistics.setActualCost(new BigDecimal(jsonObject1.getStr("cost")));
+        siteStatistics.setAccountCost(new BigDecimal(jsonObject1.getStr("cost")));
+        siteStatistics.setClickRate(new BigDecimal(jsonObject1.getStr("ctr")));
+        siteStatistics.setAvgClickPrice(new BigDecimal(jsonObject1.getStr("cpc")));
+        return siteStatistics;
     }
     }
 
 
 
 
@@ -110,7 +148,7 @@ public class TencentApiClient extends AbstractApiClient implements IAccessTokenC
                     .form("client_secret", codeVo.getAppSecret())
                     .form("client_secret", codeVo.getAppSecret())
                     .form("grant_type", "authorization_code")
                     .form("grant_type", "authorization_code")
                     .form("authorization_code", codeVo.getAuthCode())
                     .form("authorization_code", codeVo.getAuthCode())
-                    .form("redirect_uri", "authorization_code")
+                    // .form("redirect_uri", "authorization_code")
                     .timeout(SystemConstant.API_TIMEOUT)
                     .timeout(SystemConstant.API_TIMEOUT)
                     .execute();
                     .execute();
         });
         });

+ 18 - 0
fs-service/src/main/java/com/fs/newAdv/mapper/AdvMiniConfigMapper.java

@@ -0,0 +1,18 @@
+package com.fs.newAdv.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.newAdv.domain.AdvMiniConfig;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 广告微信小程序配置 Mapper 接口
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@Mapper
+public interface AdvMiniConfigMapper extends BaseMapper<AdvMiniConfig> {
+
+}

+ 16 - 0
fs-service/src/main/java/com/fs/newAdv/service/IAdvMiniConfigService.java

@@ -0,0 +1,16 @@
+package com.fs.newAdv.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.newAdv.domain.AdvMiniConfig;
+
+/**
+ * <p>
+ * 广告微信小程序配置 服务类
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+public interface IAdvMiniConfigService extends IService<AdvMiniConfig> {
+
+}

+ 1 - 1
fs-service/src/main/java/com/fs/newAdv/service/ILeadService.java

@@ -41,7 +41,7 @@ public interface ILeadService extends IService<Lead> {
      * @param mpOpenId
      * @param mpOpenId
      * @param phone
      * @param phone
      */
      */
-    void weChatAuthorizationLead(String traceId, String unionId, String mpOpenId, String phone);
+    void weChatAuthorizationLead(String traceId, String unionId, String maOpenId, String phone);
 
 
     /**
     /**
      * 小程序授权落地页访问线索处理
      * 小程序授权落地页访问线索处理

+ 20 - 0
fs-service/src/main/java/com/fs/newAdv/service/impl/AdvMiniConfigServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fs.newAdv.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.newAdv.domain.AdvMiniConfig;
+import com.fs.newAdv.mapper.AdvMiniConfigMapper;
+import com.fs.newAdv.service.IAdvMiniConfigService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 广告微信小程序配置 服务实现类
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-19
+ */
+@Service
+public class AdvMiniConfigServiceImpl extends ServiceImpl<AdvMiniConfigMapper, AdvMiniConfig> implements IAdvMiniConfigService {
+
+}

+ 6 - 4
fs-service/src/main/java/com/fs/newAdv/service/impl/LeadServiceImpl.java

@@ -118,20 +118,22 @@ public class LeadServiceImpl extends ServiceImpl<LeadMapper, Lead> implements IL
 
 
     @Override
     @Override
     @Async
     @Async
-    public void weChatAuthorizationLead(String traceId, String unionId, String mpOpenId, String phone) {
+    public void weChatAuthorizationLead(String traceId, String unionId, String maOpenId, String phone) {
        try{
        try{
+           log.info("用户微信授权线索信息:{}", traceId);
            Lead byTraceId = this.getByTraceId(traceId);
            Lead byTraceId = this.getByTraceId(traceId);
            if (byTraceId == null) {
            if (byTraceId == null) {
                return;
                return;
            }
            }
            this.update(new LambdaUpdateWrapper<Lead>()
            this.update(new LambdaUpdateWrapper<Lead>()
                    .eq(Lead::getTraceId, traceId)
                    .eq(Lead::getTraceId, traceId)
-                   .set(Lead::getUnionid, unionId)
-                   .set(Lead::getPhone, phone)
-                   .set(Lead::getOpenid, mpOpenId)
+                   .set(ObjectUtil.isNotEmpty(unionId),Lead::getUnionid, unionId)
+                   .set(ObjectUtil.isNotEmpty(phone),Lead::getPhone, phone)
+                   .set(ObjectUtil.isNotEmpty(maOpenId),Lead::getOpenid, maOpenId)
                    .set(Lead::getMiniAuth, 1));
                    .set(Lead::getMiniAuth, 1));
            if (ObjectUtil.isNotEmpty(byTraceId.getLandingPageTs()) && byTraceId.getLandingPageTs().toLocalDate().isEqual(LocalDate.now())) {
            if (ObjectUtil.isNotEmpty(byTraceId.getLandingPageTs()) && byTraceId.getLandingPageTs().toLocalDate().isEqual(LocalDate.now())) {
                // 微信授权且当日创建事件
                // 微信授权且当日创建事件
+               log.info("用户微信授权线索事件回传:{}", traceId);
                conversionEventPublisher.publishConversionEvent(traceId, SystemEventTypeEnum.AUTH_TODAY_CREATE);
                conversionEventPublisher.publishConversionEvent(traceId, SystemEventTypeEnum.AUTH_TODAY_CREATE);
            }
            }
        }catch (Exception e){
        }catch (Exception e){

+ 1 - 1
fs-service/src/main/java/com/fs/newAdv/vo/AccessTokenByAuthCodeVo.java

@@ -11,7 +11,7 @@ public class AccessTokenByAuthCodeVo implements Serializable {
     private String appId;
     private String appId;
     private String appSecret;
     private String appSecret;
     private String authCode;
     private String authCode;
-    private String userId;
+    private String adAccountId;
 
 
 
 
 
 

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

@@ -61,7 +61,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       o.delivery_pay_status,
       o.delivery_pay_status,
       o.total_price,
       o.total_price,
       csc.NAME AS mini_program_name,
       csc.NAME AS mini_program_name,
-      sp_latest.bank_transaction_id
+      sp_latest.bank_transaction_id,
+        CONCAT('store-',sp_latest.pay_code) as hfshh
       FROM
       FROM
       fs_store_order_scrm o
       fs_store_order_scrm o
       left join ( SELECT fsois.*, ROW_NUMBER() OVER ( PARTITION BY fsois.order_id ORDER BY fsois.item_id ) AS rn FROM fs_store_order_item_scrm fsois ) item_latest ON item_latest.order_id = o.id and item_latest.rn = 1
       left join ( SELECT fsois.*, ROW_NUMBER() OVER ( PARTITION BY fsois.order_id ORDER BY fsois.item_id ) AS rn FROM fs_store_order_item_scrm fsois ) item_latest ON item_latest.order_id = o.id and item_latest.rn = 1
@@ -202,8 +203,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       o.delivery_pay_status,
       o.delivery_pay_status,
       o.total_price,
       o.total_price,
       csc.NAME AS mini_program_name,
       csc.NAME AS mini_program_name,
-      sp_latest.bank_transaction_id
-      FROM
+      sp_latest.bank_transaction_id,
+        CONCAT('store-',sp_latest.pay_code) as hfshh
+        FROM
       fs_store_order_scrm o
       fs_store_order_scrm o
         left join ( SELECT fsois.*, ROW_NUMBER() OVER ( PARTITION BY fsois.order_id ORDER BY fsois.item_id ) AS rn FROM fs_store_order_item_scrm fsois ) item_latest ON item_latest.order_id = o.id and item_latest.rn = 1
         left join ( SELECT fsois.*, ROW_NUMBER() OVER ( PARTITION BY fsois.order_id ORDER BY fsois.item_id ) AS rn FROM fs_store_order_item_scrm fsois ) item_latest ON item_latest.order_id = o.id and item_latest.rn = 1
       LEFT JOIN fs_user u ON o.user_id = u.user_id
       LEFT JOIN fs_user u ON o.user_id = u.user_id
@@ -343,7 +345,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       o.delivery_pay_status,
       o.delivery_pay_status,
       o.total_price,
       o.total_price,
       csc.NAME AS mini_program_name,
       csc.NAME AS mini_program_name,
-      sp_latest.bank_transaction_id
+      sp_latest.bank_transaction_id,
+        CONCAT('live-',sp_latest.pay_code) as hfshh
       FROM
       FROM
       live_order o
       live_order o
       left join live_order_item loi on loi.order_id = o.order_id
       left join live_order_item loi on loi.order_id = o.order_id

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

@@ -101,14 +101,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <!-- 查询用户的完课积分领取记录列表 -->
     <!-- 查询用户的完课积分领取记录列表 -->
     <select id="selectRecordsByUser" resultMap="LiveCompletionPointsRecordResult">
     <select id="selectRecordsByUser" resultMap="LiveCompletionPointsRecordResult">
         SELECT * FROM live_completion_points_record
         SELECT * FROM live_completion_points_record
-        WHERE user_id = #{userId}
+        WHERE user_id = #{userId} and receive_status = 1
         ORDER BY current_completion_date DESC
         ORDER BY current_completion_date DESC
     </select>
     </select>
 
 
     <!-- 根据ID查询 -->
     <!-- 根据ID查询 -->
     <select id="selectById" resultMap="LiveCompletionPointsRecordResult">
     <select id="selectById" resultMap="LiveCompletionPointsRecordResult">
         SELECT * FROM live_completion_points_record
         SELECT * FROM live_completion_points_record
-        WHERE id = #{id}
+        WHERE id = #{id} for update
     </select>
     </select>
 
 
 </mapper>
 </mapper>

+ 7 - 7
fs-service/src/main/resources/mapper/live/LiveDataMapper.xml

@@ -414,7 +414,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             COALESCE(video_duration.total_duration, 0) AS videoDuration,
             COALESCE(video_duration.total_duration, 0) AS videoDuration,
             COUNT(DISTINCT lwu.user_id) AS totalViewers,
             COUNT(DISTINCT lwu.user_id) AS totalViewers,
             COUNT(DISTINCT CASE
             COUNT(DISTINCT CASE
-                WHEN COALESCE(user_duration.total_duration, 0) >= 1800
+                WHEN COALESCE(user_duration.total_duration, 0) >= 1200
                 THEN lwu.user_id
                 THEN lwu.user_id
             END) AS totalCompletedCourses,
             END) AS totalCompletedCourses,
             CASE
             CASE
@@ -425,30 +425,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     END) * 100.0 / COUNT(DISTINCT lwu.user_id), 2)
                     END) * 100.0 / COUNT(DISTINCT lwu.user_id), 2)
                 ELSE 0
                 ELSE 0
             END AS totalCompletionRate,
             END AS totalCompletionRate,
-            COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END) AS liveViewers,
+            COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 and lwu.online_seconds > 0 THEN lwu.user_id END) AS liveViewers,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) AS liveOver20Minutes,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) AS liveOver20Minutes,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) AS liveOver30Minutes,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) AS liveOver30Minutes,
             CASE
             CASE
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END) > 0 THEN
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END) > 0 THEN
-                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END), 2)
+                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 and lwu.online_seconds > 0  THEN lwu.user_id END), 2)
                 ELSE 0
                 ELSE 0
             END AS liveCompletionRate20,
             END AS liveCompletionRate20,
             CASE
             CASE
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END) > 0 THEN
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END) > 0 THEN
-                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END), 2)
+                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 and lwu.online_seconds > 0  THEN lwu.user_id END), 2)
                 ELSE 0
                 ELSE 0
             END AS liveCompletionRate30,
             END AS liveCompletionRate30,
-            COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END) AS playbackViewers,
+            COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 and lwu.online_seconds > 0 THEN lwu.user_id END) AS playbackViewers,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) AS playbackOver20Minutes,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) AS playbackOver20Minutes,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) AS playbackOver30Minutes,
             COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) AS playbackOver30Minutes,
             CASE
             CASE
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END) > 0 THEN
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END) > 0 THEN
-                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END), 2)
+                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1200 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 and lwu.online_seconds > 0  THEN lwu.user_id END), 2)
                 ELSE 0
                 ELSE 0
             END AS playbackCompletionRate20,
             END AS playbackCompletionRate20,
             CASE
             CASE
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END) > 0 THEN
                 WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END) > 0 THEN
-                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END), 2)
+                    ROUND(COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 and lwu.online_seconds > 0  THEN lwu.user_id END), 2)
                 ELSE 0
                 ELSE 0
             END AS playbackCompletionRate30,
             END AS playbackCompletionRate30,
             COALESCE(ld.peak_concurrent_viewers, 0) AS livePeak,
             COALESCE(ld.peak_concurrent_viewers, 0) AS livePeak,

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/store/WxUserScrmController.java

@@ -371,7 +371,7 @@ public class WxUserScrmController extends AppBaseController {
             userService.handleFsUserWx(user,loginMaWxParam,session);
             userService.handleFsUserWx(user,loginMaWxParam,session);
             String token = jwtUtils.generateToken(user.getUserId());
             String token = jwtUtils.generateToken(user.getUserId());
             // 广告线索
             // 广告线索
-            leadService.weChatAuthorizationLead(param.getTraceId(), user.getUnionId(),user.getMpOpenId(),user.getPhone());
+            leadService.weChatAuthorizationLead(param.getTraceId(), user.getUnionId(),user.getMaOpenId(),user.getPhone());
             return R.ok("登录成功").put("token",token).put("user", user);
             return R.ok("登录成功").put("token",token).put("user", user);
         } catch (WxErrorException e) {
         } catch (WxErrorException e) {
             //this.logger.error(e.getMessage(), e);
             //this.logger.error(e.getMessage(), e);