Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

yfh 1 месяц назад
Родитель
Сommit
5fb3c5e362
23 измененных файлов с 477 добавлено и 52 удалено
  1. 6 6
      fs-admin/src/main/java/com/fs/his/controller/FsAdvController.java
  2. 9 9
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreScrmController.java
  3. 3 1
      fs-company/src/main/java/com/fs/company/controller/live/LiveDataController.java
  4. 31 4
      fs-company/src/main/java/com/fs/framework/service/CompanyLoginService.java
  5. 11 0
      fs-framework/src/main/java/com/fs/framework/web/service/SysLoginService.java
  6. 1 1
      fs-live-app/src/main/java/com/fs/live/controller/LiveController.java
  7. 18 2
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  8. 5 4
      fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  9. 2 2
      fs-service/src/main/java/com/fs/course/vo/FsCourseRedPacketLogListPVO.java
  10. 1 1
      fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogListVO.java
  11. 1 1
      fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java
  12. 98 0
      fs-service/src/main/java/com/fs/hisStore/mapper/MergedOrderMapper.java
  13. 24 0
      fs-service/src/main/java/com/fs/hisStore/service/IMergedOrderService.java
  14. 4 4
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  15. 90 0
      fs-service/src/main/java/com/fs/hisStore/service/impl/MergedOrderServiceImpl.java
  16. 78 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsMergedOrderListQueryVO.java
  17. 7 2
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  18. 1 1
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  19. 2 2
      fs-service/src/main/java/com/fs/live/service/impl/LiveWatchConfigServiceImpl.java
  20. 2 2
      fs-service/src/main/resources/application-config-druid-cfryt.yml
  21. 3 3
      fs-service/src/main/resources/application-druid-bjzm.yml
  22. 23 7
      fs-service/src/main/resources/mapper/live/LiveDataMapper.xml
  23. 57 0
      fs-user-app/src/main/java/com/fs/app/controller/live/OrderController.java

+ 6 - 6
fs-admin/src/main/java/com/fs/his/controller/FsAdvController.java

@@ -40,7 +40,7 @@ public class FsAdvController extends BaseController
     /**
      * 查询广告列表
      */
-    @PreAuthorize("@ss.hasPermi('his:adv:list')")
+    @PreAuthorize("@ss.hasPermi('store:adv:list')")
     @GetMapping("/list")
     public TableDataInfo list(FsAdv fsAdv)
     {
@@ -52,7 +52,7 @@ public class FsAdvController extends BaseController
     /**
      * 导出广告列表
      */
-    @PreAuthorize("@ss.hasPermi('his:adv:export')")
+    @PreAuthorize("@ss.hasPermi('store:adv:export')")
     @Log(title = "广告", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
     public AjaxResult export(FsAdv fsAdv)
@@ -65,7 +65,7 @@ public class FsAdvController extends BaseController
     /**
      * 获取广告详细信息
      */
-    @PreAuthorize("@ss.hasPermi('his:adv:query')")
+    @PreAuthorize("@ss.hasPermi('store:adv:query')")
     @GetMapping(value = "/{advId}")
     public AjaxResult getInfo(@PathVariable("advId") String advId)
     {
@@ -76,7 +76,7 @@ public class FsAdvController extends BaseController
     /**
      * 新增广告
      */
-    @PreAuthorize("@ss.hasPermi('his:adv:add')")
+    @PreAuthorize("@ss.hasPermi('store:adv:add')")
     @Log(title = "广告", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@RequestBody FsAdv fsAdv)
@@ -91,7 +91,7 @@ public class FsAdvController extends BaseController
     /**
      * 修改广告
      */
-    @PreAuthorize("@ss.hasPermi('his:adv:edit')")
+    @PreAuthorize("@ss.hasPermi('store:adv:edit')")
     @Log(title = "广告", businessType = BusinessType.UPDATE)
     @PutMapping
     public AjaxResult edit(@RequestBody FsAdv fsAdv)
@@ -105,7 +105,7 @@ public class FsAdvController extends BaseController
     /**
      * 删除广告
      */
-    @PreAuthorize("@ss.hasPermi('his:adv:remove')")
+    @PreAuthorize("@ss.hasPermi('store:adv:remove')")
     @Log(title = "广告", businessType = BusinessType.DELETE)
 	@DeleteMapping("/{advIds}")
     public AjaxResult remove(@PathVariable String[] advIds)

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

@@ -37,7 +37,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 查询店铺管理列表
      */
-    @PreAuthorize("@ss.hasPermi('his:store:list')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:list')")
     @GetMapping("/list")
     public TableDataInfo list(FsStoreScrm fsStore)
     {
@@ -52,7 +52,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 导出店铺管理列表
      */
-    @PreAuthorize("@ss.hasPermi('his:store:export')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:export')")
     @Log(title = "店铺管理", businessType = BusinessType.EXPORT,logParam = {"店铺","导出店铺信息"},isStoreLog = true)
     @GetMapping("/export")
     public AjaxResult export(FsStoreScrm fsStore)
@@ -69,7 +69,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 获取店铺管理详细信息
      */
-    @PreAuthorize("@ss.hasPermi('his:store:query')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:query')")
     @GetMapping(value = "/{storeId}")
     public AjaxResult getInfo(@PathVariable("storeId") Long storeId)
     {
@@ -81,7 +81,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 新增店铺管理
      */
-    @PreAuthorize("@ss.hasPermi('his:store:add')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:add')")
     @Log(title = "店铺管理", businessType = BusinessType.INSERT,logParam = {"店铺","新增店铺信息"},isStoreLog = true)
     @PostMapping
     public AjaxResult add(@RequestBody FsStoreScrm fsStore)
@@ -93,7 +93,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 修改店铺管理
      */
-    @PreAuthorize("@ss.hasPermi('his:store:edit')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:edit')")
     @Log(title = "店铺管理", businessType = BusinessType.UPDATE,logParam = {"店铺","修改店铺信息"},isStoreLog = true)
     @PutMapping
     public AjaxResult edit(@RequestBody FsStoreScrm fsStore)
@@ -108,7 +108,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 删除店铺管理
      */
-    @PreAuthorize("@ss.hasPermi('his:store:remove')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:remove')")
     @Log(title = "店铺管理", businessType = BusinessType.DELETE,logParam = {"店铺","删除店铺信息"},isStoreLog = true)
 	@DeleteMapping("/{storeIds}")
     public AjaxResult remove(@PathVariable Long[] storeIds)
@@ -119,7 +119,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 店铺审核
      */
-    @PreAuthorize("@ss.hasPermi('his:store:audit')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:audit')")
     @Log(title = "店铺审核", businessType = BusinessType.AUDIT,logParam = {"店铺","店铺审核"},isStoreLog = true
     ,logParamExpression = "#p0.getIsAudit()==1?new String[]{'店铺','店铺审核通过'}: new String[]{'店铺','店铺审核退回'}")
     @PutMapping("/audit")
@@ -131,7 +131,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 重置店铺密码
      * */
-    @PreAuthorize("@ss.hasPermi('his:store:refresh')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:refresh')")
     @Log(title = "店铺管理", businessType = BusinessType.UPDATE,logParam = {"店铺","重置店铺密码"},isStoreLog = true)
     @PutMapping("/refresh/{storeId}")
     public AjaxResult refresh(@PathVariable Long storeId)
@@ -143,7 +143,7 @@ public class FsStoreScrmController extends BaseController
     /**
      * 店铺审核日志
      * */
-    @PreAuthorize("@ss.hasPermi('his:store:auditLog')")
+    @PreAuthorize("@ss.hasPermi('store:his:store:auditLog')")
     @GetMapping("/auditLog/{storeId}")
     public R auditLog(@PathVariable Long storeId){
         return R.ok().put("auditLog",storeAuditLogUtil.selectOperLogByMainId(storeId));

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

@@ -60,7 +60,9 @@ public class LiveDataController extends BaseController
     @GetMapping("/getLiveUserDetailListBySql")
     public R getLiveUserDetailListBySql(@RequestParam Long liveId, HttpServletRequest request) {
         CompanyUser user = tokenService.getLoginUser(request).getUser();
-
+        if ("00".equals(user.getUserType())) {
+            return liveDataService.getLiveUserDetailListBySql(liveId,user.getCompanyId(),null);
+        }
         return liveDataService.getLiveUserDetailListBySql(liveId,user.getCompanyId(),user.getUserId());
     }
 

+ 31 - 4
fs-company/src/main/java/com/fs/framework/service/CompanyLoginService.java

@@ -58,13 +58,13 @@ public class CompanyLoginService
     @Autowired
     private ICompanyUserService companyUserService;
 
-    @Value("${wechat.company.appid}")
+    @Value("${wechat.company.appid:#{null}}")
     private String appId;
-    @Value("${wechat.company.secret}")
+    @Value("${wechat.company.secret:#{null}}")
     private String secret;
-    @Value("${wechat.company.redirectUri}")
+    @Value("${wechat.company.redirectUri:#{null}}")
     private String redirectUri;
-    @Value("${wechat.isNeedScan}")
+    @Value("${wechat.isNeedScan:false}")
     private Boolean isNeedScan;
 
     @Autowired
@@ -119,8 +119,35 @@ public class CompanyLoginService
             }
         }
         LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        //查询当前登录用户信息
+        CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
         AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getUser().getCompanyId(),username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
         redisCache.setCacheObject("companyId:"+loginUser.getUser().getUserId(),loginUser.getUser().getCompanyId(),604800, TimeUnit.SECONDS);
+        String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest()).split(",")[0].trim();
+        log.info("销售用户{}正常登录获取到的ip地址{}", loginUser.getUser().getUserId(), ipAddr);
+
+        companyUser.setUserId(loginUser.getUser().getUserId());
+        String loginIp = companyUser.getLoginIp();
+        List<String> ipList = new ArrayList<>();
+        if (StringUtils.isNotEmpty(loginIp)) {
+            String[] ips = loginIp.split(",");
+            for (String ip : ips) {
+                ip = ip.trim();                  // 去掉前后空格
+                if (!ip.isEmpty()) {
+                    ipList.add(ip);              // 先加入已有 IP
+                }
+            }
+        }
+
+        ipList.add(ipAddr);
+        List<String> distinctList = ipList.stream()
+                .map(String::trim)       // 再次确保去掉空格
+                .distinct()
+                .collect(Collectors.toList());
+        companyUser.setLoginIp(String.join(",", distinctList));
+
+        companyUser.setLoginDate(new Date());
+        companyUserService.updateCompanyUser(companyUser);
         // 生成token
         return tokenService.createToken(loginUser);
     }

+ 11 - 0
fs-framework/src/main/java/com/fs/framework/web/service/SysLoginService.java

@@ -143,6 +143,17 @@ public class SysLoginService
      */
     public void recordLoginInfo(SysUser user)
     {
+        String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
+        String loginIp = user.getLoginIp();
+        if (com.fs.common.utils.StringUtils.isEmpty(loginIp)) {
+            user.setLoginIp(ipAddr);
+        } else {
+            List<String> ipList = new ArrayList<>(Arrays.asList(loginIp.split(",")));
+            if (!ipList.contains(ipAddr)) {
+                ipList.add(ipAddr);
+                user.setLoginIp(String.join(",", ipList));
+            }
+        }
         user.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
         user.setLoginDate(DateUtils.getNowDate());
         userService.updateUserProfile(user);

+ 1 - 1
fs-live-app/src/main/java/com/fs/live/controller/LiveController.java

@@ -77,7 +77,7 @@ public class LiveController {
 		live.setLiveId(Long.valueOf(params.get("stream_id")));
 		live.setStatus(3);
 		live.setFinishTime(LocalDateTime.now());
-		liveService.updateLiveEntity(live);
+//		liveService.updateLiveEntity(live);
 		return R.ok();
 //		{app=200149.push.tlivecloud.com, appid=1319721001, appname=live, channel_id=673,
 //				errcode=1, errmsg=The push client actively stopped the push, event_time=1755571239,

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

@@ -157,7 +157,7 @@ public class WebSocketServer {
                 sendMsgVo.setNickName(fsUser.getNickname());
                 sendMsgVo.setAvatar(fsUser.getAvatar());
                 // 广播连接消息
-                broadcastMessage(liveId, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
+                broadcastWebMessage(liveId, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
             }
 
             LiveUserFirstEntry liveUserFirstEntry = liveUserFirstEntryService.selectEntityByLiveIdUserId(liveId, userId);
@@ -242,7 +242,7 @@ public class WebSocketServer {
                 sendMsgVo.setData(JSONObject.toJSONString(liveWatchUserVO));
                 sendMsgVo.setNickName(fsUser.getNickname());
                 sendMsgVo.setAvatar(fsUser.getAvatar());
-                broadcastMessage(liveId, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
+                broadcastWebMessage(liveId, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
             }
 
         } else {
@@ -588,6 +588,22 @@ public class WebSocketServer {
         session.getAsyncRemote().sendText(JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
     }
 
+    /**
+     * 广播消息
+     * @param liveId   直播间ID
+     * @param message  消息内容
+     */
+    public void broadcastWebMessage(Long liveId, String message) {
+        ConcurrentHashMap<Long, Session> room = getRoom(liveId);
+
+        // 普通用户房间:并行发送
+        room.forEach((k, v) -> {
+            if (v.isOpen()) {
+                sendWithRetry(v,message,1);
+            }
+        });
+    }
+
     /**
      * 广播消息
      * @param liveId   直播间ID

+ 5 - 4
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -202,10 +202,11 @@ public class CompanyServiceImpl implements ICompanyService
             List<CompanyMiniapp> miniApp = companyMiniappService.getMiniAppListByCompanyList(Collections.singletonList(company.getCompanyId()));
             company.setMiniAppMaster(GET_MINI_APP_STR.apply(0, miniApp));
             company.setMiniAppServer(GET_MINI_APP_STR.apply(1, miniApp));
-        }
-        String redPackageMoney = redisCache.getCacheObject(FsConstants.COMPANY_MONEY_KEY+company.getCompanyId());
-        if(redPackageMoney!=null){
-            company.setRedPackageMoney(new BigDecimal(redPackageMoney));
+
+            String redPackageMoney = redisCache.getCacheObject(FsConstants.COMPANY_MONEY_KEY+company.getCompanyId());
+            if(redPackageMoney!=null){
+                company.setRedPackageMoney(new BigDecimal(redPackageMoney));
+            }
         }
         return company;
     }

+ 2 - 2
fs-service/src/main/java/com/fs/course/vo/FsCourseRedPacketLogListPVO.java

@@ -49,8 +49,8 @@ public class FsCourseRedPacketLogListPVO extends BaseEntity
     @Excel(name = "转帐金额")
     private BigDecimal amount;
 
-    @Excel(name = "状态",dictType = "sys_course_red_packet_status")
-    private Integer status;//状态 0 发送中  1  已发送
+    @Excel(name = "状态", readConverterExp = "0=发送中,1=已发送,2余额不足待发送")
+    private Integer status; // 状态 0 发送中 1 已发送
 
     @Excel(name = "分享人企微Id")
     private String qwUserId;

+ 1 - 1
fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogListVO.java

@@ -60,7 +60,7 @@ public class FsCourseWatchLogListVO extends BaseEntity
     @Excel(name = "小节名称")
     private String videoName;
 
-    @Excel(name = "记录类型" ,dictType = "sys_course_watch_log_type")
+    @Excel(name = "记录类型" ,dictType = "sys_course_watch_log_type_new")
     private Integer logType;
 
     @Excel(name = "奖励类型 1红包 2积分")

+ 1 - 1
fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java

@@ -878,7 +878,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
         log.info("订单号: {},发货状态: {},是否发货后: {}",liveOrder.getOrderCode(),liveOrder.getStatus(),ObjectUtils.equals(liveOrder.getStatus(),2));
 
         // 发货后退款
-        if(ObjectUtils.equals(param.getOrderStatus(),2)){
+        if(ObjectUtils.equals(param.getOrderStatus(),2) || ObjectUtils.equals(param.getOrderStatus(),3)){
 
             FsJstAftersalePush fsJstAftersalePush = new FsJstAftersalePush();
             fsJstAftersalePush.setOrderId(liveOrder.getOrderCode());

+ 98 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/MergedOrderMapper.java

@@ -0,0 +1,98 @@
+package com.fs.hisStore.mapper;
+
+import com.fs.hisStore.param.FsMyStoreOrderQueryParam;
+import com.fs.hisStore.vo.FsMergedOrderListQueryVO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 合并订单Mapper接口
+ *
+ * @author fs
+ * @date 2025-01-XX
+ */
+public interface MergedOrderMapper
+{
+    /**
+     * 查询合并的订单列表(商城订单+直播订单)
+     *
+     * @param param 查询参数
+     * @return 合并后的订单列表
+     */
+    @Select({"<script> " +
+            "SELECT * FROM ( " +
+            "  SELECT " +
+            "    o.id, " +
+            "    NULL AS order_id, " +
+            "    NULL AS live_id, " +
+            "    NULL AS after_sales_id, " +
+            "    o.order_code, " +
+            "    o.pay_price, " +
+            "    o.status, " +
+            "    o.is_package, " +
+            "    o.package_json, " +
+            "    o.item_json, " +
+            "    o.delivery_id, " +
+            "    o.finish_time, " +
+            "    o.create_time, " +
+            "    NULL AS total_num, " +
+            "    NULL AS discount_money, " +
+            "    1 AS order_type " +
+            "  FROM fs_store_order_scrm o " +
+            "  WHERE o.is_del = 0 AND o.is_sys_del = 0 " +
+            "  <if test = 'maps.status != null and maps.status != \"\"'> " +
+            "    AND o.status = #{maps.status} " +
+            "  </if> " +
+            "  <if test = 'maps.keyword != null and maps.keyword != \"\"'> " +
+            "    AND o.order_code LIKE CONCAT('%', #{maps.keyword}, '%') " +
+            "  </if> " +
+            "  <if test = 'maps.deliveryStatus != null'> " +
+            "    AND o.delivery_status = #{maps.deliveryStatus} " +
+            "  </if> " +
+            "  <if test = 'maps.userId != null'> " +
+            "    AND o.user_id = #{maps.userId} " +
+            "  </if> " +
+            "  UNION ALL " +
+            "  SELECT " +
+            "    NULL AS id, " +
+            "    o.order_id, " +
+            "    o.live_id, " +
+            "    a.id AS after_sales_id, " +
+            "    o.order_code, " +
+            "    o.pay_price, " +
+            "    o.status, " +
+            "    NULL AS is_package, " +
+            "    NULL AS package_json, " +
+            "    o.item_json, " +
+            "    o.delivery_sn AS delivery_id, " +
+            "    o.finish_time, " +
+            "    o.create_time, " +
+            "    o.total_num, " +
+            "    o.discount_money, " +
+            "    2 AS order_type " +
+            "  FROM live_order o " +
+            "  LEFT JOIN ( " +
+            "    SELECT t.*, ROW_NUMBER() OVER (PARTITION BY t.order_id ORDER BY t.create_time DESC) AS rn " +
+            "    FROM live_after_sales t " +
+            "  ) a ON o.order_id = a.order_id AND a.rn = 1 " +
+            "  WHERE o.is_del = 0 " +
+            "  <if test = 'maps.status != null and maps.status != \"\"'> " +
+            "    AND o.status = #{maps.status} " +
+            "  </if> " +
+            "  <if test = 'maps.keyword != null and maps.keyword != \"\"'> " +
+            "    AND o.order_code LIKE CONCAT('%', #{maps.keyword}, '%') " +
+            "  </if> " +
+            "  <if test = 'maps.deliveryStatus != null'> " +
+            "    AND o.delivery_status = #{maps.deliveryStatus} " +
+            "  </if> " +
+            "  <if test = 'maps.userId != null'> " +
+            "    AND o.user_id = #{maps.userId} " +
+            "  </if> " +
+            ") AS merged_orders " +
+            "ORDER BY create_time DESC " +
+            "</script>"})
+    List<FsMergedOrderListQueryVO> selectMergedOrderListVO(@Param("maps") FsMyStoreOrderQueryParam param);
+}
+

+ 24 - 0
fs-service/src/main/java/com/fs/hisStore/service/IMergedOrderService.java

@@ -0,0 +1,24 @@
+package com.fs.hisStore.service;
+
+import com.fs.hisStore.param.FsMyStoreOrderQueryParam;
+import com.fs.hisStore.vo.FsMergedOrderListQueryVO;
+
+import java.util.List;
+
+/**
+ * 合并订单Service接口
+ *
+ * @author fs
+ * @date 2025-01-XX
+ */
+public interface IMergedOrderService
+{
+    /**
+     * 查询合并的订单列表(商城订单+直播订单)
+     *
+     * @param param 查询参数
+     * @return 合并后的订单列表
+     */
+    List<FsMergedOrderListQueryVO> selectMergedOrderListVO(FsMyStoreOrderQueryParam param);
+}
+

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

@@ -5248,10 +5248,10 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         String uuid = IdUtil.randomUUID();
         redisCache.setCacheObject("createOrderKey:" + uuid, companyUser.getCompanyId() + "-" + companyUser.getUserId(), 24, TimeUnit.HOURS);
 
-        // 这里的carts是购物车信息,价格取的套餐包价格
-        for (FsStoreCartQueryVO vo : carts) {
-            vo.setPrice(storeProductPackage.getPayMoney());
-        }
+//        // 这里的carts是购物车信息,价格取的套餐包价格
+//        for (FsStoreCartQueryVO vo : carts) {
+//            vo.setPrice(storeProductPackage.getPayMoney());
+//        }
         redisCache.setCacheObject("orderCarts:" + uuid, carts, 24, TimeUnit.HOURS);
         if (orderType != null || orderMedium != null) {
             FsStoreOrderScrm fsStoreOrder = new FsStoreOrderScrm();

+ 90 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/MergedOrderServiceImpl.java

@@ -0,0 +1,90 @@
+package com.fs.hisStore.service.impl;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONUtil;
+import com.fs.common.utils.StringUtils;
+import com.fs.hisStore.enums.OrderInfoEnum;
+import com.fs.hisStore.mapper.MergedOrderMapper;
+import com.fs.hisStore.param.FsMyStoreOrderQueryParam;
+import com.fs.hisStore.service.IMergedOrderService;
+import com.fs.hisStore.vo.FsMergedOrderListQueryVO;
+import com.fs.hisStore.vo.FsStoreOrderItemVO;
+import com.fs.store.config.StoreConfig;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * 合并订单Service实现类
+ *
+ * @author fs
+ * @date 2025-01-XX
+ */
+@Service
+public class MergedOrderServiceImpl implements IMergedOrderService
+{
+    @Autowired
+    private MergedOrderMapper mergedOrderMapper;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Override
+    public List<FsMergedOrderListQueryVO> selectMergedOrderListVO(FsMyStoreOrderQueryParam param)
+    {
+        List<FsMergedOrderListQueryVO> list = mergedOrderMapper.selectMergedOrderListVO(param);
+        
+        for (FsMergedOrderListQueryVO vo : list)
+        {
+            // 处理商品JSON
+            if (StringUtils.isNotEmpty(vo.getItemJson()))
+            {
+                JSONArray jsonArray = JSONUtil.parseArray(vo.getItemJson());
+                List<FsStoreOrderItemVO> items = JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
+                if (items != null && items.size() > 0)
+                {
+                    vo.setItems(items);
+                }
+            }
+            
+            // 处理是否可以申请售后
+            vo.setIsAfterSales(0);
+            if (vo.getStatus() != null && vo.getStatus().equals(OrderInfoEnum.STATUS_3.getValue()))
+            {
+                // 已完成订单
+                vo.setIsAfterSales(1);
+                if (vo.getFinishTime() != null)
+                {
+                    String json = configService.selectConfigByKey("his.store");
+                    if (StringUtils.isNotEmpty(json))
+                    {
+                        StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+                        if (storeConfig != null && storeConfig.getStoreAfterSalesDay() != null && storeConfig.getStoreAfterSalesDay() > 0)
+                        {
+                            // 判断完成时间是否超过指定时间
+                            Calendar calendar = new GregorianCalendar();
+                            calendar.setTime(vo.getFinishTime());
+                            calendar.add(Calendar.DATE, storeConfig.getStoreAfterSalesDay());
+                            if (calendar.getTime().getTime() < new Date().getTime())
+                            {
+                                vo.setIsAfterSales(0);
+                            }
+                        }
+                    }
+                }
+            }
+            else if (vo.getStatus() != null && (vo.getStatus() == 1 || vo.getStatus() == 2))
+            {
+                vo.setIsAfterSales(1);
+            }
+        }
+        
+        return list;
+    }
+}
+

+ 78 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsMergedOrderListQueryVO.java

@@ -0,0 +1,78 @@
+package com.fs.hisStore.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 合并订单列表查询VO(商城订单+直播订单)
+ *
+ * @author fs
+ * @date 2025-01-XX
+ */
+@Data
+public class FsMergedOrderListQueryVO implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 订单ID */
+    private Long id;
+
+    /** 订单ID(直播订单使用) */
+    private Long orderId;
+
+    /** 直播ID(直播订单使用) */
+    private Long liveId;
+
+    /** 售后ID(直播订单使用) */
+    private Long afterSalesId;
+
+    /** 订单号 */
+    private String orderCode;
+
+    /** 实际支付金额 */
+    private BigDecimal payPrice;
+
+    /** 订单状态 */
+    private Integer status;
+
+    /** 是否套餐 */
+    private Integer isPackage;
+
+    /** 套餐JSON */
+    private String packageJson;
+
+    /** 商品JSON */
+    private String itemJson;
+
+    /** 物流单号 */
+    private String deliveryId;
+
+    /** 是否可以申请售后 */
+    private Integer isAfterSales;
+
+    /** 完成时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date finishTime;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /** 总数量(直播订单使用) */
+    private Integer totalNum;
+
+    /** 优惠金额(直播订单使用) */
+    private Integer discountMoney;
+
+    /** 订单类型:1-商城订单,2-直播订单 */
+    private Integer orderType;
+
+    /** 订单商品列表 */
+    private List<FsStoreOrderItemVO> items;
+}
+

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

@@ -748,7 +748,11 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             order.setPayTime(LocalDateTime.now());
             order.setIsPay("1");
             baseMapper.updateLiveOrder(order);
-            this.createOmsOrderCall(order);
+            try {
+                this.createOmsOrderCall(order);
+            } catch (Exception e) {
+                log.error("推送erp失败:{}",e.getMessage());
+            }
             return "SUCCESS";
         }catch (Exception e){
             log.info("支付错误:"+e.getMessage());
@@ -3478,8 +3482,9 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         FsStoreProductScrm fsStoreProduct = fsStoreProductService.selectFsStoreProductById(liveOrder.getProductId());
         LiveGoods goods = liveGoodsMapper.selectLiveGoodsByProductId(liveOrder.getLiveId(), liveOrder.getProductId());
         if(goods == null) return R.error("当前商品不存在");
-        if(fsStoreProduct == null) return R.error("店铺已下架商品,购买失败");
+        if(fsStoreProduct == null) return R.error("商品不存在,购买失败");
         if(fsStoreProduct.getIsShow() == 0 || goods.getStatus() == 0) return R.error("商品已下架,购买失败");
+        if(!"1".equals(fsStoreProduct.getIsAudit()) ) return R.error("商品已下架,购买失败");
         if(liveOrder.getTotalNum() == null || StringUtils.isEmpty(liveOrder.getTotalNum())) liveOrder.setTotalNum("1");
         if(goods.getStock() == null) return R.error("直播间商品库存不足");
         if(fsStoreProduct.getStock() < Integer.parseInt(liveOrder.getTotalNum()) || goods.getStock() < Integer.parseInt(liveOrder.getTotalNum())) return R.error("抱歉,这款商品已被抢光,暂时无库存~");

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

@@ -323,7 +323,7 @@ public class LiveServiceImpl implements ILiveService
         });
         notifyTask.setData(JSON.toJSONString(data));
 //        return R.ok("success");
-//        liveMiniprogramSubNotifyTaskMapper.insert(notifyTask);
+        liveMiniprogramSubNotifyTaskMapper.insert(notifyTask);
 
         return R.ok("success");
     }

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

@@ -75,7 +75,7 @@ public class LiveWatchConfigServiceImpl implements ILiveWatchConfigService {
     @Override
     public int insertLiveWatchConfig(String userId, String jsonConfig ,Long liveId)
     {
-        Live live = liveService.selectLiveByLiveId(liveId);
+        Live live = liveService.selectLiveDbByLiveId(liveId);
         if(live == null){
             return 0;
         }
@@ -95,7 +95,7 @@ public class LiveWatchConfigServiceImpl implements ILiveWatchConfigService {
     @Override
     public int updateLiveWatchConfig(String jsonConfig, Long liveId)
     {
-        Live live = liveService.selectLiveByLiveId(liveId);
+        Live live = liveService.selectLiveDbByLiveId(liveId);
         if(live == null){
             return 0;
         }

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

@@ -42,8 +42,8 @@ wx:
       port: 6379
       timeout: 2000
     configs:
-      - appId: wx17f36a56c701bdea # 第一个公众号的appid   //公众号名称
-        secret: 185030bbe7f8d7a0c16b94dd9d4ea542 # 公众号的appsecret
+      - appId: wxbf0cfcfbc92ccd72 # 第一个公众号的appid   //赤峰润元堂
+        secret: b08b0c6e763b5fa3c863b3dd114cd1c9 # 公众号的appsecret
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVcw03qZy6Wllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
 aifabu:  #爱链接

+ 3 - 3
fs-service/src/main/resources/application-druid-bjzm.yml

@@ -50,11 +50,11 @@ spring:
                     username: root
                     password: Ylrz_1q2w3e4r5t6y
                 # 初始连接数
-                initialSize: 5
+                initialSize: 50
                 # 最小连接池数量
-                minIdle: 10
+                minIdle: 50
                 # 最大连接池数量
-                maxActive: 20
+                maxActive: 500
                 # 配置获取连接等待超时的时间
                 maxWait: 60000
                 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

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

@@ -412,15 +412,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectLiveDataDetailBySql" resultType="com.fs.live.vo.LiveDataDetailVo">
         SELECT
             COALESCE(video_duration.total_duration, 0) AS videoDuration,
-            (COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 THEN lwu.user_id END) +  COUNT(DISTINCT CASE WHEN lwu.live_flag = 0 AND lwu.replay_flag = 1 THEN lwu.user_id END)) AS totalViewers,
+            COUNT(DISTINCT lwu.user_id) AS totalViewers,
             COUNT(DISTINCT CASE
-                WHEN lwu.online_seconds >= COALESCE(video_duration.total_duration, 0) AND video_duration.total_duration > 0
+                WHEN COALESCE(user_duration.total_duration, 0) >= 1800
                 THEN lwu.user_id
             END) AS totalCompletedCourses,
             CASE
                 WHEN COUNT(DISTINCT lwu.user_id) > 0 THEN
                     ROUND(COUNT(DISTINCT CASE
-                        WHEN lwu.online_seconds >= COALESCE(video_duration.total_duration, 0) AND video_duration.total_duration > 0
+                        WHEN COALESCE(user_duration.total_duration, 0) >= 1800
                         THEN lwu.user_id
                     END) * 100.0 / COUNT(DISTINCT lwu.user_id), 2)
                 ELSE 0
@@ -473,8 +473,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 ELSE 0
             END AS totalViewerConversionRate,
             CASE
-                WHEN COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1800 THEN lwu.user_id END) > 0 THEN
-                    ROUND(order_stats.paidUsers * 100.0 / COUNT(DISTINCT CASE WHEN lwu.live_flag = 1 AND lwu.replay_flag = 0 AND lwu.online_seconds >= 1800 THEN lwu.user_id END), 2)
+                WHEN COUNT(DISTINCT CASE
+                    WHEN COALESCE(user_duration.total_duration, 0) >= 1800
+                    THEN lwu.user_id
+                END) > 0 THEN
+                    ROUND(order_stats.paidUsers * 100.0 / COUNT(DISTINCT CASE
+                        WHEN COALESCE(user_duration.total_duration, 0) >= 1800
+                        THEN lwu.user_id
+                    END), 2)
                 ELSE 0
             END AS completion30MinConversionRate,
             CASE
@@ -484,11 +490,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             END AS peakRValue,
             CASE
                 WHEN COUNT(DISTINCT CASE
-                    WHEN lwu.online_seconds >= COALESCE(video_duration.total_duration, 0) AND video_duration.total_duration > 0
+                    WHEN COALESCE(user_duration.total_duration, 0) >= 1800
                     THEN lwu.user_id
                 END) > 0 THEN
                     ROUND(order_stats.gmv / COUNT(DISTINCT CASE
-                        WHEN lwu.online_seconds >= COALESCE(video_duration.total_duration, 0) AND video_duration.total_duration > 0
+                        WHEN COALESCE(user_duration.total_duration, 0) >= 1800
                         THEN lwu.user_id
                     END), 2)
                 ELSE 0
@@ -502,6 +508,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             WHERE video_type IN (1, 2)
             GROUP BY live_id
         ) video_duration ON l.live_id = video_duration.live_id
+        LEFT JOIN (
+            SELECT
+                live_id,
+                user_id,
+                COALESCE(SUM(CASE WHEN live_flag = 1 AND replay_flag = 0 THEN COALESCE(online_seconds, 0) ELSE 0 END), 0) +
+                COALESCE(SUM(CASE WHEN live_flag = 0 AND replay_flag = 1 THEN COALESCE(online_seconds, 0) ELSE 0 END), 0) AS total_duration
+            FROM live_watch_user
+            WHERE live_id = #{liveId}
+            GROUP BY live_id, user_id
+        ) user_duration ON l.live_id = user_duration.live_id AND lwu.user_id = user_duration.user_id
         LEFT JOIN (
             SELECT
                 live_id,

+ 57 - 0
fs-user-app/src/main/java/com/fs/app/controller/live/OrderController.java

@@ -0,0 +1,57 @@
+package com.fs.app.controller.live;
+
+import com.fs.app.annotation.Login;
+import com.fs.app.controller.AppBaseController;
+import com.fs.common.core.domain.R;
+import com.fs.hisStore.param.FsMyStoreOrderQueryParam;
+import com.fs.hisStore.service.IMergedOrderService;
+import com.fs.hisStore.vo.FsMergedOrderListQueryVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+@Api("订单信息接口")
+@RestController("AppOrderController")
+@AllArgsConstructor
+@RequestMapping(value="/app/order")
+public class OrderController extends AppBaseController {
+
+    private final IMergedOrderService mergedOrderService;
+
+    @Login
+    @ApiOperation("获取我的合并订单列表(商城订单+直播订单)")
+    @GetMapping("/getMyMergedOrderList")
+    public R getMyMergedOrderList(FsMyStoreOrderQueryParam param, HttpServletRequest request)
+    {
+        // 设置分页参数
+        if (param.getPage() == null || param.getPage() < 1)
+        {
+            param.setPage(1);
+        }
+        if (param.getPageSize() == null || param.getPageSize() < 1)
+        {
+            param.setPageSize(10);
+        }
+        
+        PageHelper.startPage(param.getPage(), param.getPageSize());
+        
+        // 设置用户ID
+        param.setUserId(Long.parseLong(getUserId()));
+        
+        // 查询合并订单列表
+        List<FsMergedOrderListQueryVO> list = mergedOrderService.selectMergedOrderListVO(param);
+        
+        // 封装分页信息
+        PageInfo<FsMergedOrderListQueryVO> listPageInfo = new PageInfo<>(list);
+        
+        return R.ok().put("data", listPageInfo);
+    }
+}