Explorar el Código

Merge branch 'refs/heads/cg_live_dev' into openImAndLive

# Conflicts:
#	fs-admin/src/main/java/com/fs/his/task/Task.java
#	fs-common/src/main/java/com/fs/common/core/redis/RedisCache.java
#	fs-company/src/main/java/com/fs/company/controller/common/CommonController.java
#	fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
yuhongqi hace 7 meses
padre
commit
25106f6914
Se han modificado 100 ficheros con 9516 adiciones y 514 borrados
  1. 12 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserTalentController.java
  2. 10 0
      fs-admin/src/main/java/com/fs/his/controller/FsStoreProductController.java
  3. 34 0
      fs-admin/src/main/java/com/fs/his/task/Task.java
  4. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesController.java
  5. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesItemController.java
  6. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesLogsController.java
  7. 9 15
      fs-admin/src/main/java/com/fs/live/controller/LiveAnchorController.java
  8. 105 0
      fs-admin/src/main/java/com/fs/live/controller/LiveAutoTaskController.java
  9. 105 0
      fs-admin/src/main/java/com/fs/live/controller/LiveCartController.java
  10. 78 29
      fs-admin/src/main/java/com/fs/live/controller/LiveController.java
  11. 71 0
      fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java
  12. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveEventConfController.java
  13. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveGiftController.java
  14. 87 23
      fs-admin/src/main/java/com/fs/live/controller/LiveGoodsController.java
  15. 0 103
      fs-admin/src/main/java/com/fs/live/controller/LiveGoodsOrderController.java
  16. 0 103
      fs-admin/src/main/java/com/fs/live/controller/LiveGoodsOrderItemsController.java
  17. 141 0
      fs-admin/src/main/java/com/fs/live/controller/LiveLotteryConfController.java
  18. 4 0
      fs-admin/src/main/java/com/fs/live/controller/LiveLotteryController.java
  19. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveLotteryRecordController.java
  20. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveLotteryRegistrationController.java
  21. 9 15
      fs-admin/src/main/java/com/fs/live/controller/LiveMsgController.java
  22. 268 0
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java
  23. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderItemController.java
  24. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderLogsController.java
  25. 0 103
      fs-admin/src/main/java/com/fs/live/controller/LiveQuestionController.java
  26. 116 0
      fs-admin/src/main/java/com/fs/live/controller/LiveRedConfController.java
  27. 4 0
      fs-admin/src/main/java/com/fs/live/controller/LiveRedController.java
  28. 104 0
      fs-admin/src/main/java/com/fs/live/controller/LiveRewardRecordController.java
  29. 98 0
      fs-admin/src/main/java/com/fs/live/controller/LiveSensitiveWordsController.java
  30. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveUserFavoriteController.java
  31. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveUserFollowController.java
  32. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveUserLikeController.java
  33. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveUserLotteryRecordController.java
  34. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveUserRedRecordController.java
  35. 19 15
      fs-admin/src/main/java/com/fs/live/controller/LiveVideoController.java
  36. 103 0
      fs-admin/src/main/java/com/fs/live/controller/LiveWatchConfigController.java
  37. 42 14
      fs-admin/src/main/java/com/fs/live/controller/LiveWatchUserController.java
  38. 12 0
      fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java
  39. 99 1
      fs-common/src/main/java/com/fs/common/core/redis/RedisCache.java
  40. 64 0
      fs-common/src/main/java/com/fs/common/utils/DateUtils.java
  41. 10 0
      fs-company/src/main/java/com/fs/company/controller/common/CommonController.java
  42. 16 0
      fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java
  43. 121 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveAnchorController.java
  44. 105 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveAutoTaskController.java
  45. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveCartController.java
  46. 357 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveController.java
  47. 157 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveDataController.java
  48. 103 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveGiftController.java
  49. 163 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveGoodsController.java
  50. 133 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryConfController.java
  51. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryRecordController.java
  52. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryRegistrationController.java
  53. 101 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveMsgController.java
  54. 274 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java
  55. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderItemController.java
  56. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderLogsController.java
  57. 40 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveProfitController.java
  58. 115 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveRedConfController.java
  59. 104 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveRewardRecordController.java
  60. 104 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveSensitiveWordsController.java
  61. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserFavoriteController.java
  62. 103 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserFirstEntryController.java
  63. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserFollowController.java
  64. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserLikeController.java
  65. 107 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveVideoController.java
  66. 113 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveWatchConfigController.java
  67. 132 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveWatchUserController.java
  68. 2 1
      fs-company/src/main/java/com/fs/company/controller/store/FsStoreProductController.java
  69. 141 0
      fs-live-app/src/main/java/com/fs/app/config/ProductionWordFilter.java
  70. 98 1
      fs-live-app/src/main/java/com/fs/app/controller/AppBaseController.java
  71. 97 0
      fs-live-app/src/main/java/com/fs/app/controller/CaptchaController.java
  72. 42 0
      fs-live-app/src/main/java/com/fs/app/controller/CommonController.java
  73. 69 0
      fs-live-app/src/main/java/com/fs/app/controller/FsStoreController.java
  74. 105 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveAfterSalesController.java
  75. 139 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveCartController.java
  76. 172 15
      fs-live-app/src/main/java/com/fs/app/controller/LiveController.java
  77. 115 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveDataController.java
  78. 13 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveGiftController.java
  79. 131 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveGoodsController.java
  80. 48 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveLotteryController.java
  81. 89 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveMsgController.java
  82. 250 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveOrderController.java
  83. 97 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveOrderLogsController.java
  84. 104 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveOrderPaymentController.java
  85. 30 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveRedController.java
  86. 97 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveUserFavoriteController.java
  87. 97 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveUserFollowController.java
  88. 60 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveUserGiftController.java
  89. 97 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveUserLikeController.java
  90. 98 0
      fs-live-app/src/main/java/com/fs/app/controller/LiveWatchUserController.java
  91. 148 0
      fs-live-app/src/main/java/com/fs/app/controller/UserAddressController.java
  92. 443 65
      fs-live-app/src/main/java/com/fs/app/controller/UserController.java
  93. 18 0
      fs-live-app/src/main/java/com/fs/app/param/FsAddressParseParam.java
  94. 59 0
      fs-live-app/src/main/java/com/fs/app/param/FsUserAddressAddEditParam.java
  95. 32 0
      fs-live-app/src/main/java/com/fs/app/param/FsUserEditPhoneParam.java
  96. 19 0
      fs-live-app/src/main/java/com/fs/app/param/FsUserLoginByWeChatParam.java
  97. 26 0
      fs-live-app/src/main/java/com/fs/app/param/FsUserLoginParam.java
  98. 279 11
      fs-live-app/src/main/java/com/fs/app/task/Task.java
  99. 85 0
      fs-live-app/src/main/java/com/fs/app/utils/CityTreeUtil.java
  100. 46 0
      fs-live-app/src/main/java/com/fs/app/utils/VerifyUtils.java

+ 12 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserTalentController.java

@@ -6,6 +6,8 @@ import java.util.Objects;
 
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
+import com.fs.company.service.ICompanyService;
+import com.fs.company.vo.CompanyVO;
 import com.fs.common.utils.StringUtils;
 import com.fs.his.utils.PhoneUtil;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -40,6 +42,9 @@ public class FsUserTalentController extends BaseController
     @Autowired
     private IFsUserTalentService fsUserTalentService;
 
+    @Autowired
+    private ICompanyService companyService;
+
     /**
      * 查询达人列表
      */
@@ -130,4 +135,11 @@ public class FsUserTalentController extends BaseController
         List<FsUserTalent> list = fsUserTalentService.selectFsUserTalentList(fsUserTalent);
         return R.ok().put("data",list);
     }
+
+    @GetMapping("/listCompanyByKeyword/{keyword}")
+    public R listCompanyByKeyword(@PathVariable String keyword)
+    {
+        List<CompanyVO> companies = companyService.selectCompanyByKeyword(keyword);
+        return R.ok().put("data",companies);
+    }
 }

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

@@ -55,6 +55,16 @@ public class FsStoreProductController extends BaseController
         return getDataTable(list);
     }
 
+    @PreAuthorize("@ss.hasPermi('his:storeProduct:list')")
+    @GetMapping("/liveList")
+    public TableDataInfo livList(FsStoreProduct fsStoreProduct,@RequestParam Long liveId)
+    {
+        fsStoreProduct.setLiveId(liveId.toString());
+        startPage();
+        List<FsStoreProductVO> list = fsStoreProductService.selectFsStoreProductListVO(fsStoreProduct);
+        return getDataTable(list);
+    }
+
     /**
      * 导出商品列表
      */

+ 34 - 0
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -51,6 +51,11 @@ import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.im.dto.*;
 import com.fs.im.service.IImService;
 import com.fs.im.service.OpenIMService;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.param.LiveOrderFinishParam;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.qw.service.IQwAppContactWayService;
+import com.fs.qw.service.IQwExternalContactTransferLogService;
 import com.fs.qw.domain.QwCompany;
 import com.fs.qw.service.*;
 import com.fs.qwApi.service.QwApiService;
@@ -156,8 +161,21 @@ public class Task {
 
     @Autowired
     ITencentCloudCosService tencentCloudCosService;
+
+    @Autowired
+    private ILiveOrderService liveOrderService;
     @Autowired
     private ConfigUtil configUtil;
+
+    public void pushLiveOrder()
+    {
+        List<LiveOrder> list = liveOrderService.selectNotPushedLiveOrder();
+        for (LiveOrder liveOrder : list) {
+            try {
+                liveOrderService.pushLiveOrder(liveOrder);
+            } catch (Exception e) {}
+        }
+    }
     @Autowired
     private IQwCompanyService qwCompanyService;
     @Autowired
@@ -761,6 +779,22 @@ public class Task {
         }
     }
 
+    public void finishLiveOrder(){
+        List<LiveOrder> orders = liveOrderService.selectLiveOrderByFinish();
+        for (LiveOrder order : orders) {
+            // 订单已超过48小时,执行关闭操作
+            LiveOrderFinishParam param = new LiveOrderFinishParam();
+            param.setOrderId(order.getOrderId());
+            try {
+                // todo yhq 未完成
+                liveOrderService.autoFinishOrder(param);
+            }catch (Exception e){
+                logger.info("订单已超过48小时关闭异常"+param);
+            }
+
+        }
+    }
+
 
     public void finishStoreOrderByXN(){
         List<FsStoreOrder> orders = fsStoreOrderMapper.selectFinishStoreOrderByXN();

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveAfterSales;
+import com.fs.live.service.ILiveAfterSalesService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 售后记录Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveAfteraSales")
+public class LiveAfterSalesController extends BaseController
+{
+    @Autowired
+    private ILiveAfterSalesService liveAfterSalesService;
+
+    /**
+     * 查询售后记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfteraSales:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveAfterSales liveAfterSales)
+    {
+        startPage();
+        List<LiveAfterSales> list = liveAfterSalesService.selectLiveAfterSalesList(liveAfterSales);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出售后记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfteraSales:export')")
+    @Log(title = "售后记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveAfterSales liveAfterSales)
+    {
+        List<LiveAfterSales> list = liveAfterSalesService.selectLiveAfterSalesList(liveAfterSales);
+        ExcelUtil<LiveAfterSales> util = new ExcelUtil<LiveAfterSales>(LiveAfterSales.class);
+        return util.exportExcel(list, "售后记录数据");
+    }
+
+    /**
+     * 获取售后记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfteraSales:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveAfterSalesService.selectLiveAfterSalesById(id));
+    }
+
+    /**
+     * 新增售后记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfteraSales:add')")
+    @Log(title = "售后记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveAfterSales liveAfterSales)
+    {
+        return toAjax(liveAfterSalesService.insertLiveAfterSales(liveAfterSales));
+    }
+
+    /**
+     * 修改售后记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfteraSales:edit')")
+    @Log(title = "售后记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveAfterSales liveAfterSales)
+    {
+        return toAjax(liveAfterSalesService.updateLiveAfterSales(liveAfterSales));
+    }
+
+    /**
+     * 删除售后记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfteraSales:remove')")
+    @Log(title = "售后记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveAfterSalesService.deleteLiveAfterSalesByIds(ids));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesItemController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveAfterSalesItem;
+import com.fs.live.service.ILiveAfterSalesItemService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 售后子Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveAfterSalesItem")
+public class LiveAfterSalesItemController extends BaseController
+{
+    @Autowired
+    private ILiveAfterSalesItemService liveAfterSalesItemService;
+
+    /**
+     * 查询售后子列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesItem:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveAfterSalesItem liveAfterSalesItem)
+    {
+        startPage();
+        List<LiveAfterSalesItem> list = liveAfterSalesItemService.selectLiveAfterSalesItemList(liveAfterSalesItem);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出售后子列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesItem:export')")
+    @Log(title = "售后子", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveAfterSalesItem liveAfterSalesItem)
+    {
+        List<LiveAfterSalesItem> list = liveAfterSalesItemService.selectLiveAfterSalesItemList(liveAfterSalesItem);
+        ExcelUtil<LiveAfterSalesItem> util = new ExcelUtil<LiveAfterSalesItem>(LiveAfterSalesItem.class);
+        return util.exportExcel(list, "售后子数据");
+    }
+
+    /**
+     * 获取售后子详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesItem:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveAfterSalesItemService.selectLiveAfterSalesItemById(id));
+    }
+
+    /**
+     * 新增售后子
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesItem:add')")
+    @Log(title = "售后子", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveAfterSalesItem liveAfterSalesItem)
+    {
+        return toAjax(liveAfterSalesItemService.insertLiveAfterSalesItem(liveAfterSalesItem));
+    }
+
+    /**
+     * 修改售后子
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesItem:edit')")
+    @Log(title = "售后子", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveAfterSalesItem liveAfterSalesItem)
+    {
+        return toAjax(liveAfterSalesItemService.updateLiveAfterSalesItem(liveAfterSalesItem));
+    }
+
+    /**
+     * 删除售后子
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesItem:remove')")
+    @Log(title = "售后子", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveAfterSalesItemService.deleteLiveAfterSalesItemByIds(ids));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesLogsController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveAfterSalesLogs;
+import com.fs.live.service.ILiveAfterSalesLogsService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 售后订单操作Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveAfterSalesLogs")
+public class LiveAfterSalesLogsController extends BaseController
+{
+    @Autowired
+    private ILiveAfterSalesLogsService liveAfterSalesLogsService;
+
+    /**
+     * 查询售后订单操作列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesLogs:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveAfterSalesLogs liveAfterSalesLogs)
+    {
+        startPage();
+        List<LiveAfterSalesLogs> list = liveAfterSalesLogsService.selectLiveAfterSalesLogsList(liveAfterSalesLogs);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出售后订单操作列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesLogs:export')")
+    @Log(title = "售后订单操作", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveAfterSalesLogs liveAfterSalesLogs)
+    {
+        List<LiveAfterSalesLogs> list = liveAfterSalesLogsService.selectLiveAfterSalesLogsList(liveAfterSalesLogs);
+        ExcelUtil<LiveAfterSalesLogs> util = new ExcelUtil<LiveAfterSalesLogs>(LiveAfterSalesLogs.class);
+        return util.exportExcel(list, "售后订单操作数据");
+    }
+
+    /**
+     * 获取售后订单操作详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesLogs:query')")
+    @GetMapping(value = "/{logsId}")
+    public AjaxResult getInfo(@PathVariable("logsId") Long logsId)
+    {
+        return AjaxResult.success(liveAfterSalesLogsService.selectLiveAfterSalesLogsByLogsId(logsId));
+    }
+
+    /**
+     * 新增售后订单操作
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesLogs:add')")
+    @Log(title = "售后订单操作", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveAfterSalesLogs liveAfterSalesLogs)
+    {
+        return toAjax(liveAfterSalesLogsService.insertLiveAfterSalesLogs(liveAfterSalesLogs));
+    }
+
+    /**
+     * 修改售后订单操作
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesLogs:edit')")
+    @Log(title = "售后订单操作", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveAfterSalesLogs liveAfterSalesLogs)
+    {
+        return toAjax(liveAfterSalesLogsService.updateLiveAfterSalesLogs(liveAfterSalesLogs));
+    }
+
+    /**
+     * 删除售后订单操作
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAfterSalesLogs:remove')")
+    @Log(title = "售后订单操作", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{logsIds}")
+    public AjaxResult remove(@PathVariable Long[] logsIds)
+    {
+        return toAjax(liveAfterSalesLogsService.deleteLiveAfterSalesLogsByLogsIds(logsIds));
+    }
+}

+ 9 - 15
fs-admin/src/main/java/com/fs/live/controller/LiveAnchorController.java

@@ -1,28 +1,22 @@
-package com.fs.live.controller;
+package com.fs.live.controller.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.live.domain.LiveAnchor;
 import com.fs.live.service.ILiveAnchorService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 主播Controller
- * 
+ *
  * @author fs
  * @date 2025-01-17
  */

+ 105 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveAutoTaskController.java

@@ -0,0 +1,105 @@
+package com.fs.live.controller;
+
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.live.domain.LiveAutoTask;
+import com.fs.live.service.ILiveAutoTaskService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播间自动化任务配置Controller
+ *
+ * @author fs
+ * @date 2025-08-29
+ */
+@RestController
+@RequestMapping("/live/task")
+public class LiveAutoTaskController extends BaseController
+{
+    @Autowired
+    private ILiveAutoTaskService liveAutoTaskService;
+
+    /**
+     * 查询直播间自动化任务配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveAutoTask liveAutoTask)
+    {
+        startPage();
+        List<LiveAutoTask> list = liveAutoTaskService.selectLiveAutoTaskList(liveAutoTask);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播间自动化任务配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:export')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveAutoTask liveAutoTask)
+    {
+        List<LiveAutoTask> list = liveAutoTaskService.selectLiveAutoTaskList(liveAutoTask);
+        ExcelUtil<LiveAutoTask> util = new ExcelUtil<LiveAutoTask>(LiveAutoTask.class);
+        return util.exportExcel(list, "直播间自动化任务配置数据");
+    }
+
+    /**
+     * 获取直播间自动化任务配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveAutoTaskService.selectLiveAutoTaskById(id));
+    }
+
+    /**
+     * 新增直播间自动化任务配置
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:add')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R add(@RequestBody LiveAutoTask liveAutoTask)
+    {
+        return liveAutoTaskService.insertLiveAutoTask(liveAutoTask);
+    }
+
+    /**
+     * 修改直播间自动化任务配置
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:edit')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveAutoTask liveAutoTask)
+    {
+        return toAjax(liveAutoTaskService.updateLiveAutoTask(liveAutoTask));
+    }
+
+    /**
+     * 删除直播间自动化任务配置
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:remove')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveAutoTaskService.deleteLiveAutoTaskByIds(ids));
+    }
+}

+ 105 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveCartController.java

@@ -0,0 +1,105 @@
+package com.fs.live.controller;
+
+import java.util.List;
+
+import com.fs.live.vo.LiveCartVo;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveCart;
+import com.fs.live.service.ILiveCartService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 购物车Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveCart")
+public class LiveCartController extends BaseController
+{
+    @Autowired
+    private ILiveCartService liveCartService;
+
+    /**
+     * 查询购物车列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveCart liveCart)
+    {
+        startPage();
+        List<LiveCartVo> list = liveCartService.selectLiveCartListVo(liveCart);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出购物车列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:export')")
+    @Log(title = "购物车", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveCart liveCart)
+    {
+        List<LiveCart> list = liveCartService.selectLiveCartList(liveCart);
+        ExcelUtil<LiveCart> util = new ExcelUtil<LiveCart>(LiveCart.class);
+        return util.exportExcel(list, "购物车数据");
+    }
+
+    /**
+     * 获取购物车详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:query')")
+    @GetMapping(value = "/{cardId}")
+    public AjaxResult getInfo(@PathVariable("cardId") Long cardId)
+    {
+        return AjaxResult.success(liveCartService.selectLiveCartByCartId(cardId));
+    }
+
+    /**
+     * 新增购物车
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:add')")
+    @Log(title = "购物车", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveCart liveCart)
+    {
+        return toAjax(liveCartService.insertLiveCart(liveCart));
+    }
+
+    /**
+     * 修改购物车
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:edit')")
+    @Log(title = "购物车", businessType = BusinessType.UPDATE)
+    @PostMapping("/update")
+    public AjaxResult edit(@RequestBody LiveCart liveCart)
+    {
+        return toAjax(liveCartService.updateLiveCart(liveCart));
+    }
+
+    /**
+     * 删除购物车
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:remove')")
+    @Log(title = "购物车", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{cardIds}")
+    public AjaxResult remove(@PathVariable Long[] cardIds)
+    {
+        return toAjax(liveCartService.deleteLiveCartByCartIds(cardIds));
+    }
+}

+ 78 - 29
fs-admin/src/main/java/com/fs/live/controller/LiveController.java

@@ -1,45 +1,45 @@
 package com.fs.live.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.course.domain.FsUserTalent;
+import com.fs.course.service.IFsUserTalentService;
 import com.fs.live.domain.Live;
 import com.fs.live.service.ILiveService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import com.fs.live.vo.LiveListVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * 直播Controller
- * 
+ *
  * @author fs
  * @date 2025-01-17
  */
 @RestController
 @RequestMapping("/live/live")
-public class LiveController extends BaseController
-{
+public class LiveController extends BaseController {
     @Autowired
     private ILiveService liveService;
+    @Autowired
+    private IFsUserTalentService fsUserTalentService;
 
     /**
      * 查询直播列表
      */
     @PreAuthorize("@ss.hasPermi('live:live:list')")
     @GetMapping("/list")
-    public TableDataInfo list(Live live)
-    {
+    public TableDataInfo list(Live live) {
         startPage();
         List<Live> list = liveService.selectLiveList(live);
         return getDataTable(list);
@@ -51,20 +51,29 @@ public class LiveController extends BaseController
     @PreAuthorize("@ss.hasPermi('live:live:export')")
     @Log(title = "直播", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
-    public AjaxResult export(Live live)
-    {
+    public AjaxResult export(Live live) {
         List<Live> list = liveService.selectLiveList(live);
         ExcelUtil<Live> util = new ExcelUtil<Live>(Live.class);
         return util.exportExcel(list, "直播数据");
     }
 
+    /**
+     * 导出直播列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:edit')")
+    @GetMapping("/finishLive")
+    public R finishLive(Live live) {
+        Long userId = getUserId();
+        live.setCompanyUserId(userId);
+        return liveService.finishLive(live);
+    }
+
     /**
      * 获取直播详细信息
      */
     @PreAuthorize("@ss.hasPermi('live:live:query')")
     @GetMapping(value = "/{liveId}")
-    public AjaxResult getInfo(@PathVariable("liveId") Long liveId)
-    {
+    public AjaxResult getInfo(@PathVariable("liveId") Long liveId) {
         return AjaxResult.success(liveService.selectLiveByLiveId(liveId));
     }
 
@@ -74,8 +83,7 @@ public class LiveController extends BaseController
     @PreAuthorize("@ss.hasPermi('live:live:add')")
     @Log(title = "直播", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody Live live)
-    {
+    public AjaxResult add(@RequestBody Live live) {
         return toAjax(liveService.insertLive(live));
     }
 
@@ -85,8 +93,7 @@ public class LiveController extends BaseController
     @PreAuthorize("@ss.hasPermi('live:live:edit')")
     @Log(title = "直播", businessType = BusinessType.UPDATE)
     @PutMapping
-    public AjaxResult edit(@RequestBody Live live)
-    {
+    public AjaxResult edit(@RequestBody Live live) {
         return toAjax(liveService.updateLive(live));
     }
 
@@ -95,9 +102,51 @@ public class LiveController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('live:live:remove')")
     @Log(title = "直播", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{liveIds}")
-    public AjaxResult remove(@PathVariable Long[] liveIds)
-    {
+    @DeleteMapping("/{liveIds}")
+    public AjaxResult remove(@PathVariable Long[] liveIds) {
         return toAjax(liveService.deleteLiveByLiveIds(liveIds));
     }
+
+    @GetMapping("/living/{liveId}")
+    public R getRoom(@PathVariable String liveId) {
+        return liveService.getLiveRoom(liveId);
+    }
+
+    @PostMapping("/updateLiveIsAudit")
+    public Integer updateLiveIsAudit(@RequestBody Live live) {
+        return liveService.updateLive(live);
+    }
+
+    /**
+     * 批量上下架视频
+     */
+    @PostMapping("/handleShelfOrUn")
+    public R handleShelfOrUn(@RequestBody LiveListVo listVo) {
+        return liveService.handleShelfOrUnAdmin(listVo);
+    }
+
+    /**
+     * 批量删除视频
+     */
+    @PostMapping("/handleDeleteSelected")
+    public R handleDeleteSelected(@RequestBody LiveListVo listVo) {
+        return liveService.handleDeleteSelectedAdmin(listVo);
+    }
+    /**
+     * 校验上传的身份证信息
+     */
+    @PostMapping("/verifyIdInfo")
+    public R verifyIdInfo(@RequestBody Map<String, String> payload) {
+        return liveService.verifyIdInfo(payload);
+    }
+
+    /**
+     * 获取达人详细信息
+     */
+    @GetMapping(value = "/selectCompanyTalent")
+    public TableDataInfo selectCompanyTalent()
+    {
+        List<FsUserTalent> list = fsUserTalentService.selectAllCompanyTalent();
+        return getDataTable(list);
+    }
 }

+ 71 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java

@@ -0,0 +1,71 @@
+package com.fs.live.controller;
+
+import com.fs.common.core.domain.R;
+import com.fs.live.domain.LiveData;
+import com.fs.live.service.ILiveDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+import static com.fs.common.utils.SecurityUtils.getUserId;
+
+@RestController
+@RequestMapping("/live/liveData")
+public class LiveDataController {
+
+    @Autowired
+    private ILiveDataService liveDataService;
+
+    /**
+     * 查询直播数据列表
+     * */
+    @GetMapping("/list")
+    public List<LiveData> list(LiveData liveData) {
+        return liveDataService.selectLiveDataList(liveData);
+    }
+
+    /**
+     * 查询直播数据详情
+     * */
+    @GetMapping("/get/{liveId}")
+    public R getLiveData(@PathVariable Long liveId) {
+        return R.ok().put("liveData", liveDataService.selectLiveDataByLiveId(liveId));
+    }
+
+    /**
+     * 点赞
+     * */
+    @GetMapping("/like/{liveId}")
+    public R like(@PathVariable Long liveId) {
+        return R.ok(liveDataService.updateLikeByLiveId(liveId, getUserId()));
+    }
+
+    /**
+     * 收藏
+     * */
+    @GetMapping("/collect/{liveId}")
+    public R collect(@PathVariable Long liveId) {
+        return R.ok(liveDataService.collect(liveId, getUserId()));
+    }
+
+    /**
+     * 关注
+     * */
+    @GetMapping("/follow/{liveId}")
+    public R follow(@PathVariable Long liveId) {
+        return R.ok(liveDataService.follow(liveId, getUserId()));
+    }
+
+    /**
+     * 获取直播内数据
+     * */
+    @GetMapping("/getLiveViewData")
+    public R getLiveViewData(Long liveId) {
+        Map<String,Object> liveViewData =liveDataService.getLiveViewData(liveId);
+        return R.ok(liveViewData);
+    }
+
+
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveEventConfController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveEventConf;
+import com.fs.live.service.ILiveEventConfService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播触发事件配置Controller
+ * 
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveEventConf")
+public class LiveEventConfController extends BaseController
+{
+    @Autowired
+    private ILiveEventConfService liveEventConfService;
+
+    /**
+     * 查询直播触发事件配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveEventConf:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveEventConf liveEventConf)
+    {
+        startPage();
+        List<LiveEventConf> list = liveEventConfService.selectLiveEventConfList(liveEventConf);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播触发事件配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveEventConf:export')")
+    @Log(title = "直播触发事件配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveEventConf liveEventConf)
+    {
+        List<LiveEventConf> list = liveEventConfService.selectLiveEventConfList(liveEventConf);
+        ExcelUtil<LiveEventConf> util = new ExcelUtil<LiveEventConf>(LiveEventConf.class);
+        return util.exportExcel(list, "直播触发事件配置数据");
+    }
+
+    /**
+     * 获取直播触发事件配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveEventConf:query')")
+    @GetMapping(value = "/{eventId}")
+    public AjaxResult getInfo(@PathVariable("eventId") Long eventId)
+    {
+        return AjaxResult.success(liveEventConfService.selectLiveEventConfByEventId(eventId));
+    }
+
+    /**
+     * 新增直播触发事件配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveEventConf:add')")
+    @Log(title = "直播触发事件配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveEventConf liveEventConf)
+    {
+        return toAjax(liveEventConfService.insertLiveEventConf(liveEventConf));
+    }
+
+    /**
+     * 修改直播触发事件配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveEventConf:edit')")
+    @Log(title = "直播触发事件配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveEventConf liveEventConf)
+    {
+        return toAjax(liveEventConfService.updateLiveEventConf(liveEventConf));
+    }
+
+    /**
+     * 删除直播触发事件配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveEventConf:remove')")
+    @Log(title = "直播触发事件配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{eventIds}")
+    public AjaxResult remove(@PathVariable Long[] eventIds)
+    {
+        return toAjax(liveEventConfService.deleteLiveEventConfByEventIds(eventIds));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveGiftController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveGift;
+import com.fs.live.service.ILiveGiftService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播间礼物配置Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/gift")
+public class LiveGiftController extends BaseController
+{
+    @Autowired
+    private ILiveGiftService liveGiftService;
+
+    /**
+     * 查询直播间礼物配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveGift liveGift)
+    {
+        startPage();
+        List<LiveGift> list = liveGiftService.selectLiveGiftList(liveGift);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播间礼物配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:export')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveGift liveGift)
+    {
+        List<LiveGift> list = liveGiftService.selectLiveGiftList(liveGift);
+        ExcelUtil<LiveGift> util = new ExcelUtil<LiveGift>(LiveGift.class);
+        return util.exportExcel(list, "直播间礼物配置数据");
+    }
+
+    /**
+     * 获取直播间礼物配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:query')")
+    @GetMapping(value = "/{giftId}")
+    public AjaxResult getInfo(@PathVariable("giftId") Long giftId)
+    {
+        return AjaxResult.success(liveGiftService.selectLiveGiftByGiftId(giftId));
+    }
+
+    /**
+     * 新增直播间礼物配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:add')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveGift liveGift)
+    {
+        return toAjax(liveGiftService.insertLiveGift(liveGift));
+    }
+
+    /**
+     * 修改直播间礼物配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:edit')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveGift liveGift)
+    {
+        return toAjax(liveGiftService.updateLiveGift(liveGift));
+    }
+
+    /**
+     * 删除直播间礼物配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:remove')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{giftIds}")
+    public AjaxResult remove(@PathVariable Long[] giftIds)
+    {
+        return toAjax(liveGiftService.deleteLiveGiftByGiftIds(giftIds));
+    }
+}

+ 87 - 23
fs-admin/src/main/java/com/fs/live/controller/LiveGoodsController.java

@@ -1,30 +1,33 @@
 package com.fs.live.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.entity.SysUser;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.SecurityUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.service.ICompanyUserService;
 import com.fs.live.domain.LiveGoods;
 import com.fs.live.service.ILiveGoodsService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import com.fs.live.vo.LiveGoodsListVo;
+import com.fs.live.vo.LiveGoodsVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * 直播商品Controller
- * 
+ *
  * @author fs
- * @date 2025-01-17
+ * @date 2025-07-08
  */
 @RestController
 @RequestMapping("/live/liveGoods")
@@ -33,15 +36,22 @@ public class LiveGoodsController extends BaseController
     @Autowired
     private ILiveGoodsService liveGoodsService;
 
+    @Autowired
+    private ICompanyUserService companyUserService;
+
     /**
      * 查询直播商品列表
      */
     @PreAuthorize("@ss.hasPermi('live:liveGoods:list')")
     @GetMapping("/list")
-    public TableDataInfo list(LiveGoods liveGoods)
+    public TableDataInfo list(LiveGoods liveGoods, @RequestParam(value = "liveId", required = true) Long liveId)
     {
+        // 设置企业ID和企业用户ID
+        setCompanyId(liveGoods);
+        liveGoods.setLiveId(liveId);
+
         startPage();
-        List<LiveGoods> list = liveGoodsService.selectLiveGoodsList(liveGoods);
+        List<LiveGoodsVo> list = liveGoodsService.selectProductListByLiveId(liveGoods);
         return getDataTable(list);
     }
 
@@ -53,6 +63,9 @@ public class LiveGoodsController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(LiveGoods liveGoods)
     {
+        // 设置企业ID和企业用户ID
+        setCompanyId(liveGoods);
+
         List<LiveGoods> list = liveGoodsService.selectLiveGoodsList(liveGoods);
         ExcelUtil<LiveGoods> util = new ExcelUtil<LiveGoods>(LiveGoods.class);
         return util.exportExcel(list, "直播商品数据");
@@ -65,7 +78,8 @@ public class LiveGoodsController extends BaseController
     @GetMapping(value = "/{goodsId}")
     public AjaxResult getInfo(@PathVariable("goodsId") Long goodsId)
     {
-        return AjaxResult.success(liveGoodsService.selectLiveGoodsByGoodsId(goodsId));
+        //CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        return AjaxResult.success();
     }
 
     /**
@@ -74,9 +88,12 @@ public class LiveGoodsController extends BaseController
     @PreAuthorize("@ss.hasPermi('live:liveGoods:add')")
     @Log(title = "直播商品", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody LiveGoods liveGoods)
+    public AjaxResult add(@RequestBody Map<String, Object> payload)
     {
-        return toAjax(liveGoodsService.insertLiveGoods(liveGoods));
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        //CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
+        SysUser user = loginUser.getUser();
+        return toAjax(liveGoodsService.insertLiveGoodsAdmin(payload, user));
     }
 
     /**
@@ -85,9 +102,9 @@ public class LiveGoodsController extends BaseController
     @PreAuthorize("@ss.hasPermi('live:liveGoods:edit')")
     @Log(title = "直播商品", businessType = BusinessType.UPDATE)
     @PutMapping
-    public AjaxResult edit(@RequestBody LiveGoods liveGoods)
+    public R edit(@RequestBody LiveGoods liveGoods)
     {
-        return toAjax(liveGoodsService.updateLiveGoods(liveGoods));
+        return liveGoodsService.updateLiveGoods(liveGoods);
     }
 
     /**
@@ -95,9 +112,56 @@ public class LiveGoodsController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('live:liveGoods:remove')")
     @Log(title = "直播商品", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{goodsIds}")
+    @DeleteMapping("/{goodsIds}")
     public AjaxResult remove(@PathVariable Long[] goodsIds)
     {
         return toAjax(liveGoodsService.deleteLiveGoodsByGoodsIds(goodsIds));
     }
+
+    /**
+     * 设置企业ID 企业用户ID
+     * @param liveGoods 直播商品
+     */
+    private void setCompanyId(LiveGoods liveGoods) {
+        // 设置企业ID 企业用户ID
+        //LoginUser loginUser = SecurityUtils.getLoginUser();
+        //CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
+        //liveGoods.setCompanyId(companyUser.getCompanyId());
+        //liveGoods.setCompanyUserId(companyUser.getUserId());
+    }
+
+
+
+    /**
+     * 获取直播店铺
+     * */
+    @GetMapping("/liveStore/{liveId}")
+    public R liveGoodsStore(@PathVariable Long liveId,@RequestParam String key)
+    {
+        return liveGoodsService.getStoreByLiveId(liveId, key);
+    }
+
+    /**
+     * 批量上下架视频
+     */
+    @PostMapping("/handleShelfOrUn")
+    public R handleShelfOrUn(@RequestBody LiveGoodsListVo listVo) {
+        return liveGoodsService.handleShelfOrUnAdmin(listVo);
+    }
+
+    /**
+     * 批量删除视频
+     */
+    @PostMapping("/handleDeleteSelected")
+    public R handleDeleteSelected(@RequestBody LiveGoodsListVo listVo) {
+        return liveGoodsService.handleDeleteSelectedAdmin(listVo);
+    }
+
+    /**
+     * 更新展示状态
+     */
+    @PostMapping("/handleIsShowChange")
+    public R handleIsShowChange(@RequestBody LiveGoodsListVo listVo) {
+        return liveGoodsService.handleIsShowChange(listVo);
+    }
 }

+ 0 - 103
fs-admin/src/main/java/com/fs/live/controller/LiveGoodsOrderController.java

@@ -1,103 +0,0 @@
-package com.fs.live.controller;
-
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.live.domain.LiveGoodsOrder;
-import com.fs.live.service.ILiveGoodsOrderService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
-
-/**
- * 订单Controller
- * 
- * @author fs
- * @date 2025-01-17
- */
-@RestController
-@RequestMapping("/live/liveOrder")
-public class LiveGoodsOrderController extends BaseController
-{
-    @Autowired
-    private ILiveGoodsOrderService liveGoodsOrderService;
-
-    /**
-     * 查询订单列表
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrder:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(LiveGoodsOrder liveGoodsOrder)
-    {
-        startPage();
-        List<LiveGoodsOrder> list = liveGoodsOrderService.selectLiveGoodsOrderList(liveGoodsOrder);
-        return getDataTable(list);
-    }
-
-    /**
-     * 导出订单列表
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrder:export')")
-    @Log(title = "订单", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public AjaxResult export(LiveGoodsOrder liveGoodsOrder)
-    {
-        List<LiveGoodsOrder> list = liveGoodsOrderService.selectLiveGoodsOrderList(liveGoodsOrder);
-        ExcelUtil<LiveGoodsOrder> util = new ExcelUtil<LiveGoodsOrder>(LiveGoodsOrder.class);
-        return util.exportExcel(list, "订单数据");
-    }
-
-    /**
-     * 获取订单详细信息
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrder:query')")
-    @GetMapping(value = "/{orderId}")
-    public AjaxResult getInfo(@PathVariable("orderId") Long orderId)
-    {
-        return AjaxResult.success(liveGoodsOrderService.selectLiveGoodsOrderByOrderId(orderId));
-    }
-
-    /**
-     * 新增订单
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrder:add')")
-    @Log(title = "订单", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody LiveGoodsOrder liveGoodsOrder)
-    {
-        return toAjax(liveGoodsOrderService.insertLiveGoodsOrder(liveGoodsOrder));
-    }
-
-    /**
-     * 修改订单
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrder:edit')")
-    @Log(title = "订单", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody LiveGoodsOrder liveGoodsOrder)
-    {
-        return toAjax(liveGoodsOrderService.updateLiveGoodsOrder(liveGoodsOrder));
-    }
-
-    /**
-     * 删除订单
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrder:remove')")
-    @Log(title = "订单", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{orderIds}")
-    public AjaxResult remove(@PathVariable Long[] orderIds)
-    {
-        return toAjax(liveGoodsOrderService.deleteLiveGoodsOrderByOrderIds(orderIds));
-    }
-}

+ 0 - 103
fs-admin/src/main/java/com/fs/live/controller/LiveGoodsOrderItemsController.java

@@ -1,103 +0,0 @@
-package com.fs.live.controller;
-
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.live.domain.LiveGoodsOrderItems;
-import com.fs.live.service.ILiveGoodsOrderItemsService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
-
-/**
- * 订单商品Controller
- * 
- * @author fs
- * @date 2025-01-17
- */
-@RestController
-@RequestMapping("/live/liveOrderitems")
-public class LiveGoodsOrderItemsController extends BaseController
-{
-    @Autowired
-    private ILiveGoodsOrderItemsService liveGoodsOrderItemsService;
-
-    /**
-     * 查询订单商品列表
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrderitems:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(LiveGoodsOrderItems liveGoodsOrderItems)
-    {
-        startPage();
-        List<LiveGoodsOrderItems> list = liveGoodsOrderItemsService.selectLiveGoodsOrderItemsList(liveGoodsOrderItems);
-        return getDataTable(list);
-    }
-
-    /**
-     * 导出订单商品列表
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrderitems:export')")
-    @Log(title = "订单商品", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public AjaxResult export(LiveGoodsOrderItems liveGoodsOrderItems)
-    {
-        List<LiveGoodsOrderItems> list = liveGoodsOrderItemsService.selectLiveGoodsOrderItemsList(liveGoodsOrderItems);
-        ExcelUtil<LiveGoodsOrderItems> util = new ExcelUtil<LiveGoodsOrderItems>(LiveGoodsOrderItems.class);
-        return util.exportExcel(list, "订单商品数据");
-    }
-
-    /**
-     * 获取订单商品详细信息
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrderitems:query')")
-    @GetMapping(value = "/{id}")
-    public AjaxResult getInfo(@PathVariable("id") Long id)
-    {
-        return AjaxResult.success(liveGoodsOrderItemsService.selectLiveGoodsOrderItemsById(id));
-    }
-
-    /**
-     * 新增订单商品
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrderitems:add')")
-    @Log(title = "订单商品", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody LiveGoodsOrderItems liveGoodsOrderItems)
-    {
-        return toAjax(liveGoodsOrderItemsService.insertLiveGoodsOrderItems(liveGoodsOrderItems));
-    }
-
-    /**
-     * 修改订单商品
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrderitems:edit')")
-    @Log(title = "订单商品", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody LiveGoodsOrderItems liveGoodsOrderItems)
-    {
-        return toAjax(liveGoodsOrderItemsService.updateLiveGoodsOrderItems(liveGoodsOrderItems));
-    }
-
-    /**
-     * 删除订单商品
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveOrderitems:remove')")
-    @Log(title = "订单商品", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{ids}")
-    public AjaxResult remove(@PathVariable Long[] ids)
-    {
-        return toAjax(liveGoodsOrderItemsService.deleteLiveGoodsOrderItemsByIds(ids));
-    }
-}

+ 141 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveLotteryConfController.java

@@ -0,0 +1,141 @@
+package com.fs.live.controller;
+
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.live.param.LiveLotteryProductSaveParam;
+import com.fs.live.vo.LiveLotteryProductVO;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveLotteryConf;
+import com.fs.live.service.ILiveLotteryConfService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播抽奖配置Controller
+ *
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveLotteryConf")
+public class LiveLotteryConfController extends BaseController
+{
+    @Autowired
+    private ILiveLotteryConfService liveLotteryConfService;
+
+    /**
+     * 查询直播抽奖配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveLotteryConf liveLotteryConf)
+    {
+        startPage();
+        List<LiveLotteryConf> list = liveLotteryConfService.selectLiveLotteryConfList(liveLotteryConf);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播抽奖配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:export')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveLotteryConf liveLotteryConf)
+    {
+        List<LiveLotteryConf> list = liveLotteryConfService.selectLiveLotteryConfList(liveLotteryConf);
+        ExcelUtil<LiveLotteryConf> util = new ExcelUtil<LiveLotteryConf>(LiveLotteryConf.class);
+        return util.exportExcel(list, "直播抽奖配置数据");
+    }
+
+    /**
+     * 获取直播抽奖配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:query')")
+    @GetMapping(value = "/{lotteryId}")
+    public AjaxResult getInfo(@PathVariable("lotteryId") Long lotteryId)
+    {
+        return AjaxResult.success(liveLotteryConfService.selectLiveLotteryConfByLotteryId(lotteryId));
+    }
+
+    /**
+     * 新增直播抽奖配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:add')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveLotteryConf liveLotteryConf)
+    {
+        return toAjax(liveLotteryConfService.insertLiveLotteryConf(liveLotteryConf));
+    }
+
+    /**
+     * 修改直播抽奖配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:edit')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody LiveLotteryConf liveLotteryConf)
+    {
+        return liveLotteryConfService.updateLiveLotteryConf(liveLotteryConf);
+    }
+
+    /**
+     * 删除直播抽奖配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:remove')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{lotteryIds}")
+    public AjaxResult remove(@PathVariable Long[] lotteryIds)
+    {
+        return toAjax(liveLotteryConfService.deleteLiveLotteryConfByLotteryIds(lotteryIds));
+    }
+
+
+    @GetMapping("/live/{liveId}")
+    public List<LiveLotteryConf> getByLiveId(@PathVariable Long liveId) {
+        return liveLotteryConfService.getByLiveId(liveId);
+    }
+
+
+    @DeleteMapping("/{id}")
+    public void delete(@PathVariable Long id) {
+        liveLotteryConfService.delete(id);
+    }
+
+    /**
+     * 发起抽奖
+     * */
+    @GetMapping("/start/{lotteryId}")
+    public String  start(@PathVariable Long lotteryId) {
+       return liveLotteryConfService.startLottery(lotteryId,getUserId());
+    }
+
+    /** 查询抽奖配置的所有商品信息*/
+    @GetMapping("/getGoods/{lotteryId}")
+    public R getGoods(@PathVariable Long lotteryId) {
+        return R.ok().put("data",liveLotteryConfService.getGoods(lotteryId));
+    }
+
+    /** 抽奖商品配置保存*/
+    @PostMapping("/product")
+    public void saveGoods(@RequestBody LiveLotteryProductSaveParam liveLotteryProducts) {
+        //liveLotteryProducts.setCreateBy(getUsername());
+        liveLotteryConfService.saveProducts(liveLotteryProducts);
+    }
+
+}

+ 4 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveLotteryController.java

@@ -0,0 +1,4 @@
+package com.fs.live.controller;
+
+public class LiveLotteryController {
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveLotteryRecordController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveLotteryRecord;
+import com.fs.live.service.ILiveLotteryRecordService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播抽奖记录Controller
+ * 
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveLotteryRecord")
+public class LiveLotteryRecordController extends BaseController
+{
+    @Autowired
+    private ILiveLotteryRecordService liveLotteryRecordService;
+
+    /**
+     * 查询直播抽奖记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveLotteryRecord liveLotteryRecord)
+    {
+        startPage();
+        List<LiveLotteryRecord> list = liveLotteryRecordService.selectLiveLotteryRecordList(liveLotteryRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播抽奖记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:export')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveLotteryRecord liveLotteryRecord)
+    {
+        List<LiveLotteryRecord> list = liveLotteryRecordService.selectLiveLotteryRecordList(liveLotteryRecord);
+        ExcelUtil<LiveLotteryRecord> util = new ExcelUtil<LiveLotteryRecord>(LiveLotteryRecord.class);
+        return util.exportExcel(list, "直播抽奖记录数据");
+    }
+
+    /**
+     * 获取直播抽奖记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:query')")
+    @GetMapping(value = "/{lotteryId}")
+    public AjaxResult getInfo(@PathVariable("lotteryId") Long lotteryId)
+    {
+        return AjaxResult.success(liveLotteryRecordService.selectLiveLotteryRecordByLotteryId(lotteryId));
+    }
+
+    /**
+     * 新增直播抽奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:add')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveLotteryRecord liveLotteryRecord)
+    {
+        return toAjax(liveLotteryRecordService.insertLiveLotteryRecord(liveLotteryRecord));
+    }
+
+    /**
+     * 修改直播抽奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:edit')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveLotteryRecord liveLotteryRecord)
+    {
+        return toAjax(liveLotteryRecordService.updateLiveLotteryRecord(liveLotteryRecord));
+    }
+
+    /**
+     * 删除直播抽奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:remove')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{lotteryIds}")
+    public AjaxResult remove(@PathVariable Long[] lotteryIds)
+    {
+        return toAjax(liveLotteryRecordService.deleteLiveLotteryRecordByLotteryIds(lotteryIds));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveLotteryRegistrationController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveLotteryRegistration;
+import com.fs.live.service.ILiveLotteryRegistrationService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播抽奖登记Controller
+ * 
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveLotteryRegistration")
+public class LiveLotteryRegistrationController extends BaseController
+{
+    @Autowired
+    private ILiveLotteryRegistrationService liveLotteryRegistrationService;
+
+    /**
+     * 查询直播抽奖登记列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveLotteryRegistration liveLotteryRegistration)
+    {
+        startPage();
+        List<LiveLotteryRegistration> list = liveLotteryRegistrationService.selectLiveLotteryRegistrationList(liveLotteryRegistration);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播抽奖登记列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:export')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveLotteryRegistration liveLotteryRegistration)
+    {
+        List<LiveLotteryRegistration> list = liveLotteryRegistrationService.selectLiveLotteryRegistrationList(liveLotteryRegistration);
+        ExcelUtil<LiveLotteryRegistration> util = new ExcelUtil<LiveLotteryRegistration>(LiveLotteryRegistration.class);
+        return util.exportExcel(list, "直播抽奖登记数据");
+    }
+
+    /**
+     * 获取直播抽奖登记详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:query')")
+    @GetMapping(value = "/{registrationId}")
+    public AjaxResult getInfo(@PathVariable("registrationId") Long registrationId)
+    {
+        return AjaxResult.success(liveLotteryRegistrationService.selectLiveLotteryRegistrationByRegistrationId(registrationId));
+    }
+
+    /**
+     * 新增直播抽奖登记
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:add')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveLotteryRegistration liveLotteryRegistration)
+    {
+        return toAjax(liveLotteryRegistrationService.insertLiveLotteryRegistration(liveLotteryRegistration));
+    }
+
+    /**
+     * 修改直播抽奖登记
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:edit')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveLotteryRegistration liveLotteryRegistration)
+    {
+        return toAjax(liveLotteryRegistrationService.updateLiveLotteryRegistration(liveLotteryRegistration));
+    }
+
+    /**
+     * 删除直播抽奖登记
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:remove')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{registrationIds}")
+    public AjaxResult remove(@PathVariable Long[] registrationIds)
+    {
+        return toAjax(liveLotteryRegistrationService.deleteLiveLotteryRegistrationByRegistrationIds(registrationIds));
+    }
+}

+ 9 - 15
fs-admin/src/main/java/com/fs/live/controller/LiveMsgController.java

@@ -1,28 +1,22 @@
-package com.fs.live.controller;
+package com.fs.live.controller.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.live.domain.LiveMsg;
 import com.fs.live.service.ILiveMsgService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 直播讨论Controller
- * 
+ *
  * @author fs
  * @date 2025-01-17
  */

+ 268 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java

@@ -0,0 +1,268 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import java.util.Map;
+
+import cn.hutool.core.util.StrUtil;
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.StringUtils;
+import com.fs.erp.domain.ErpDeliverys;
+import com.fs.erp.domain.ErpOrderQuery;
+import com.fs.erp.dto.ErpOrderQueryRequert;
+import com.fs.erp.dto.ErpOrderQueryResponse;
+import com.fs.erp.service.IErpOrderService;
+import com.fs.his.config.FsSysConfig;
+import com.fs.his.domain.FsStoreOrder;
+import com.fs.his.dto.ExpressInfoDTO;
+import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.service.IFsExpressService;
+import com.fs.his.utils.ConfigUtil;
+import com.fs.live.enums.LiveOrderCancleReason;
+import com.fs.live.vo.LiveGoodsVo;
+import com.fs.live.vo.LiveOrderVo;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+import static com.fs.his.utils.PhoneUtil.decryptPhone;
+
+/**
+ * 订单Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrder")
+public class LiveOrderController extends BaseController
+{
+    @Autowired
+    private ILiveOrderService liveOrderService;
+
+
+    @Autowired
+    private IFsExpressService expressService;
+
+    @Autowired
+    private ConfigUtil configUtil;
+
+    @Autowired
+    @Qualifier("erpOrderServiceImpl")
+    private IErpOrderService gyOrderService;
+
+    @Autowired
+    @Qualifier("wdtErpOrderServiceImpl")
+    private IErpOrderService wdtOrderService;
+
+    /**
+     * 查询订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrder liveOrder)
+    {
+        startPage();
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:export')")
+    @Log(title = "订单", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrder liveOrder)
+    {
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        ExcelUtil<LiveOrder> util = new ExcelUtil<LiveOrder>(LiveOrder.class);
+        return util.exportExcel(list, "订单数据");
+    }
+
+    /**
+     * 获取订单详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:query')")
+    @GetMapping(value = "/info/{orderId}")
+    public AjaxResult getInfo(@PathVariable("orderId") String orderId)
+    {
+        return AjaxResult.success(liveOrderService.selectLiveOrderByOrderId(orderId));
+    }
+
+
+    /**
+     * 新增订单
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:add')")
+    @Log(title = "订单", businessType = BusinessType.INSERT)
+    @PostMapping("/create")
+    public R add(@RequestBody LiveOrder liveOrder)
+    {
+        return R.ok().put("data", liveOrderService.insertLiveOrder(liveOrder));
+    }
+
+    /**
+     * 修改订单
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:edit')")
+    @Log(title = "订单", businessType = BusinessType.UPDATE)
+    @PutMapping("/update")
+    public AjaxResult edit(@RequestBody LiveOrder liveOrder)
+    {
+        return toAjax(liveOrderService.updateLiveOrder(liveOrder));
+    }
+
+
+    /**
+     * 查看物流状态
+     * */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:express')")
+    @GetMapping(value = "/getExpress/{id}")
+    public R getExpress(@PathVariable("id") String id)
+    {
+        LiveOrder order=liveOrderService.selectLiveOrderByOrderId(id);
+        ExpressInfoDTO expressInfoDTO=null;
+        if(StringUtils.isNotEmpty(order.getDeliverySn())){
+            String lastFourNumber = "";
+            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+
+                lastFourNumber = order.getUserPhone();
+                if (lastFourNumber.length() == 11) {
+                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                }else if (lastFourNumber.length()>11){
+                    String jm = decryptPhone(lastFourNumber);
+                    lastFourNumber = StrUtil.sub(jm, jm.length(), -4);
+                }
+            }
+            expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            if((expressInfoDTO.getStateEx()!=null&&expressInfoDTO.getStateEx().equals("0"))&&(expressInfoDTO.getState()!=null&&expressInfoDTO.getState().equals("0"))){
+                lastFourNumber = "19923690275";
+                if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+                    if (lastFourNumber.length() == 11) {
+                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                    }
+                }
+
+                expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            }
+        }
+        return R.ok().put("data",expressInfoDTO);
+    }
+
+    /**
+     * 支付订单
+     * */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:pay')")
+    @PostMapping(value = "/pay")
+    public void pay(LiveOrder liveOrder)
+    {
+       liveOrderService.handlePay(liveOrder);
+    }
+
+    /**
+     * 取消订单确认
+     * */
+    @GetMapping(value = "/cancelConfirm/{orderId}")
+    public R cancelConfirm(@PathVariable String orderId)
+    {
+        LiveOrder byId = liveOrderService.getById(orderId);
+        List<Map<String, String>> allCodeDescMap = LiveOrderCancleReason.getAllCodeDescMap();
+        return R.ok().put("reason",allCodeDescMap).put("data",byId);
+    }
+
+    /**
+     * 按照时间粒度返回订单
+     * */
+    @GetMapping(value = "/getLiveOrderTimeGranularity")
+    public R getLiveOrderTimeGranularity(LiveOrderVo liveOrder){
+        return liveOrderService.getLiveOrderTimeGranularity(liveOrder);
+    }
+
+    @Log(title = "同步物流", businessType = BusinessType.UPDATE)
+    @GetMapping(value = "/syncExpress/{id}")
+    public R syncExpress(@PathVariable("id") Long id) {
+        return liveOrderService.syncExpress(id);
+    }
+
+    @Log(title = "同步管易物流单号", businessType = BusinessType.UPDATE)
+    @PreAuthorize("@ss.hasPermi('store:storeOrder:updateErpOrder')")
+    @PostMapping("/updateErpOrder")
+    public R updateErpOrder( @RequestBody LiveOrder param) {
+        LiveOrder order = liveOrderService.selectLiveOrderByOrderId(String.valueOf(param.getOrderId()));
+        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+        IErpOrderService erpOrderService = getErpService();
+        request.setCode(order.getExtendOrderId());
+        ErpOrderQueryResponse response = erpOrderService.getOrder(request);
+        if(response.getOrders()!=null&&response.getOrders().size()>0){
+            for(ErpOrderQuery orderQuery : response.getOrders()){
+                if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
+                    for(ErpDeliverys delivery:orderQuery.getDeliverys()){
+                        if(delivery.getDelivery()&& StringUtils.isNotEmpty(delivery.getMail_no())){
+                            //更新商订单状态
+                            liveOrderService.updateDeliveryOrder(param.getOrderId(), delivery.getMail_no(),delivery.getExpress_code(),delivery.getExpress_name());
+                            return R.ok();
+                        }
+                    }
+
+                }
+            }
+        }
+        return R.error("未查询到快递信息");
+    }
+    private IErpOrderService getErpService() {
+        FsSysConfig sysConfig = configUtil.getSysConfig();
+        Integer erpOpen = sysConfig.getErpOpen();
+        if (erpOpen != null && erpOpen == 1){
+            //判断erp类型
+            Integer erpType = sysConfig.getErpType();
+            if (erpType != null){
+                IErpOrderService erpOrderService = null;
+                if (erpType == 1){
+                    //管易
+                    erpOrderService =  gyOrderService;
+                } else if (erpType == 2){
+                    //旺店通
+                    erpOrderService =  wdtOrderService;
+                }
+                return erpOrderService;
+
+
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 查询订单商品列表
+     */
+
+    @GetMapping("/ltemlist/{orderId}")
+    public TableDataInfo ltemlist(@PathVariable("orderId") String orderId)
+    {
+        List<LiveGoodsVo> list = liveOrderService.selectLiveOrderItemList(orderId);
+        return getDataTable(list);
+    }
+
+
+
+
+
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveOrderItemController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.service.ILiveOrderItemService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 订单详情Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrderItem")
+public class LiveOrderItemController extends BaseController
+{
+    @Autowired
+    private ILiveOrderItemService liveOrderItemService;
+
+    /**
+     * 查询订单详情列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrderItem liveOrderItem)
+    {
+        startPage();
+        List<LiveOrderItem> list = liveOrderItemService.selectLiveOrderItemList(liveOrderItem);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单详情列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:export')")
+    @Log(title = "订单详情", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrderItem liveOrderItem)
+    {
+        List<LiveOrderItem> list = liveOrderItemService.selectLiveOrderItemList(liveOrderItem);
+        ExcelUtil<LiveOrderItem> util = new ExcelUtil<LiveOrderItem>(LiveOrderItem.class);
+        return util.exportExcel(list, "订单详情数据");
+    }
+
+    /**
+     * 获取订单详情详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:query')")
+    @GetMapping(value = "/{itemId}")
+    public AjaxResult getInfo(@PathVariable("itemId") String itemId)
+    {
+        return AjaxResult.success(liveOrderItemService.selectLiveOrderItemByItemId(itemId));
+    }
+
+    /**
+     * 新增订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:add')")
+    @Log(title = "订单详情", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveOrderItem liveOrderItem)
+    {
+        return toAjax(liveOrderItemService.insertLiveOrderItem(liveOrderItem));
+    }
+
+    /**
+     * 修改订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:edit')")
+    @Log(title = "订单详情", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveOrderItem liveOrderItem)
+    {
+        return toAjax(liveOrderItemService.updateLiveOrderItem(liveOrderItem));
+    }
+
+    /**
+     * 删除订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:remove')")
+    @Log(title = "订单详情", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{itemIds}")
+    public AjaxResult remove(@PathVariable String[] itemIds)
+    {
+        return toAjax(liveOrderItemService.deleteLiveOrderItemByItemIds(itemIds));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveOrderLogsController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveOrderLogs;
+import com.fs.live.service.ILiveOrderLogsService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 订单操作记录Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrderLogs")
+public class LiveOrderLogsController extends BaseController
+{
+    @Autowired
+    private ILiveOrderLogsService liveOrderLogsService;
+
+    /**
+     * 查询订单操作记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrderLogs liveOrderLogs)
+    {
+        startPage();
+        List<LiveOrderLogs> list = liveOrderLogsService.selectLiveOrderLogsList(liveOrderLogs);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单操作记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:export')")
+    @Log(title = "订单操作记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrderLogs liveOrderLogs)
+    {
+        List<LiveOrderLogs> list = liveOrderLogsService.selectLiveOrderLogsList(liveOrderLogs);
+        ExcelUtil<LiveOrderLogs> util = new ExcelUtil<LiveOrderLogs>(LiveOrderLogs.class);
+        return util.exportExcel(list, "订单操作记录数据");
+    }
+
+    /**
+     * 获取订单操作记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:query')")
+    @GetMapping(value = "/{logsId}")
+    public AjaxResult getInfo(@PathVariable("logsId") String logsId)
+    {
+        return AjaxResult.success(liveOrderLogsService.selectLiveOrderLogsByLogsId(logsId));
+    }
+
+    /**
+     * 新增订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:add')")
+    @Log(title = "订单操作记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveOrderLogs liveOrderLogs)
+    {
+        return toAjax(liveOrderLogsService.insertLiveOrderLogs(liveOrderLogs));
+    }
+
+    /**
+     * 修改订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:edit')")
+    @Log(title = "订单操作记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveOrderLogs liveOrderLogs)
+    {
+        return toAjax(liveOrderLogsService.updateLiveOrderLogs(liveOrderLogs));
+    }
+
+    /**
+     * 删除订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:remove')")
+    @Log(title = "订单操作记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{logsIds}")
+    public AjaxResult remove(@PathVariable String[] logsIds)
+    {
+        return toAjax(liveOrderLogsService.deleteLiveOrderLogsByLogsIds(logsIds));
+    }
+}

+ 0 - 103
fs-admin/src/main/java/com/fs/live/controller/LiveQuestionController.java

@@ -1,103 +0,0 @@
-package com.fs.live.controller;
-
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.live.domain.LiveQuestion;
-import com.fs.live.service.ILiveQuestionService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
-
-/**
- * 问答Controller
- * 
- * @author fs
- * @date 2025-01-17
- */
-@RestController
-@RequestMapping("/live/liveQuestion")
-public class LiveQuestionController extends BaseController
-{
-    @Autowired
-    private ILiveQuestionService liveQuestionService;
-
-    /**
-     * 查询问答列表
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveQuestion:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(LiveQuestion liveQuestion)
-    {
-        startPage();
-        List<LiveQuestion> list = liveQuestionService.selectLiveQuestionList(liveQuestion);
-        return getDataTable(list);
-    }
-
-    /**
-     * 导出问答列表
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveQuestion:export')")
-    @Log(title = "问答", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public AjaxResult export(LiveQuestion liveQuestion)
-    {
-        List<LiveQuestion> list = liveQuestionService.selectLiveQuestionList(liveQuestion);
-        ExcelUtil<LiveQuestion> util = new ExcelUtil<LiveQuestion>(LiveQuestion.class);
-        return util.exportExcel(list, "问答数据");
-    }
-
-    /**
-     * 获取问答详细信息
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveQuestion:query')")
-    @GetMapping(value = "/{questionId}")
-    public AjaxResult getInfo(@PathVariable("questionId") Long questionId)
-    {
-        return AjaxResult.success(liveQuestionService.selectLiveQuestionByQuestionId(questionId));
-    }
-
-    /**
-     * 新增问答
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveQuestion:add')")
-    @Log(title = "问答", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody LiveQuestion liveQuestion)
-    {
-        return toAjax(liveQuestionService.insertLiveQuestion(liveQuestion));
-    }
-
-    /**
-     * 修改问答
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveQuestion:edit')")
-    @Log(title = "问答", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody LiveQuestion liveQuestion)
-    {
-        return toAjax(liveQuestionService.updateLiveQuestion(liveQuestion));
-    }
-
-    /**
-     * 删除问答
-     */
-    @PreAuthorize("@ss.hasPermi('live:liveQuestion:remove')")
-    @Log(title = "问答", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{questionIds}")
-    public AjaxResult remove(@PathVariable Long[] questionIds)
-    {
-        return toAjax(liveQuestionService.deleteLiveQuestionByQuestionIds(questionIds));
-    }
-}

+ 116 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveRedConfController.java

@@ -0,0 +1,116 @@
+package com.fs.live.controller;
+
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.live.param.RedPO;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveRedConf;
+import com.fs.live.service.ILiveRedConfService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播红包记录配置Controller
+ *
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveRedConf")
+public class LiveRedConfController extends BaseController
+{
+    @Autowired
+    private ILiveRedConfService liveRedConfService;
+
+    /**
+     * 查询直播红包记录配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveRedConf liveRedConf)
+    {
+        startPage();
+        List<LiveRedConf> list = liveRedConfService.selectLiveRedConfList(liveRedConf);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播红包记录配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:export')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveRedConf liveRedConf)
+    {
+        List<LiveRedConf> list = liveRedConfService.selectLiveRedConfList(liveRedConf);
+        ExcelUtil<LiveRedConf> util = new ExcelUtil<LiveRedConf>(LiveRedConf.class);
+        return util.exportExcel(list, "直播红包记录配置数据");
+    }
+
+    /**
+     * 获取直播红包记录配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:query')")
+    @GetMapping(value = "/{redId}")
+    public AjaxResult getInfo(@PathVariable("redId") Long redId)
+    {
+        return AjaxResult.success(liveRedConfService.selectLiveRedConfByRedId(redId));
+    }
+
+    /**
+     * 新增直播红包记录配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:add')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveRedConf liveRedConf)
+    {
+        return toAjax(liveRedConfService.insertLiveRedConf(liveRedConf));
+    }
+
+    /**
+     * 修改直播红包记录配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:edit')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody LiveRedConf liveRedConf)
+    {
+        liveRedConfService.updateLiveRedConf(liveRedConf);
+        return R.ok(liveRedConf.getRedStatus().toString());
+    }
+
+    /**
+     * 删除直播红包记录配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:remove')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{redIds}")
+    public AjaxResult remove(@PathVariable Long[] redIds)
+    {
+        return toAjax(liveRedConfService.deleteLiveRedConfByRedIds(redIds));
+    }
+
+    @GetMapping("/live/{liveId}")
+    public List<LiveRedConf> getByLiveId(@PathVariable Long liveId) {
+        return liveRedConfService.getByLiveId(liveId);
+    }
+
+    /**
+     * 点击发放红包
+     * */
+    @PostMapping("/start/{redId}")
+    public String start(@PathVariable String redId) {
+        return liveRedConfService.start(redId,getUserId());
+    }
+
+
+
+}

+ 4 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveRedController.java

@@ -0,0 +1,4 @@
+package com.fs.live.controller;
+
+public class LiveRedController {
+}

+ 104 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveRewardRecordController.java

@@ -0,0 +1,104 @@
+package com.fs.live.controller;
+
+import java.util.List;
+
+import com.fs.live.domain.LiveRewardRecord;
+import com.fs.live.service.ILiveRewardRecordService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户直播间奖励记录Controller
+ *
+ * @author fs
+ * @date 2025-08-27
+ */
+@RestController
+@RequestMapping("/live/record")
+public class LiveRewardRecordController extends BaseController
+{
+    @Autowired
+    private ILiveRewardRecordService liveRewardRecordService;
+
+    /**
+     * 查询用户直播间奖励记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveRewardRecord liveRewardRecord)
+    {
+        startPage();
+        List<LiveRewardRecord> list = liveRewardRecordService.selectLiveRewardRecordList(liveRewardRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播间奖励记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:export')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveRewardRecord liveRewardRecord)
+    {
+        List<LiveRewardRecord> list = liveRewardRecordService.selectLiveRewardRecordList(liveRewardRecord);
+        ExcelUtil<LiveRewardRecord> util = new ExcelUtil<LiveRewardRecord>(LiveRewardRecord.class);
+        return util.exportExcel(list, "用户直播间奖励记录数据");
+    }
+
+    /**
+     * 获取用户直播间奖励记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveRewardRecordService.selectLiveRewardRecordById(id));
+    }
+
+    /**
+     * 新增用户直播间奖励记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:add')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveRewardRecord liveRewardRecord)
+    {
+        return toAjax(liveRewardRecordService.insertLiveRewardRecord(liveRewardRecord));
+    }
+
+    /**
+     * 修改用户直播间奖励记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:edit')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveRewardRecord liveRewardRecord)
+    {
+        return toAjax(liveRewardRecordService.updateLiveRewardRecord(liveRewardRecord));
+    }
+
+    /**
+     * 删除用户直播间奖励记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:remove')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveRewardRecordService.deleteLiveRewardRecordByIds(ids));
+    }
+}

+ 98 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveSensitiveWordsController.java

@@ -0,0 +1,98 @@
+package com.fs.live.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveSensitiveWords;
+import com.fs.live.service.ILiveSensitiveWordsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播间敏感词过滤Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/words")
+public class LiveSensitiveWordsController extends BaseController
+{
+    @Autowired
+    private ILiveSensitiveWordsService liveSensitiveWordsService;
+
+    /**
+     * 查询直播间敏感词过滤列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveSensitiveWords liveSensitiveWords)
+    {
+        startPage();
+        List<LiveSensitiveWords> list = liveSensitiveWordsService.selectLiveSensitiveWordsList(liveSensitiveWords);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播间敏感词过滤列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:export')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveSensitiveWords liveSensitiveWords)
+    {
+        List<LiveSensitiveWords> list = liveSensitiveWordsService.selectLiveSensitiveWordsList(liveSensitiveWords);
+        ExcelUtil<LiveSensitiveWords> util = new ExcelUtil<LiveSensitiveWords>(LiveSensitiveWords.class);
+        return util.exportExcel(list, "直播间敏感词过滤数据");
+    }
+
+    /**
+     * 获取直播间敏感词过滤详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:query')")
+    @GetMapping(value = "/{wordId}")
+    public AjaxResult getInfo(@PathVariable("wordId") Long wordId)
+    {
+        return AjaxResult.success(liveSensitiveWordsService.selectLiveSensitiveWordsByWordId(wordId));
+    }
+
+    /**
+     * 新增直播间敏感词过滤
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:add')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveSensitiveWords liveSensitiveWords)
+    {
+
+        return toAjax(liveSensitiveWordsService.insertLiveSensitiveWords(liveSensitiveWords));
+    }
+
+    /**
+     * 修改直播间敏感词过滤
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:edit')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveSensitiveWords liveSensitiveWords)
+    {
+        return toAjax(liveSensitiveWordsService.updateLiveSensitiveWords(liveSensitiveWords));
+    }
+
+    /**
+     * 删除直播间敏感词过滤
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:remove')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{wordIds}")
+    public AjaxResult remove(@PathVariable Long[] wordIds)
+    {
+        return toAjax(liveSensitiveWordsService.deleteLiveSensitiveWordsByWordIds(wordIds));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveUserFavoriteController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveUserFavorite;
+import com.fs.live.service.ILiveUserFavoriteService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户直播收藏Controller
+ * 
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/live/liveUserFavorite")
+public class LiveUserFavoriteController extends BaseController
+{
+    @Autowired
+    private ILiveUserFavoriteService liveUserFavoriteService;
+
+    /**
+     * 查询用户直播收藏列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFavorite liveUserFavorite)
+    {
+        startPage();
+        List<LiveUserFavorite> list = liveUserFavoriteService.selectLiveUserFavoriteList(liveUserFavorite);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播收藏列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:export')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFavorite liveUserFavorite)
+    {
+        List<LiveUserFavorite> list = liveUserFavoriteService.selectLiveUserFavoriteList(liveUserFavorite);
+        ExcelUtil<LiveUserFavorite> util = new ExcelUtil<LiveUserFavorite>(LiveUserFavorite.class);
+        return util.exportExcel(list, "用户直播收藏数据");
+    }
+
+    /**
+     * 获取用户直播收藏详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:query')")
+    @GetMapping(value = "/{favoriteId}")
+    public AjaxResult getInfo(@PathVariable("favoriteId") Long favoriteId)
+    {
+        return AjaxResult.success(liveUserFavoriteService.selectLiveUserFavoriteByFavoriteId(favoriteId));
+    }
+
+    /**
+     * 新增用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:add')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFavorite liveUserFavorite)
+    {
+        return toAjax(liveUserFavoriteService.insertLiveUserFavorite(liveUserFavorite));
+    }
+
+    /**
+     * 修改用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:edit')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFavorite liveUserFavorite)
+    {
+        return toAjax(liveUserFavoriteService.updateLiveUserFavorite(liveUserFavorite));
+    }
+
+    /**
+     * 删除用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:remove')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{favoriteIds}")
+    public AjaxResult remove(@PathVariable Long[] favoriteIds)
+    {
+        return toAjax(liveUserFavoriteService.deleteLiveUserFavoriteByFavoriteIds(favoriteIds));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveUserFollowController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveUserFollow;
+import com.fs.live.service.ILiveUserFollowService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户直播关注Controller
+ * 
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/live/liveUserFollow")
+public class LiveUserFollowController extends BaseController
+{
+    @Autowired
+    private ILiveUserFollowService liveUserFollowService;
+
+    /**
+     * 查询用户直播关注列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFollow liveUserFollow)
+    {
+        startPage();
+        List<LiveUserFollow> list = liveUserFollowService.selectLiveUserFollowList(liveUserFollow);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播关注列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:export')")
+    @Log(title = "用户直播关注", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFollow liveUserFollow)
+    {
+        List<LiveUserFollow> list = liveUserFollowService.selectLiveUserFollowList(liveUserFollow);
+        ExcelUtil<LiveUserFollow> util = new ExcelUtil<LiveUserFollow>(LiveUserFollow.class);
+        return util.exportExcel(list, "用户直播关注数据");
+    }
+
+    /**
+     * 获取用户直播关注详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserFollowService.selectLiveUserFollowById(id));
+    }
+
+    /**
+     * 新增用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:add')")
+    @Log(title = "用户直播关注", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFollow liveUserFollow)
+    {
+        return toAjax(liveUserFollowService.insertLiveUserFollow(liveUserFollow));
+    }
+
+    /**
+     * 修改用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:edit')")
+    @Log(title = "用户直播关注", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFollow liveUserFollow)
+    {
+        return toAjax(liveUserFollowService.updateLiveUserFollow(liveUserFollow));
+    }
+
+    /**
+     * 删除用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:remove')")
+    @Log(title = "用户直播关注", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserFollowService.deleteLiveUserFollowByIds(ids));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveUserLikeController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveUserLike;
+import com.fs.live.service.ILiveUserLikeService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户直播赞Controller
+ * 
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/live/liveUserLike")
+public class LiveUserLikeController extends BaseController
+{
+    @Autowired
+    private ILiveUserLikeService liveUserLikeService;
+
+    /**
+     * 查询用户直播赞列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserLike liveUserLike)
+    {
+        startPage();
+        List<LiveUserLike> list = liveUserLikeService.selectLiveUserLikeList(liveUserLike);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播赞列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:export')")
+    @Log(title = "用户直播赞", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserLike liveUserLike)
+    {
+        List<LiveUserLike> list = liveUserLikeService.selectLiveUserLikeList(liveUserLike);
+        ExcelUtil<LiveUserLike> util = new ExcelUtil<LiveUserLike>(LiveUserLike.class);
+        return util.exportExcel(list, "用户直播赞数据");
+    }
+
+    /**
+     * 获取用户直播赞详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserLikeService.selectLiveUserLikeById(id));
+    }
+
+    /**
+     * 新增用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:add')")
+    @Log(title = "用户直播赞", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserLike liveUserLike)
+    {
+        return toAjax(liveUserLikeService.insertLiveUserLike(liveUserLike));
+    }
+
+    /**
+     * 修改用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:edit')")
+    @Log(title = "用户直播赞", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserLike liveUserLike)
+    {
+        return toAjax(liveUserLikeService.updateLiveUserLike(liveUserLike));
+    }
+
+    /**
+     * 删除用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:remove')")
+    @Log(title = "用户直播赞", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserLikeService.deleteLiveUserLikeByIds(ids));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveUserLotteryRecordController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveUserLotteryRecord;
+import com.fs.live.service.ILiveUserLotteryRecordService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播用户中奖记录Controller
+ * 
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveUserLotteryRecord")
+public class LiveUserLotteryRecordController extends BaseController
+{
+    @Autowired
+    private ILiveUserLotteryRecordService liveUserLotteryRecordService;
+
+    /**
+     * 查询直播用户中奖记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLotteryRecord:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserLotteryRecord liveUserLotteryRecord)
+    {
+        startPage();
+        List<LiveUserLotteryRecord> list = liveUserLotteryRecordService.selectLiveUserLotteryRecordList(liveUserLotteryRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播用户中奖记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLotteryRecord:export')")
+    @Log(title = "直播用户中奖记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserLotteryRecord liveUserLotteryRecord)
+    {
+        List<LiveUserLotteryRecord> list = liveUserLotteryRecordService.selectLiveUserLotteryRecordList(liveUserLotteryRecord);
+        ExcelUtil<LiveUserLotteryRecord> util = new ExcelUtil<LiveUserLotteryRecord>(LiveUserLotteryRecord.class);
+        return util.exportExcel(list, "直播用户中奖记录数据");
+    }
+
+    /**
+     * 获取直播用户中奖记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLotteryRecord:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserLotteryRecordService.selectLiveUserLotteryRecordById(id));
+    }
+
+    /**
+     * 新增直播用户中奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLotteryRecord:add')")
+    @Log(title = "直播用户中奖记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserLotteryRecord liveUserLotteryRecord)
+    {
+        return toAjax(liveUserLotteryRecordService.insertLiveUserLotteryRecord(liveUserLotteryRecord));
+    }
+
+    /**
+     * 修改直播用户中奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLotteryRecord:edit')")
+    @Log(title = "直播用户中奖记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserLotteryRecord liveUserLotteryRecord)
+    {
+        return toAjax(liveUserLotteryRecordService.updateLiveUserLotteryRecord(liveUserLotteryRecord));
+    }
+
+    /**
+     * 删除直播用户中奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLotteryRecord:remove')")
+    @Log(title = "直播用户中奖记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserLotteryRecordService.deleteLiveUserLotteryRecordByIds(ids));
+    }
+}

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveUserRedRecordController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveUserRedRecord;
+import com.fs.live.service.ILiveUserRedRecordService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播用户红包记录Controller
+ * 
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveUserRedRecord")
+public class LiveUserRedRecordController extends BaseController
+{
+    @Autowired
+    private ILiveUserRedRecordService liveUserRedRecordService;
+
+    /**
+     * 查询直播用户红包记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserRedRecord:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserRedRecord liveUserRedRecord)
+    {
+        startPage();
+        List<LiveUserRedRecord> list = liveUserRedRecordService.selectLiveUserRedRecordList(liveUserRedRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播用户红包记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserRedRecord:export')")
+    @Log(title = "直播用户红包记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserRedRecord liveUserRedRecord)
+    {
+        List<LiveUserRedRecord> list = liveUserRedRecordService.selectLiveUserRedRecordList(liveUserRedRecord);
+        ExcelUtil<LiveUserRedRecord> util = new ExcelUtil<LiveUserRedRecord>(LiveUserRedRecord.class);
+        return util.exportExcel(list, "直播用户红包记录数据");
+    }
+
+    /**
+     * 获取直播用户红包记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserRedRecord:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserRedRecordService.selectLiveUserRedRecordById(id));
+    }
+
+    /**
+     * 新增直播用户红包记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserRedRecord:add')")
+    @Log(title = "直播用户红包记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserRedRecord liveUserRedRecord)
+    {
+        return toAjax(liveUserRedRecordService.insertLiveUserRedRecord(liveUserRedRecord));
+    }
+
+    /**
+     * 修改直播用户红包记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserRedRecord:edit')")
+    @Log(title = "直播用户红包记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserRedRecord liveUserRedRecord)
+    {
+        return toAjax(liveUserRedRecordService.updateLiveUserRedRecord(liveUserRedRecord));
+    }
+
+    /**
+     * 删除直播用户红包记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserRedRecord:remove')")
+    @Log(title = "直播用户红包记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserRedRecordService.deleteLiveUserRedRecordByIds(ids));
+    }
+}

+ 19 - 15
fs-admin/src/main/java/com/fs/live/controller/LiveVideoController.java

@@ -1,28 +1,22 @@
-package com.fs.live.controller;
+package com.fs.live.controller.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.live.domain.LiveVideo;
 import com.fs.live.service.ILiveVideoService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 直播视频Controller
- * 
+ *
  * @author fs
  * @date 2025-01-17
  */
@@ -68,6 +62,16 @@ public class LiveVideoController extends BaseController
         return AjaxResult.success(liveVideoService.selectLiveVideoByVideoId(videoId));
     }
 
+    /**
+     * 获取直播视频详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:query')")
+    @GetMapping(value = "/liveVideoByLiveId/{liveId}")
+    public AjaxResult getLiveVideoByLiveId(@PathVariable("liveId") Long liveId)
+    {
+        return AjaxResult.success(liveVideoService.selectLiveVideoByLiveId(liveId));
+    }
+
     /**
      * 新增直播视频
      */

+ 103 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveWatchConfigController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.framework.web.service.TokenService;
+import com.fs.live.domain.LiveWatchConfig;
+import com.fs.live.service.ILiveWatchConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播观看奖励设置Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/config")
+public class LiveWatchConfigController extends BaseController
+{
+    @Autowired
+    private ILiveWatchConfigService liveWatchConfigService;
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询直播观看奖励设置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveWatchConfig liveWatchConfig)
+    {
+        startPage();
+        List<LiveWatchConfig> list = liveWatchConfigService.selectLiveWatchConfigList(liveWatchConfig);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播观看奖励设置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:export')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveWatchConfig liveWatchConfig)
+    {
+        List<LiveWatchConfig> list = liveWatchConfigService.selectLiveWatchConfigList(liveWatchConfig);
+        ExcelUtil<LiveWatchConfig> util = new ExcelUtil<LiveWatchConfig>(LiveWatchConfig.class);
+        return util.exportExcel(list, "直播观看奖励设置数据");
+    }
+
+    /**
+     * 获取直播观看奖励设置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success("",liveWatchConfigService.selectLiveWatchConfigByLiveId(id));
+    }
+
+    /**
+     * 新增直播观看奖励设置
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:add')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody String jsonConfig)
+    {
+        String userId = tokenService.getLoginUser(ServletUtils.getRequest()).getUser().getUserId().toString();
+        return toAjax(liveWatchConfigService.insertLiveWatchConfig(userId, jsonConfig));
+    }
+
+    /**
+     * 修改直播观看奖励设置
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:edit')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody String jsonConfig)
+    {
+        return toAjax(liveWatchConfigService.updateLiveWatchConfig(jsonConfig));
+    }
+
+    /**
+     * 删除直播观看奖励设置
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:remove')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+
+        return toAjax(liveWatchConfigService.deleteLiveWatchConfigByIds(ids));
+    }
+}

+ 42 - 14
fs-admin/src/main/java/com/fs/live/controller/LiveWatchUserController.java

@@ -1,28 +1,25 @@
 package com.fs.live.controller;
 
-import java.util.List;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.live.domain.LiveWatchUser;
 import com.fs.live.service.ILiveWatchUserService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import com.fs.live.vo.LiveWatchUserVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 直播间观看用户Controller
- * 
+ *
  * @author fs
  * @date 2025-01-18
  */
@@ -45,6 +42,16 @@ public class LiveWatchUserController extends BaseController
         return getDataTable(list);
     }
 
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:list')")
+    @GetMapping("/watchUserList")
+    public TableDataInfo watchUserList(@RequestParam Long liveId) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        startPage();
+        List<LiveWatchUserVO> onLineUserList = liveWatchUserService.selectWatchUserList(params);
+        return getDataTable(onLineUserList);
+    }
+
     /**
      * 导出直播间观看用户列表
      */
@@ -100,4 +107,25 @@ public class LiveWatchUserController extends BaseController
     {
         return toAjax(liveWatchUserService.deleteLiveWatchUserByIds(ids));
     }
+
+    /**
+     * 修改直播间用户禁言状态
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeUserState")
+    public AjaxResult changeUserState(@RequestParam Long liveId, @RequestParam Long userId) {
+        return toAjax(liveWatchUserService.changeUserState(liveId, userId));
+    }
+
+    /**
+     * 封禁用户账号
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @GetMapping("/blockUser/{userId}")
+    public AjaxResult blockUser(@PathVariable Long userId) {
+        return toAjax(liveWatchUserService.blockUser(userId));
+    }
+
 }

+ 12 - 0
fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java

@@ -0,0 +1,12 @@
+package com.fs.common.constant;
+
+public class LiveKeysConstant {
+
+    public static final String USER_VISIT_KEY = "live:user:visit:";  // 用户访问标识用于判断是否是首次访问
+    public static final String UNIQUE_VISITORS_KEY = "live:unique:visitors:";  //访客数
+    public static final String UNIQUE_VIEWERS_KEY = "live:unique:viewers:";  //累计观看人数
+    public static final String PAGE_VIEWS_KEY = "live:page:views:";  //浏览量
+    public static final String TOTAL_VIEWS_KEY = "live:total:views:";  //累计观看人次
+    public static final String MAX_ONLINE_USERS_KEY = "live:max:online:"; //最大在线人数
+    public static final String ONLINE_USERS_KEY = "live:online:users:";  //当前在线人数
+}

+ 99 - 1
fs-common/src/main/java/com/fs/common/core/redis/RedisCache.java

@@ -9,17 +9,32 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.stereotype.Component;
 
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
 /**
  * spring redis 工具类
  *
 
  **/
-@SuppressWarnings(value = { "unchecked", "rawtypes" })
 @Component
 public class RedisCache
 {
     @Autowired
     public RedisTemplate redisTemplate;
+    /**
+     * 递增 key 对应的数值
+     *
+     * @param key 缓存键
+     * @param delta 增量
+     * @return 递增后的值
+     */
+    public Long increment(final String key, final long delta) {
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+    public Long incrementCacheValue(final String key, final long delta) {
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
 
     /**
      * 缓存基本的对象,Integer、String、实体类等
@@ -70,6 +85,18 @@ public class RedisCache
         return redisTemplate.expire(key, timeout, unit);
     }
 
+    /**
+     * 当 key 不存在时设置值
+     *
+     * @param key   缓存键
+     * @param value 缓存值
+     * @param timeout 过期时间
+     * @param unit 时间单位
+     * @return true: 设置成功,false: key 已存在
+     */
+    public boolean setIfAbsent(final String key, final Object value, long timeout, TimeUnit unit) {
+        return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit));
+    }
     /**
      * 获得缓存的基本对象。
      *
@@ -116,6 +143,58 @@ public class RedisCache
         return count == null ? 0 : count;
     }
 
+
+    /**
+     * 添加List消息数据
+     *
+     * @param key 缓存的键值
+     * @param dataList 待缓存的List消息数据
+     * @return 缓存的对象
+     */
+    public <T> long setVoiceList(final String key, final List<T> dataList)
+    {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 添加List消息数据的key
+     *
+     * @param key 缓存的键值
+     * @param value 待缓存的值
+     * @return 缓存的对象
+     */
+    public <T> void setVoice(final String key, final T value)
+    {
+        redisTemplate.opsForList().rightPush(key, value);
+    }
+
+    /**
+     * 获得list对象的value
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T getVoiceAllList(final String key)
+    {
+        return (T) redisTemplate.opsForList().range(key,0,-1);
+    }
+
+    /**
+     * 获得缓存的对象id
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T popVoiceKey(final String key)
+    {
+        if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
+            return (T) redisTemplate.opsForList().leftPop(key);
+        }
+        return null;
+    }
+
+
     /**
      * 获得缓存的list对象
      *
@@ -228,6 +307,25 @@ public class RedisCache
         return redisTemplate.keys(pattern);
     }
 
+    /**
+     * 将对象添加到 Redis 的 Set 集合中
+     *
+     * @param key   Redis Key
+     * @param value 要添加的对象(例如 userId)
+     */
+    public void setSetCacheObject(String key, Object value) {
+        redisTemplate.opsForSet().add(key, value);
+    }
+
+    /**
+     * 从 Redis 的 Set 集合中移除指定的对象
+     *
+     * @param key   Redis Key
+     * @param value 要移除的对象(例如 userId)
+     */
+    public void removeSetCacheObject(String key, Object value) {
+        redisTemplate.opsForSet().remove(key, value);
+    }
 
     public Boolean setIfAbsent(String key, String value, long timeout, TimeUnit unit) {
         return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);

+ 64 - 0
fs-common/src/main/java/com/fs/common/utils/DateUtils.java

@@ -8,6 +8,8 @@ import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.LinkedList;
+
 import org.apache.commons.lang3.time.DateFormatUtils;
 
 /**
@@ -264,6 +266,68 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         return endOfDay.format(OUTPUT_FORMATTER);
     }
 
+    /**
+     * 检查两个时间是否跨天
+     * @param startTime 开始时间
+     * @param finishTime 结束时间
+     * @return true表示跨天,false表示未跨天
+     */
+    public static boolean isCrossDay(LocalDateTime startTime, LocalDateTime finishTime) {
+        if (startTime == null || finishTime == null) {
+            throw new IllegalArgumentException("时间参数不能为空");
+        }
+
+        // 如果结束时间早于开始时间,说明参数有误
+        if (finishTime.isBefore(startTime)) {
+            throw new IllegalArgumentException("结束时间不能早于开始时间");
+        }
+
+        LocalDate startDate = startTime.toLocalDate();
+        LocalDate finishDate = finishTime.toLocalDate();
+
+        // 比较日期部分是否相等
+        return !startDate.isEqual(finishDate);
+    }
+
+    /**
+     * 返回时间最近步长 向下(向前)取整
+     * @param startTime 开始时间
+     * @param step 步长
+     * @return 开始时间最近步长
+     */
+    public static LocalDateTime getLiveOrderStartTime(LocalDateTime startTime, int step) {
+
+        // 将startTime按照最近30分钟来取值 比如17:35 就改为17:30
+        int minute = startTime.getMinute();
+        int truncatedMinute = (minute / step) * step;
+        startTime = startTime.withMinute(truncatedMinute).withSecond(0).withNano(0);
+        return startTime;
+    }
+
+    /**
+     * 根据开始时间、结束时间和步长拆分时间
+     *
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param unit 时间单位 (ChronoUnit.HOURS, ChronoUnit.DAYS等)
+     * @param step 步长
+     * @return 时间点列表
+     */
+    public static LinkedList<LocalDateTime> splitTimeByStep(LocalDateTime startTime,
+                                                            LocalDateTime endTime,
+                                                            ChronoUnit unit,
+                                                            int step) {
+        LinkedList<LocalDateTime> timeSlots = new LinkedList<>();
+        LocalDateTime currentTime = startTime;
+
+        while (!currentTime.isAfter(endTime)) {
+            timeSlots.add(currentTime);
+            currentTime = currentTime.plus(step, unit);
+        }
+
+        return timeSlots;
+    }
+
     // 返回昨天或明天的日期字符串(格式:yyyy-MM-dd)
     public static String addDateDays(int days) {
         Calendar cal = Calendar.getInstance();

+ 10 - 0
fs-company/src/main/java/com/fs/company/controller/common/CommonController.java

@@ -12,6 +12,7 @@ import com.fs.common.utils.file.FileUploadUtils;
 import com.fs.common.utils.file.FileUtils;
 import com.fs.company.utils.AudioUtils;
 import com.fs.company.vo.WangUploadVO;
+import com.fs.course.service.ITencentCloudCosService;
 import com.fs.framework.config.ServerConfig;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
@@ -58,6 +59,9 @@ public class CommonController
     @Autowired
     private ServerConfig serverConfig;
 
+    @Autowired
+    private ITencentCloudCosService tencentCloudCosService;
+
     @Autowired
     private QwApiService qwApiService;
 
@@ -292,6 +296,12 @@ public class CommonController
         }
     }
 
+    @GetMapping("/common/getTmpSecretKey")
+    public R getTmpSecretKey()
+    {
+        return tencentCloudCosService.getKeyAndCredentials();
+    }
+
     @GetMapping(value = "/common/getInquiryConfig")
     public AjaxResult getInquiryConfig()
     {

+ 16 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java

@@ -26,6 +26,8 @@ import com.fs.company.vo.CompanyUserImportVO;
 import com.fs.company.vo.CompanyUserQwListVO;
 import com.fs.company.vo.CompanyUserVO;
 import com.fs.course.config.CourseConfig;
+import com.fs.course.domain.FsUserTalent;
+import com.fs.course.service.IFsUserTalentService;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.service.TokenService;
@@ -86,6 +88,8 @@ public class CompanyUserController extends BaseController
     @Autowired
     private ISysConfigService configService;
     @Autowired
+    private IFsUserTalentService fsUserTalentService;
+    @Autowired
     private RedisCache redisCache;
     @Autowired
     private OpenIMService openIMService;
@@ -156,6 +160,18 @@ public class CompanyUserController extends BaseController
     }
 
 
+    /**
+     * 获取达人详细信息
+     */
+
+    @GetMapping(value = "/selectCompanyTalent/{companyId}")
+    public TableDataInfo selectCompanyTalent(@PathVariable String companyId)
+    {
+        List<FsUserTalent> list = fsUserTalentService.selectCompanyTalent(companyId);
+        return getDataTable(list);
+    }
+
+
     @Log(title = "销售信息导入", businessType = BusinessType.IMPORT,isStoreLog = true,logParam = {"销售","信息导入"})
     @PreAuthorize("@ss.hasPermi('company:user:import')")
     @PostMapping("/importCompanyUser")

+ 121 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveAnchorController.java

@@ -0,0 +1,121 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.security.SecurityUtils;
+import com.fs.live.domain.LiveAnchor;
+import com.fs.live.service.ILiveAnchorService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 主播Controller
+ *
+ * @author fs
+ * @date 2025-01-17
+ */
+@RestController
+@RequestMapping("/live/liveAnchor")
+public class LiveAnchorController extends BaseController
+{
+    @Autowired
+    private ILiveAnchorService liveAnchorService;
+
+    /**
+     * 查询主播列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAnchor:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveAnchor liveAnchor)
+    {
+        // 设置企业ID 企业用户ID
+        setCompanyId(liveAnchor);
+
+        startPage();
+        List<LiveAnchor> list = liveAnchorService.selectLiveAnchorList(liveAnchor);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出主播列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAnchor:export')")
+    @Log(title = "主播", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveAnchor liveAnchor)
+    {
+        // 设置企业ID 企业用户ID
+        setCompanyId(liveAnchor);
+
+        List<LiveAnchor> list = liveAnchorService.selectLiveAnchorList(liveAnchor);
+        ExcelUtil<LiveAnchor> util = new ExcelUtil<LiveAnchor>(LiveAnchor.class);
+        return util.exportExcel(list, "主播数据");
+    }
+
+    /**
+     * 获取主播详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAnchor:query')")
+    @GetMapping(value = "/{anchorId}")
+    public AjaxResult getInfo(@PathVariable("anchorId") Long anchorId)
+    {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        return AjaxResult.success(liveAnchorService.selectLiveAnchorByAnchorIdAndCompanyIdAndCompanyUserId(anchorId, user.getCompanyId(), user.getUserId()));
+    }
+
+    /**
+     * 新增主播
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAnchor:add')")
+    @Log(title = "主播", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveAnchor liveAnchor)
+    {
+        // 设置企业ID 企业用户ID
+        setCompanyId(liveAnchor);
+        return toAjax(liveAnchorService.insertLiveAnchor(liveAnchor));
+    }
+
+    /**
+     * 修改主播
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAnchor:edit')")
+    @Log(title = "主播", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveAnchor liveAnchor)
+    {
+        return toAjax(liveAnchorService.updateLiveAnchor(liveAnchor));
+    }
+
+    /**
+     * 删除主播
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveAnchor:remove')")
+    @Log(title = "主播", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{anchorIds}")
+    public AjaxResult remove(@PathVariable Long[] anchorIds)
+    {
+        return toAjax(liveAnchorService.deleteLiveAnchorByAnchorIds(anchorIds));
+    }
+
+    /**
+     * 设置企业ID 企业用户ID
+     * @param liveAnchor 主播信息
+     */
+    private void setCompanyId(LiveAnchor liveAnchor) {
+        // 设置企业ID 企业用户ID
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        CompanyUser user = loginUser.getUser();
+        liveAnchor.setCompanyId(user.getCompanyId());
+        liveAnchor.setCompanyUserId(user.getUserId());
+    }
+}

+ 105 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveAutoTaskController.java

@@ -0,0 +1,105 @@
+package com.fs.company.controller.live;
+
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.live.domain.LiveAutoTask;
+import com.fs.live.service.ILiveAutoTaskService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播间自动化任务配置Controller
+ *
+ * @author fs
+ * @date 2025-08-29
+ */
+@RestController
+@RequestMapping("/live/task")
+public class LiveAutoTaskController extends BaseController
+{
+    @Autowired
+    private ILiveAutoTaskService liveAutoTaskService;
+
+    /**
+     * 查询直播间自动化任务配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveAutoTask liveAutoTask)
+    {
+        startPage();
+        List<LiveAutoTask> list = liveAutoTaskService.selectLiveAutoTaskList(liveAutoTask);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播间自动化任务配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:export')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveAutoTask liveAutoTask)
+    {
+        List<LiveAutoTask> list = liveAutoTaskService.selectLiveAutoTaskList(liveAutoTask);
+        ExcelUtil<LiveAutoTask> util = new ExcelUtil<LiveAutoTask>(LiveAutoTask.class);
+        return util.exportExcel(list, "直播间自动化任务配置数据");
+    }
+
+    /**
+     * 获取直播间自动化任务配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveAutoTaskService.selectLiveAutoTaskById(id));
+    }
+
+    /**
+     * 新增直播间自动化任务配置
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:add')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R add(@RequestBody LiveAutoTask liveAutoTask)
+    {
+        return liveAutoTaskService.insertLiveAutoTask(liveAutoTask);
+    }
+
+    /**
+     * 修改直播间自动化任务配置
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:edit')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveAutoTask liveAutoTask)
+    {
+        return toAjax(liveAutoTaskService.updateLiveAutoTask(liveAutoTask));
+    }
+
+    /**
+     * 删除直播间自动化任务配置
+     */
+    @PreAuthorize("@ss.hasPermi('shop:task:remove')")
+    @Log(title = "直播间自动化任务配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveAutoTaskService.deleteLiveAutoTaskByIds(ids));
+    }
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveCartController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveCart;
+import com.fs.live.service.ILiveCartService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 购物车Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveCart")
+public class LiveCartController extends BaseController
+{
+    @Autowired
+    private ILiveCartService liveCartService;
+
+    /**
+     * 查询购物车列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveCart liveCart)
+    {
+        startPage();
+        List<LiveCart> list = liveCartService.selectLiveCartList(liveCart);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出购物车列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:export')")
+    @Log(title = "购物车", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveCart liveCart)
+    {
+        List<LiveCart> list = liveCartService.selectLiveCartList(liveCart);
+        ExcelUtil<LiveCart> util = new ExcelUtil<LiveCart>(LiveCart.class);
+        return util.exportExcel(list, "购物车数据");
+    }
+
+    /**
+     * 获取购物车详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:query')")
+    @GetMapping(value = "/{cardId}")
+    public AjaxResult getInfo(@PathVariable("cardId") Long cardId)
+    {
+        return AjaxResult.success(liveCartService.selectLiveCartByCartId(cardId));
+    }
+
+    /**
+     * 新增购物车
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:add')")
+    @Log(title = "购物车", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveCart liveCart)
+    {
+        return toAjax(liveCartService.insertLiveCart(liveCart));
+    }
+
+    /**
+     * 修改购物车
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:edit')")
+    @Log(title = "购物车", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveCart liveCart)
+    {
+        return toAjax(liveCartService.updateLiveCart(liveCart));
+    }
+
+    /**
+     * 删除购物车
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveCart:remove')")
+    @Log(title = "购物车", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{cardIds}")
+    public AjaxResult remove(@PathVariable Long[] cardIds)
+    {
+        return toAjax(liveCartService.deleteLiveCartByCartIds(cardIds));
+    }
+}

+ 357 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveController.java

@@ -0,0 +1,357 @@
+package com.fs.company.controller.live;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.exception.file.OssException;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.http.HttpUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.his.domain.FsPayConfig;
+import com.fs.his.utils.HttpUtil;
+import com.fs.live.domain.LiveCompanyCode;
+import com.fs.live.service.ILiveCompanyCodeService;
+import com.fs.live.vo.LiveListVo;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.security.SecurityUtils;
+import com.fs.framework.service.TokenService;
+import com.fs.live.domain.Live;
+import com.fs.live.service.ILiveService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.io.FileUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServlet;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播Controller
+ *
+ * @author fs
+ * @date 2025-01-17
+ */
+@RestController
+@RequestMapping("/live/live")
+public class LiveController extends BaseController
+{
+    @Autowired
+    private ILiveService liveService;
+    @Autowired
+    private TokenService tokenService;
+    @Autowired
+    private ILiveCompanyCodeService liveCompanyCodeService;
+
+    /**
+     * 查询直播列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(Live live)
+    {
+        // 设置企业ID和企业用户ID
+        setCompanyId(live);
+
+        startPage();
+        List<Live> list = liveService.selectLiveList(live);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询直播列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:selectLiveToStudent')")
+    @PostMapping("/selectLiveToStudent")
+    public TableDataInfo selectLiveToStudent(@RequestBody Map<String,String> param)
+    {
+        startPage();
+        String liveName = param.get("liveName");
+        String status = param.get("status");
+        String startTime = param.get("startTime");
+        String finishTime = param.get("finishTime");
+        List<Live> list = liveService.selectLiveToStudent(liveName,status,startTime,finishTime);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:export')")
+    @Log(title = "直播", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(Live live)
+    {
+        // 设置企业ID和企业用户ID
+        setCompanyId(live);
+
+        List<Live> list = liveService.selectLiveList(live);
+        ExcelUtil<Live> util = new ExcelUtil<Live>(Live.class);
+        return util.exportExcel(list, "直播数据");
+    }
+
+    /**
+     * 获取直播详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:query')")
+    @GetMapping(value = "/{liveId}")
+    public AjaxResult getInfo(@PathVariable("liveId") Long liveId)
+    {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        return AjaxResult.success(liveService.selectLiveByLiveIdAndCompanyIdAndCompanyUserId(liveId, user.getCompanyId(), user.getUserId()));
+    }
+
+
+
+    /**
+     * 新增直播
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:add')")
+    @Log(title = "直播", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody Live live)
+    {
+        // 设置企业ID和企业用户ID
+        setCompanyId(live);
+        return toAjax(liveService.insertLive(live));
+    }
+
+    /**
+     * 结束直播
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:edit')")
+    @GetMapping("/finishLive")
+    public R finishLive(Live live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyUserId(user.getUserId());
+        live.setCompanyId(user.getCompanyId());
+        return liveService.finishLive(live);
+    }
+
+    /**
+     * 复制直播
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:edit')")
+    @GetMapping("/copyLive")
+    public R copyLive(Live live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyUserId(user.getUserId());
+        live.setCompanyId(user.getCompanyId());
+        return liveService.copyLive(live);
+    }
+
+    /**
+     * 开启直播
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:edit')")
+    @GetMapping("/startLive")
+    public R startLive(Live live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyUserId(user.getUserId());
+        live.setCompanyId(user.getCompanyId());
+        return liveService.startLive(live);
+    }
+
+    /**
+     * 修改直播
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:edit')")
+    @Log(title = "直播", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody Live live)
+    {
+        return toAjax(liveService.updateLive(live));
+    }
+
+    /**
+     * 删除直播
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:remove')")
+    @Log(title = "直播", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{liveIds}")
+    public AjaxResult remove(@PathVariable Long[] liveIds)
+    {
+        return toAjax(liveService.deleteLiveByLiveIds(liveIds));
+    }
+
+    @GetMapping("/living/{liveId}")
+    public R getRoom(@PathVariable String liveId) {
+        return liveService.getLiveRoom(liveId);
+    }
+
+    @PostMapping("/checkLive")
+    public R checkLiving(@RequestBody Map<String, String> payload) {
+        return liveService.checkLiving(payload);
+    }
+
+    @PostMapping("/closeLiving")
+    public R closeLiving(@RequestBody Map<String, String> payload) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        payload.put("userId", loginUser.getUser().getUserId().toString());
+        return liveService.closeLiving(payload);
+    }
+
+    @PostMapping("/create")
+    public R createRoom(@RequestBody Map<String, Object> payload) {
+        if (!payload.containsKey("liveId")) {
+            return R.error("直播间id缺失");
+        }
+        Long liveId = Long.valueOf(payload.get("liveId").toString());
+        return liveService.createLiveRoom(liveId);
+    }
+
+    /**
+     * 校验上传的身份证信息
+     */
+    @PostMapping("/verifyIdInfo")
+    public R verifyIdInfo(@RequestBody Map<String, String> payload) {
+        return liveService.verifyIdInfo(payload);
+    }
+
+    /**
+     * 开始循环播放视频
+     */
+    @PostMapping("/startLoopPlay")
+    public R startLoopPlay(@RequestBody Live live) {
+        return liveService.startLoopPlay(live);
+    }
+
+    /**
+     * 停止循环播放
+     */
+    @PostMapping("/stopLoopPlay")
+    public R stopLoopPlay(@RequestBody Live live) {
+        return liveService.stopLoopPlay(live);
+    }
+
+    /**
+     * 批量上下架视频
+     */
+    @PostMapping("/handleShelfOrUn")
+    public R handleShelfOrUn(@RequestBody LiveListVo listVo) {
+        setListCompanyId(listVo);
+        return liveService.handleShelfOrUn(listVo);
+    }
+
+    /**
+     * 批量删除视频
+     */
+    @PostMapping("/handleDeleteSelected")
+    public R handleDeleteSelected(@RequestBody LiveListVo listVo) {
+        setListCompanyId(listVo);
+        return liveService.handleDeleteSelected(listVo);
+    }
+
+
+
+    /**
+     * 设置企业ID和企业用户ID
+     * @param live 直播间
+     */
+    private void setCompanyId(Live live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyId(user.getCompanyId());
+        live.setCompanyUserId(user.getUserId());
+    }
+
+    /**
+     * 设置企业ID和企业用户ID
+     * @param live 直播间
+     */
+    private void setListCompanyId(LiveListVo live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyId(user.getCompanyId());
+        live.setCompanyUserId(user.getUserId());
+    }
+
+    @ApiOperation("查询微信urlScheme")
+    @GetMapping("/getAppletScheme")
+    public R getAppletScheme(@RequestParam(value = "cardId") Long cardId) {
+        try {
+            String appId = "123";
+            String secret = "123";
+            String rspStr = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/token", "grant_type=client_credential&" + "appid=" + appId + "&secret=" + secret);
+            JSONObject obj = JSONObject.parseObject(rspStr);
+            String access_token = obj.getString("access_token");
+            JSONObject jsonObject = new JSONObject();
+            JSONObject jump_wxaObj = new JSONObject();
+            jump_wxaObj.put("path", "/pages_company/card");
+            jump_wxaObj.put("query", "id=" + cardId);
+            jsonObject.put("jump_wxa", jump_wxaObj);
+            jsonObject.put("is_expire", false);
+            String paramStr = jsonObject.toJSONString();
+            String postStr = HttpUtils.sendPost("https://api.weixin.qq.com/wxa/generatescheme?access_token=" + access_token, paramStr);
+            obj = JSONObject.parseObject(postStr);
+            //response.addHeader("Access-Control-Allow-Origin", "*");
+            return R.ok().put("result", obj);
+        } catch (Exception e) {
+            return R.error("操作失败");
+        }
+    }
+
+    @ApiOperation("生成微信小程序码")
+    @GetMapping("/getWxaCodeUnLimit")
+    public R getWxaCodeUnLimit(@RequestParam(value = "liveId") Long liveId) {
+        String url="https://api.weixin.qq.com/cgi-bin/stable_token";
+        HashMap<String, String> map = new HashMap<>();
+        map.put("grant_type","client_credential");
+        // 芳华惠选
+        map.put("appid","wx503cf8ab31f83dd4");
+        map.put("secret","1ba1972363889dcb4a37ecb685744435");
+        String accessToken = HttpUtil.endApi(url, null, map);
+        // 创建Gson对象
+        Gson gson = new Gson();
+        // 将JSON字符串解析为Java对象
+        Map<String, String> accessTokenMap  = gson.fromJson(accessToken, new TypeToken<Map<String, Object>>(){}.getType());
+        String codeUrl="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+accessTokenMap.get("access_token");
+        HashMap<String, String> jsonMap = new HashMap<>();
+        jsonMap.put("page","pages/auth/login");
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        String scene = "a="+ liveId+"&b="+user.getCompanyId()+"&c="+user.getUserId();
+        jsonMap.put("scene",scene);
+        //正式版为 "release",体验版为 "trial",开发版为 "develop"
+        jsonMap.put("env_version","trial");
+        byte[] bytes = HttpUtil.getWechatQrcodeByHttpURL(codeUrl, jsonMap);
+        if(bytes.length == 0) return R.error("生成二维码失败");
+        if (bytes.length > 0 && bytes.length < 500) {
+            String errorCode = new String(bytes, StandardCharsets.UTF_8);
+            logger.error(errorCode);
+            return R.error("生成二维码失败");
+        }
+        // 保存
+        String saveUrl = OSSFactory.build().uploadSuffix(bytes, ".png");
+        Date nowDate = DateUtils.getNowDate();
+        LiveCompanyCode exist = liveCompanyCodeService.selectByLiveIdAndUser(liveId, user.getCompanyId(), user.getUserId());
+        if (exist == null) {
+            exist = new LiveCompanyCode();
+            exist.setLiveId(liveId);
+            exist.setCompanyId(user.getCompanyId());
+            exist.setCompanyUserId(user.getUserId());
+            exist.setCreateTime(nowDate);
+        }
+        exist.setUpdateTime(nowDate);
+        exist.setLiveCodeUrl(saveUrl);
+        liveCompanyCodeService.saveOrUpdate(exist);
+        return R.ok().put("data", exist);
+    }
+}

+ 157 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveDataController.java

@@ -0,0 +1,157 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+import com.fs.live.domain.LiveData;
+import com.fs.live.service.ILiveDataService;
+import com.fs.live.vo.ColumnsConfigVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播数据Controller
+ *
+ * @author fs
+ * @date 2025-03-05
+ */
+@RestController
+@RequestMapping("/liveData/liveData")
+public class LiveDataController extends BaseController
+{
+    @Autowired
+    private ILiveDataService liveDataService;
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询直播数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveData liveData)
+    {
+        startPage();
+        List<LiveData> list = liveDataService.selectLiveDataList(liveData);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:export')")
+    @Log(title = "直播数据", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveData liveData)
+    {
+        List<LiveData> list = liveDataService.selectLiveDataList(liveData);
+        ExcelUtil<LiveData> util = new ExcelUtil<LiveData>(LiveData.class);
+        return util.exportExcel(list, "直播数据数据");
+    }
+
+    /**
+     * 获取直播数据详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:query')")
+    @GetMapping(value = "/{liveId}")
+    public AjaxResult getInfo(@PathVariable("liveId") Long liveId)
+    {
+        return AjaxResult.success(liveDataService.selectLiveDataByLiveId(liveId));
+    }
+
+    /**
+     * 新增直播数据
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:add')")
+    @Log(title = "直播数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveData liveData)
+    {
+        return toAjax(liveDataService.insertLiveData(liveData));
+    }
+
+    /**
+     * 修改直播数据
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:edit')")
+    @Log(title = "直播数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveData liveData)
+    {
+        return toAjax(liveDataService.updateLiveData(liveData));
+    }
+
+    /**
+     * 删除直播数据
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:remove')")
+    @Log(title = "直播数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{liveIds}")
+    public AjaxResult remove(@PathVariable Long[] liveIds)
+    {
+        return toAjax(liveDataService.deleteLiveDataByLiveIds(liveIds));
+    }
+
+    /**
+     * 直播数据页面近期直播卡片数据
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:recentLive')")
+    @GetMapping("/recentLive")
+    public AjaxResult recentLive(){
+        return AjaxResult.success(liveDataService.getRecentLive());
+    }
+
+    /**
+     * 查询直播top榜数据
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:getLiveTop')")
+    @GetMapping("/getLiveTop")
+    public AjaxResult getLiveTop(String rankType){
+        System.out.println(rankType);
+        return AjaxResult.success(liveDataService.getLiveTop(rankType));
+    }
+    /**
+     * 查询直播趋势数据
+     * @param
+     * @param
+     * @return
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:getTrendData')")
+    @PostMapping("/getTrendData")
+    public AjaxResult getTrendData(@RequestBody Map<String,String> queryParams) {
+        String type = queryParams.get("type");
+        String date = queryParams.get("date");
+        String category = queryParams.get("category");
+        return AjaxResult.success(liveDataService.getTrendData(type, date,category));
+    }
+    /*@PreAuthorize("@ss.hasPermi('liveData:liveData:columns')")
+    @GetMapping("/columns")
+    public AjaxResult getTableColumns(HttpServletRequest request, HttpServletResponse response) {
+        LoginUser loginUser = tokenService.getLoginUser(request);
+        //LoginUser loginUser = SecurityUtils.getLoginUser();
+        Long userId = loginUser.getUser().getUserId();
+        List<ColumnsConfigVo> columnsConfig = liveDataService.getColumnsConfig(userId.toString());
+       return AjaxResult.success(columnsConfig);
+    }*/
+
+    @PostMapping("/updateColumns")
+    public AjaxResult updateColumns(@RequestBody List<ColumnsConfigVo> columns, HttpServletRequest request) {
+        LoginUser loginUser = tokenService.getLoginUser(request);
+        Long userId = loginUser.getUser().getUserId();
+        liveDataService.saveColumnsConfig(userId.toString(), columns);
+        return AjaxResult.success("列配置已保存");
+    }
+
+
+
+}

+ 103 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveGiftController.java

@@ -0,0 +1,103 @@
+package com.fs.live.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveGift;
+import com.fs.live.service.ILiveGiftService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播间礼物配置Controller
+ * 
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/gift")
+public class LiveGiftController extends BaseController
+{
+    @Autowired
+    private ILiveGiftService liveGiftService;
+
+    /**
+     * 查询直播间礼物配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveGift liveGift)
+    {
+        startPage();
+        List<LiveGift> list = liveGiftService.selectLiveGiftList(liveGift);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播间礼物配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:export')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveGift liveGift)
+    {
+        List<LiveGift> list = liveGiftService.selectLiveGiftList(liveGift);
+        ExcelUtil<LiveGift> util = new ExcelUtil<LiveGift>(LiveGift.class);
+        return util.exportExcel(list, "直播间礼物配置数据");
+    }
+
+    /**
+     * 获取直播间礼物配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:query')")
+    @GetMapping(value = "/{giftId}")
+    public AjaxResult getInfo(@PathVariable("giftId") Long giftId)
+    {
+        return AjaxResult.success(liveGiftService.selectLiveGiftByGiftId(giftId));
+    }
+
+    /**
+     * 新增直播间礼物配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:add')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveGift liveGift)
+    {
+        return toAjax(liveGiftService.insertLiveGift(liveGift));
+    }
+
+    /**
+     * 修改直播间礼物配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:edit')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveGift liveGift)
+    {
+        return toAjax(liveGiftService.updateLiveGift(liveGift));
+    }
+
+    /**
+     * 删除直播间礼物配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:gift:remove')")
+    @Log(title = "直播间礼物配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{giftIds}")
+    public AjaxResult remove(@PathVariable Long[] giftIds)
+    {
+        return toAjax(liveGiftService.deleteLiveGiftByGiftIds(giftIds));
+    }
+}

+ 163 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveGoodsController.java

@@ -0,0 +1,163 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.security.SecurityUtils;
+import com.fs.live.domain.LiveGoods;
+import com.fs.live.service.ILiveGoodsService;
+import com.fs.live.vo.LiveGoodsListVo;
+import com.fs.live.vo.LiveGoodsVo;
+import com.fs.live.vo.LiveListVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播商品Controller
+ *
+ * @author fs
+ * @date 2025-01-17
+ */
+@RestController
+@RequestMapping("/live/liveGoods")
+public class LiveGoodsController extends BaseController
+{
+    @Autowired
+    private ILiveGoodsService liveGoodsService;
+
+    /**
+     * 查询直播商品列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveGoods liveGoods, @RequestParam(value = "liveId", required = true) Long liveId)
+    {
+        // 设置企业ID和企业用户ID
+        setCompanyId(liveGoods);
+        liveGoods.setLiveId(liveId);
+
+        startPage();
+        List<LiveGoodsVo> list = liveGoodsService.selectProductListByLiveId(liveGoods);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播商品列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:export')")
+    @Log(title = "直播商品", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveGoods liveGoods)
+    {
+        // 设置企业ID和企业用户ID
+        setCompanyId(liveGoods);
+
+        List<LiveGoods> list = liveGoodsService.selectLiveGoodsList(liveGoods);
+        ExcelUtil<LiveGoods> util = new ExcelUtil<LiveGoods>(LiveGoods.class);
+        return util.exportExcel(list, "直播商品数据");
+    }
+
+    /**
+     * 获取直播商品详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:query')")
+    @GetMapping(value = "/{goodsId}")
+    public AjaxResult getInfo(@PathVariable("goodsId") Long goodsId)
+    {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        return AjaxResult.success();
+    }
+
+    /**
+     * 新增直播商品
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:add')")
+    @Log(title = "直播商品", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R add(@RequestBody Map<String, Object> payload)
+    {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        CompanyUser user = loginUser.getUser();
+        return liveGoodsService.insertLiveGoods(payload,user);
+    }
+
+    /**
+     * 修改直播商品
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:edit')")
+    @Log(title = "直播商品", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody LiveGoods liveGoods)
+    {
+        return liveGoodsService.updateLiveGoods(liveGoods);
+    }
+
+    /**
+     * 删除直播商品
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:remove')")
+    @Log(title = "直播商品", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{goodsIds}")
+    public AjaxResult remove(@PathVariable Long[] goodsIds)
+    {
+        return toAjax(liveGoodsService.deleteLiveGoodsByGoodsIds(goodsIds));
+    }
+
+    /**
+     * 设置企业ID 企业用户ID
+     * @param liveGoods 直播商品
+     */
+    private void setCompanyId(LiveGoods liveGoods) {
+        // 设置企业ID 企业用户ID
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        CompanyUser user = loginUser.getUser();
+        liveGoods.setCompanyId(user.getCompanyId());
+        liveGoods.setCompanyUserId(user.getUserId());
+    }
+
+    /**
+     * 批量上下架视频
+     */
+    @PostMapping("/handleShelfOrUn")
+    public R handleShelfOrUn(@RequestBody LiveGoodsListVo listVo) {
+        setListCompanyId(listVo);
+        return liveGoodsService.handleShelfOrUn(listVo);
+    }
+
+    /**
+     * 批量删除视频
+     */
+    @PostMapping("/handleDeleteSelected")
+    public R handleDeleteSelected(@RequestBody LiveGoodsListVo listVo) {
+        setListCompanyId(listVo);
+        return liveGoodsService.handleDeleteSelected(listVo);
+    }
+
+    /**
+     * 更新展示状态
+     */
+    @PostMapping("/handleIsShowChange")
+    public R handleIsShowChange(@RequestBody LiveGoodsListVo listVo) {
+        setListCompanyId(listVo);
+        return liveGoodsService.handleIsShowChange(listVo);
+    }
+
+    /**
+     * 设置企业ID和企业用户ID
+     */
+    private void setListCompanyId(LiveGoodsListVo live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyId(user.getCompanyId());
+        live.setCompanyUserId(user.getUserId());
+    }
+}

+ 133 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryConfController.java

@@ -0,0 +1,133 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveLotteryConf;
+import com.fs.live.param.LiveLotteryProductSaveParam;
+import com.fs.live.service.ILiveLotteryConfService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播抽奖配置Controller
+ *
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveLotteryConf")
+public class LiveLotteryConfController extends BaseController
+{
+    @Autowired
+    private ILiveLotteryConfService liveLotteryConfService;
+
+    /**
+     * 查询直播抽奖配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveLotteryConf liveLotteryConf)
+    {
+        startPage();
+        List<LiveLotteryConf> list = liveLotteryConfService.selectLiveLotteryConfList(liveLotteryConf);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播抽奖配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:export')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveLotteryConf liveLotteryConf)
+    {
+        List<LiveLotteryConf> list = liveLotteryConfService.selectLiveLotteryConfList(liveLotteryConf);
+        ExcelUtil<LiveLotteryConf> util = new ExcelUtil<LiveLotteryConf>(LiveLotteryConf.class);
+        return util.exportExcel(list, "直播抽奖配置数据");
+    }
+
+    /**
+     * 获取直播抽奖配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:query')")
+    @GetMapping(value = "/{lotteryId}")
+    public AjaxResult getInfo(@PathVariable("lotteryId") Long lotteryId)
+    {
+        return AjaxResult.success(liveLotteryConfService.selectLiveLotteryConfByLotteryId(lotteryId));
+    }
+
+    /**
+     * 新增直播抽奖配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:add')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveLotteryConf liveLotteryConf)
+    {
+        return toAjax(liveLotteryConfService.insertLiveLotteryConf(liveLotteryConf));
+    }
+
+    /**
+     * 修改直播抽奖配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:edit')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody LiveLotteryConf liveLotteryConf)
+    {
+       return liveLotteryConfService.updateLiveLotteryConf(liveLotteryConf);
+    }
+
+    /**
+     * 删除直播抽奖配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryConf:remove')")
+    @Log(title = "直播抽奖配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{lotteryIds}")
+    public AjaxResult remove(@PathVariable Long[] lotteryIds)
+    {
+        return toAjax(liveLotteryConfService.deleteLiveLotteryConfByLotteryIds(lotteryIds));
+    }
+
+
+    @GetMapping("/live/{liveId}")
+    public List<LiveLotteryConf> getByLiveId(@PathVariable Long liveId) {
+        return liveLotteryConfService.getByLiveId(liveId);
+    }
+
+
+    @DeleteMapping("/{id}")
+    public void delete(@PathVariable Long id) {
+        liveLotteryConfService.delete(id);
+    }
+
+    /**
+     * 发起抽奖
+     * */
+    @GetMapping("/start/{lotteryId}")
+    public String  start(@PathVariable Long lotteryId) {
+       return liveLotteryConfService.startLottery(lotteryId,getUserId());
+    }
+
+    /** 查询抽奖配置的所有商品信息*/
+    @GetMapping("/getGoods/{lotteryId}")
+    public R getGoods(@PathVariable Long lotteryId) {
+        return R.ok().put("data",liveLotteryConfService.getGoods(lotteryId));
+    }
+
+    /** 抽奖商品配置保存*/
+    @PostMapping("/product")
+    public void saveGoods(@RequestBody LiveLotteryProductSaveParam liveLotteryProducts) {
+        //liveLotteryProducts.setCreateBy(getUsername());
+        liveLotteryConfService.saveProducts(liveLotteryProducts);
+    }
+
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryRecordController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveLotteryRecord;
+import com.fs.live.service.ILiveLotteryRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播抽奖记录Controller
+ *
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveLotteryRecord")
+public class LiveLotteryRecordController extends BaseController
+{
+    @Autowired
+    private ILiveLotteryRecordService liveLotteryRecordService;
+
+    /**
+     * 查询直播抽奖记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveLotteryRecord liveLotteryRecord)
+    {
+        startPage();
+        List<LiveLotteryRecord> list = liveLotteryRecordService.selectLiveLotteryRecordList(liveLotteryRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播抽奖记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:export')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveLotteryRecord liveLotteryRecord)
+    {
+        List<LiveLotteryRecord> list = liveLotteryRecordService.selectLiveLotteryRecordList(liveLotteryRecord);
+        ExcelUtil<LiveLotteryRecord> util = new ExcelUtil<LiveLotteryRecord>(LiveLotteryRecord.class);
+        return util.exportExcel(list, "直播抽奖记录数据");
+    }
+
+    /**
+     * 获取直播抽奖记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:query')")
+    @GetMapping(value = "/{lotteryId}")
+    public AjaxResult getInfo(@PathVariable("lotteryId") Long lotteryId)
+    {
+        return AjaxResult.success(liveLotteryRecordService.selectLiveLotteryRecordByLotteryId(lotteryId));
+    }
+
+    /**
+     * 新增直播抽奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:add')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveLotteryRecord liveLotteryRecord)
+    {
+        return toAjax(liveLotteryRecordService.insertLiveLotteryRecord(liveLotteryRecord));
+    }
+
+    /**
+     * 修改直播抽奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:edit')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveLotteryRecord liveLotteryRecord)
+    {
+        return toAjax(liveLotteryRecordService.updateLiveLotteryRecord(liveLotteryRecord));
+    }
+
+    /**
+     * 删除直播抽奖记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRecord:remove')")
+    @Log(title = "直播抽奖记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{lotteryIds}")
+    public AjaxResult remove(@PathVariable Long[] lotteryIds)
+    {
+        return toAjax(liveLotteryRecordService.deleteLiveLotteryRecordByLotteryIds(lotteryIds));
+    }
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryRegistrationController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveLotteryRegistration;
+import com.fs.live.service.ILiveLotteryRegistrationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播抽奖登记Controller
+ *
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveLotteryRegistration")
+public class LiveLotteryRegistrationController extends BaseController
+{
+    @Autowired
+    private ILiveLotteryRegistrationService liveLotteryRegistrationService;
+
+    /**
+     * 查询直播抽奖登记列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveLotteryRegistration liveLotteryRegistration)
+    {
+        startPage();
+        List<LiveLotteryRegistration> list = liveLotteryRegistrationService.selectLiveLotteryRegistrationList(liveLotteryRegistration);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播抽奖登记列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:export')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveLotteryRegistration liveLotteryRegistration)
+    {
+        List<LiveLotteryRegistration> list = liveLotteryRegistrationService.selectLiveLotteryRegistrationList(liveLotteryRegistration);
+        ExcelUtil<LiveLotteryRegistration> util = new ExcelUtil<LiveLotteryRegistration>(LiveLotteryRegistration.class);
+        return util.exportExcel(list, "直播抽奖登记数据");
+    }
+
+    /**
+     * 获取直播抽奖登记详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:query')")
+    @GetMapping(value = "/{registrationId}")
+    public AjaxResult getInfo(@PathVariable("registrationId") Long registrationId)
+    {
+        return AjaxResult.success(liveLotteryRegistrationService.selectLiveLotteryRegistrationByRegistrationId(registrationId));
+    }
+
+    /**
+     * 新增直播抽奖登记
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:add')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveLotteryRegistration liveLotteryRegistration)
+    {
+        return toAjax(liveLotteryRegistrationService.insertLiveLotteryRegistration(liveLotteryRegistration));
+    }
+
+    /**
+     * 修改直播抽奖登记
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:edit')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveLotteryRegistration liveLotteryRegistration)
+    {
+        return toAjax(liveLotteryRegistrationService.updateLiveLotteryRegistration(liveLotteryRegistration));
+    }
+
+    /**
+     * 删除直播抽奖登记
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveLotteryRegistration:remove')")
+    @Log(title = "直播抽奖登记", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{registrationIds}")
+    public AjaxResult remove(@PathVariable Long[] registrationIds)
+    {
+        return toAjax(liveLotteryRegistrationService.deleteLiveLotteryRegistrationByRegistrationIds(registrationIds));
+    }
+}

+ 101 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveMsgController.java

@@ -0,0 +1,101 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyUser;
+import com.fs.framework.security.SecurityUtils;
+import com.fs.live.domain.LiveMsg;
+import com.fs.live.service.ILiveMsgService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播讨论Controller
+ * 
+ * @author fs
+ * @date 2025-01-17
+ */
+@RestController
+@RequestMapping("/live/liveMsg")
+public class LiveMsgController extends BaseController
+{
+    @Autowired
+    private ILiveMsgService liveMsgService;
+
+    /**
+     * 查询直播讨论列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveMsg liveMsg)
+    {
+        startPage();
+        List<LiveMsg> list = liveMsgService.selectLiveMsgList(liveMsg);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播讨论列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:export')")
+    @Log(title = "直播讨论", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveMsg liveMsg)
+    {
+        List<LiveMsg> list = liveMsgService.selectLiveMsgList(liveMsg);
+        ExcelUtil<LiveMsg> util = new ExcelUtil<LiveMsg>(LiveMsg.class);
+        return util.exportExcel(list, "直播讨论数据");
+    }
+
+    /**
+     * 获取直播讨论详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:query')")
+    @GetMapping(value = "/{msgId}")
+    public AjaxResult getInfo(@PathVariable("msgId") Long msgId)
+    {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        return AjaxResult.success(liveMsgService.selectLiveMsgByMsgId(msgId));
+    }
+
+    /**
+     * 新增直播讨论
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:add')")
+    @Log(title = "直播讨论", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveMsg liveMsg)
+    {
+        return toAjax(liveMsgService.insertLiveMsg(liveMsg));
+    }
+
+    /**
+     * 修改直播讨论
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:edit')")
+    @Log(title = "直播讨论", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveMsg liveMsg)
+    {
+        return toAjax(liveMsgService.updateLiveMsg(liveMsg));
+    }
+
+    /**
+     * 删除直播讨论
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:remove')")
+    @Log(title = "直播讨论", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{msgIds}")
+    public AjaxResult remove(@PathVariable Long[] msgIds)
+    {
+        return toAjax(liveMsgService.deleteLiveMsgByMsgIds(msgIds));
+    }
+
+}

+ 274 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java

@@ -0,0 +1,274 @@
+package com.fs.company.controller.live;
+
+import cn.hutool.core.util.StrUtil;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.erp.domain.ErpDeliverys;
+import com.fs.erp.domain.ErpOrderQuery;
+import com.fs.erp.dto.ErpOrderQueryRequert;
+import com.fs.erp.dto.ErpOrderQueryResponse;
+import com.fs.erp.service.IErpOrderService;
+import com.fs.his.config.FsSysConfig;
+import com.fs.his.domain.FsStoreOrder;
+import com.fs.his.domain.FsStoreOrderItem;
+import com.fs.his.dto.ExpressInfoDTO;
+import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.service.IFsExpressService;
+import com.fs.his.utils.ConfigUtil;
+import com.fs.live.domain.Live;
+import com.fs.live.domain.LiveGoods;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.enums.LiveOrderCancleReason;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.live.vo.LiveGoodsVo;
+import com.fs.live.vo.LiveOrderVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+import static com.fs.his.utils.PhoneUtil.decryptPhone;
+
+/**
+ * 订单Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrder")
+public class LiveOrderController extends BaseController
+{
+    @Autowired
+    private ILiveOrderService liveOrderService;
+
+
+    @Autowired
+    private IFsExpressService expressService;
+
+    @Autowired
+    private ConfigUtil configUtil;
+
+    @Autowired
+    @Qualifier("erpOrderServiceImpl")
+    private IErpOrderService gyOrderService;
+
+    @Autowired
+    @Qualifier("wdtErpOrderServiceImpl")
+    private IErpOrderService wdtOrderService;
+
+
+    /**
+     * 推送到智慧药房
+     */
+    @Log(title = "推药房", businessType = BusinessType.INSERT)
+    @PreAuthorize("@ss.hasPermi('his:storeOrder:sendHisGoods')")
+    @PutMapping("/tuiOrder")
+    public AjaxResult tuiOrder(@RequestBody LiveOrder liveOrder)
+    {
+        return toAjax(liveOrderService.tuiOrder(liveOrder.getOrderId()));
+    }
+
+    /**
+     * 查询订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrder liveOrder)
+    {
+        startPage();
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:export')")
+    @Log(title = "订单", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrder liveOrder)
+    {
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        ExcelUtil<LiveOrder> util = new ExcelUtil<LiveOrder>(LiveOrder.class);
+        return util.exportExcel(list, "订单数据");
+    }
+
+    /**
+     * 获取订单详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:query')")
+    @GetMapping(value = "/info/{orderId}")
+    public AjaxResult getInfo(@PathVariable("orderId") String orderId)
+    {
+        return AjaxResult.success(liveOrderService.selectLiveOrderByOrderId(orderId));
+    }
+
+    /**
+     * 新增订单
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:add')")
+    @Log(title = "订单", businessType = BusinessType.INSERT)
+    @PostMapping("/create")
+    public R add(@RequestBody LiveOrder liveOrder)
+    {
+        liveOrder.setUserId(String.valueOf(getUserId()));
+        return liveOrderService.createLiveOrder(liveOrder);
+    }
+
+    /**
+     * 修改订单
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:edit')")
+    @Log(title = "订单", businessType = BusinessType.UPDATE)
+    @PutMapping("/update")
+    public AjaxResult edit(@RequestBody LiveOrder liveOrder)
+    {
+        return toAjax(liveOrderService.updateLiveOrder(liveOrder));
+    }
+
+
+    /**
+     * 查看物流状态
+     * */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:express')")
+    @GetMapping(value = "/getExpress/{id}")
+    public R getExpress(@PathVariable("id") String id)
+    {
+        LiveOrder order=liveOrderService.selectLiveOrderByOrderId(id);
+        ExpressInfoDTO expressInfoDTO=null;
+        if(StringUtils.isNotEmpty(order.getDeliverySn())){
+            String lastFourNumber = "";
+            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+
+                lastFourNumber = order.getUserPhone();
+                if (lastFourNumber.length() == 11) {
+                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                }else if (lastFourNumber.length()>11){
+                    String jm = decryptPhone(lastFourNumber);
+                    lastFourNumber = StrUtil.sub(jm, jm.length(), -4);
+                }
+            }
+            expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            if((expressInfoDTO.getStateEx()!=null&&expressInfoDTO.getStateEx().equals("0"))&&(expressInfoDTO.getState()!=null&&expressInfoDTO.getState().equals("0"))){
+                lastFourNumber = "19923690275";
+                if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+                    if (lastFourNumber.length() == 11) {
+                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                    }
+                }
+
+                expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            }
+        }
+        return R.ok().put("data",expressInfoDTO);
+    }
+
+    /**
+     * 支付订单
+     * */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:pay')")
+    @PostMapping(value = "/pay")
+    public void pay(LiveOrder liveOrder)
+    {
+       liveOrderService.handlePay(liveOrder);
+    }
+
+    /**
+     * 取消订单确认
+     * */
+    @GetMapping(value = "/cancelConfirm/{orderId}")
+    public R cancelConfirm(@PathVariable String orderId)
+    {
+        LiveOrder byId = liveOrderService.getById(orderId);
+        List<Map<String, String>> allCodeDescMap = LiveOrderCancleReason.getAllCodeDescMap();
+        return R.ok().put("reason",allCodeDescMap).put("data",byId);
+    }
+
+    /**
+     * 按照时间粒度返回订单
+     * */
+    @GetMapping(value = "/getLiveOrderTimeGranularity")
+    public R getLiveOrderTimeGranularity(LiveOrderVo liveOrder){
+        return liveOrderService.getLiveOrderTimeGranularity(liveOrder);
+    }
+
+
+    @Log(title = "同步物流", businessType = BusinessType.UPDATE)
+    @GetMapping(value = "/syncExpress/{id}")
+    public R syncExpress(@PathVariable("id") Long id) {
+        return liveOrderService.syncExpress(id);
+    }
+
+    @Log(title = "同步管易物流单号", businessType = BusinessType.UPDATE)
+    @PreAuthorize("@ss.hasPermi('store:storeOrder:updateErpOrder')")
+    @PostMapping("/updateErpOrder")
+    public R updateErpOrder( @RequestBody LiveOrder param) {
+        LiveOrder order = liveOrderService.selectLiveOrderByOrderId(String.valueOf(param.getOrderId()));
+        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+        IErpOrderService erpOrderService = getErpService();
+        request.setCode(order.getExtendOrderId());
+        ErpOrderQueryResponse response = erpOrderService.getOrder(request);
+        if(response.getOrders()!=null&&response.getOrders().size()>0){
+            for(ErpOrderQuery orderQuery : response.getOrders()){
+                if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
+                    for(ErpDeliverys delivery:orderQuery.getDeliverys()){
+                        if(delivery.getDelivery()&& StringUtils.isNotEmpty(delivery.getMail_no())){
+                            //更新商订单状态
+                            liveOrderService.updateDeliveryOrder(param.getOrderId(), delivery.getMail_no(),delivery.getExpress_code(),delivery.getExpress_name());
+                            return R.ok();
+                        }
+                    }
+
+                }
+            }
+        }
+        return R.error("未查询到快递信息");
+    }
+    private IErpOrderService getErpService() {
+        FsSysConfig sysConfig = configUtil.getSysConfig();
+        Integer erpOpen = sysConfig.getErpOpen();
+        if (erpOpen != null && erpOpen == 1){
+            //判断erp类型
+            Integer erpType = sysConfig.getErpType();
+            if (erpType != null){
+                IErpOrderService erpOrderService = null;
+                if (erpType == 1){
+                    //管易
+                    erpOrderService =  gyOrderService;
+                } else if (erpType == 2){
+                    //旺店通
+                    erpOrderService =  wdtOrderService;
+                }
+                return erpOrderService;
+
+
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 查询订单商品列表
+     */
+
+    @GetMapping("/ltemlist/{orderId}")
+    public TableDataInfo ltemlist(@PathVariable("orderId") String orderId)
+    {
+        List<LiveGoodsVo> list = liveOrderService.selectLiveOrderItemList(orderId);
+        return getDataTable(list);
+    }
+
+
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveOrderItemController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.service.ILiveOrderItemService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 订单详情Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrderItem")
+public class LiveOrderItemController extends BaseController
+{
+    @Autowired
+    private ILiveOrderItemService liveOrderItemService;
+
+    /**
+     * 查询订单详情列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrderItem liveOrderItem)
+    {
+        startPage();
+        List<LiveOrderItem> list = liveOrderItemService.selectLiveOrderItemList(liveOrderItem);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单详情列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:export')")
+    @Log(title = "订单详情", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrderItem liveOrderItem)
+    {
+        List<LiveOrderItem> list = liveOrderItemService.selectLiveOrderItemList(liveOrderItem);
+        ExcelUtil<LiveOrderItem> util = new ExcelUtil<LiveOrderItem>(LiveOrderItem.class);
+        return util.exportExcel(list, "订单详情数据");
+    }
+
+    /**
+     * 获取订单详情详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:query')")
+    @GetMapping(value = "/{itemId}")
+    public AjaxResult getInfo(@PathVariable("itemId") String itemId)
+    {
+        return AjaxResult.success(liveOrderItemService.selectLiveOrderItemByItemId(itemId));
+    }
+
+    /**
+     * 新增订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:add')")
+    @Log(title = "订单详情", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveOrderItem liveOrderItem)
+    {
+        return toAjax(liveOrderItemService.insertLiveOrderItem(liveOrderItem));
+    }
+
+    /**
+     * 修改订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:edit')")
+    @Log(title = "订单详情", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveOrderItem liveOrderItem)
+    {
+        return toAjax(liveOrderItemService.updateLiveOrderItem(liveOrderItem));
+    }
+
+    /**
+     * 删除订单详情
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderItem:remove')")
+    @Log(title = "订单详情", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{itemIds}")
+    public AjaxResult remove(@PathVariable String[] itemIds)
+    {
+        return toAjax(liveOrderItemService.deleteLiveOrderItemByItemIds(itemIds));
+    }
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveOrderLogsController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveOrderLogs;
+import com.fs.live.service.ILiveOrderLogsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 订单操作记录Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrderLogs")
+public class LiveOrderLogsController extends BaseController
+{
+    @Autowired
+    private ILiveOrderLogsService liveOrderLogsService;
+
+    /**
+     * 查询订单操作记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrderLogs liveOrderLogs)
+    {
+        startPage();
+        List<LiveOrderLogs> list = liveOrderLogsService.selectLiveOrderLogsList(liveOrderLogs);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单操作记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:export')")
+    @Log(title = "订单操作记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrderLogs liveOrderLogs)
+    {
+        List<LiveOrderLogs> list = liveOrderLogsService.selectLiveOrderLogsList(liveOrderLogs);
+        ExcelUtil<LiveOrderLogs> util = new ExcelUtil<LiveOrderLogs>(LiveOrderLogs.class);
+        return util.exportExcel(list, "订单操作记录数据");
+    }
+
+    /**
+     * 获取订单操作记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:query')")
+    @GetMapping(value = "/{logsId}")
+    public AjaxResult getInfo(@PathVariable("logsId") String logsId)
+    {
+        return AjaxResult.success(liveOrderLogsService.selectLiveOrderLogsByLogsId(logsId));
+    }
+
+    /**
+     * 新增订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:add')")
+    @Log(title = "订单操作记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveOrderLogs liveOrderLogs)
+    {
+        return toAjax(liveOrderLogsService.insertLiveOrderLogs(liveOrderLogs));
+    }
+
+    /**
+     * 修改订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:edit')")
+    @Log(title = "订单操作记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveOrderLogs liveOrderLogs)
+    {
+        return toAjax(liveOrderLogsService.updateLiveOrderLogs(liveOrderLogs));
+    }
+
+    /**
+     * 删除订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:remove')")
+    @Log(title = "订单操作记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{logsIds}")
+    public AjaxResult remove(@PathVariable String[] logsIds)
+    {
+        return toAjax(liveOrderLogsService.deleteLiveOrderLogsByLogsIds(logsIds));
+    }
+}

+ 40 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveProfitController.java

@@ -0,0 +1,40 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.live.service.ILiveUserFirstEntryService;
+import com.fs.live.vo.LiveUserFirstProfit;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.List;
+
+import static com.github.pagehelper.page.PageMethod.startPage;
+
+/**
+ * 业绩归属控制类Controller
+ *
+ * @author fs
+ * @date 2025-09-08
+ */
+@RestController
+@RequestMapping("/live/liveProfit")
+public class LiveProfitController extends BaseController {
+
+    @Autowired
+    private ILiveUserFirstEntryService liveUserFirstEntryService;
+
+    @GetMapping("/list")
+    public TableDataInfo list() {
+        startPage();
+        List<LiveUserFirstProfit> list = liveUserFirstEntryService.selectLiveProfitList();
+        return getDataTable(list);
+    }
+
+}

+ 115 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveRedConfController.java

@@ -0,0 +1,115 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveRedConf;
+import com.fs.live.service.ILiveRedConfService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播红包记录配置Controller
+ *
+ * @author fs
+ * @date 2025-07-17
+ */
+@RestController
+@RequestMapping("/live/liveRedConf")
+public class LiveRedConfController extends BaseController
+{
+    @Autowired
+    private ILiveRedConfService liveRedConfService;
+
+    /**
+     * 查询直播红包记录配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveRedConf liveRedConf)
+    {
+        startPage();
+        List<LiveRedConf> list = liveRedConfService.selectLiveRedConfList(liveRedConf);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播红包记录配置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:export')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveRedConf liveRedConf)
+    {
+        List<LiveRedConf> list = liveRedConfService.selectLiveRedConfList(liveRedConf);
+        ExcelUtil<LiveRedConf> util = new ExcelUtil<LiveRedConf>(LiveRedConf.class);
+        return util.exportExcel(list, "直播红包记录配置数据");
+    }
+
+    /**
+     * 获取直播红包记录配置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:query')")
+    @GetMapping(value = "/{redId}")
+    public AjaxResult getInfo(@PathVariable("redId") Long redId)
+    {
+        return AjaxResult.success(liveRedConfService.selectLiveRedConfByRedId(redId));
+    }
+
+    /**
+     * 新增直播红包记录配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:add')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveRedConf liveRedConf)
+    {
+        return toAjax(liveRedConfService.insertLiveRedConf(liveRedConf));
+    }
+
+    /**
+     * 修改直播红包记录配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:edit')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody LiveRedConf liveRedConf)
+    {
+        liveRedConfService.updateLiveRedConf(liveRedConf);
+        return R.ok(liveRedConf.getRedStatus().toString());
+    }
+
+    /**
+     * 删除直播红包记录配置
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveRedConf:remove')")
+    @Log(title = "直播红包记录配置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{redIds}")
+    public AjaxResult remove(@PathVariable Long[] redIds)
+    {
+        return toAjax(liveRedConfService.deleteLiveRedConfByRedIds(redIds));
+    }
+
+    @GetMapping("/live/{liveId}")
+    public List<LiveRedConf> getByLiveId(@PathVariable Long liveId) {
+        return liveRedConfService.getByLiveId(liveId);
+    }
+
+    /**
+     * 点击发放红包
+     * */
+    @PostMapping("/start/{redId}")
+    public String start(@PathVariable String redId) {
+        return liveRedConfService.start(redId,getUserId());
+    }
+
+
+
+}

+ 104 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveRewardRecordController.java

@@ -0,0 +1,104 @@
+package com.fs.company.controller.live;
+
+import java.util.List;
+
+import com.fs.live.domain.LiveRewardRecord;
+import com.fs.live.service.ILiveRewardRecordService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户直播间奖励记录Controller
+ *
+ * @author fs
+ * @date 2025-08-27
+ */
+@RestController
+@RequestMapping("/live/record")
+public class LiveRewardRecordController extends BaseController
+{
+    @Autowired
+    private ILiveRewardRecordService liveRewardRecordService;
+
+    /**
+     * 查询用户直播间奖励记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveRewardRecord liveRewardRecord)
+    {
+        startPage();
+        List<LiveRewardRecord> list = liveRewardRecordService.selectLiveRewardRecordList(liveRewardRecord);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播间奖励记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:export')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveRewardRecord liveRewardRecord)
+    {
+        List<LiveRewardRecord> list = liveRewardRecordService.selectLiveRewardRecordList(liveRewardRecord);
+        ExcelUtil<LiveRewardRecord> util = new ExcelUtil<LiveRewardRecord>(LiveRewardRecord.class);
+        return util.exportExcel(list, "用户直播间奖励记录数据");
+    }
+
+    /**
+     * 获取用户直播间奖励记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveRewardRecordService.selectLiveRewardRecordById(id));
+    }
+
+    /**
+     * 新增用户直播间奖励记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:add')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveRewardRecord liveRewardRecord)
+    {
+        return toAjax(liveRewardRecordService.insertLiveRewardRecord(liveRewardRecord));
+    }
+
+    /**
+     * 修改用户直播间奖励记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:edit')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveRewardRecord liveRewardRecord)
+    {
+        return toAjax(liveRewardRecordService.updateLiveRewardRecord(liveRewardRecord));
+    }
+
+    /**
+     * 删除用户直播间奖励记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:record:remove')")
+    @Log(title = "用户直播间奖励记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveRewardRecordService.deleteLiveRewardRecordByIds(ids));
+    }
+}

+ 104 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveSensitiveWordsController.java

@@ -0,0 +1,104 @@
+package com.fs.company.controller.live;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveSensitiveWords;
+import com.fs.live.service.ILiveSensitiveWordsService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播间敏感词过滤Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/words")
+public class LiveSensitiveWordsController extends BaseController
+{
+    @Autowired
+    private ILiveSensitiveWordsService liveSensitiveWordsService;
+
+    /**
+     * 查询直播间敏感词过滤列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveSensitiveWords liveSensitiveWords)
+    {
+        startPage();
+        List<LiveSensitiveWords> list = liveSensitiveWordsService.selectLiveSensitiveWordsList(liveSensitiveWords);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播间敏感词过滤列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:export')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveSensitiveWords liveSensitiveWords)
+    {
+        List<LiveSensitiveWords> list = liveSensitiveWordsService.selectLiveSensitiveWordsList(liveSensitiveWords);
+        ExcelUtil<LiveSensitiveWords> util = new ExcelUtil<LiveSensitiveWords>(LiveSensitiveWords.class);
+        return util.exportExcel(list, "直播间敏感词过滤数据");
+    }
+
+    /**
+     * 获取直播间敏感词过滤详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:query')")
+    @GetMapping(value = "/{wordId}")
+    public AjaxResult getInfo(@PathVariable("wordId") Long wordId)
+    {
+        return AjaxResult.success(liveSensitiveWordsService.selectLiveSensitiveWordsByWordId(wordId));
+    }
+
+    /**
+     * 新增直播间敏感词过滤
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:add')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveSensitiveWords liveSensitiveWords)
+    {
+
+        return toAjax(liveSensitiveWordsService.insertLiveSensitiveWords(liveSensitiveWords));
+    }
+
+    /**
+     * 修改直播间敏感词过滤
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:edit')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveSensitiveWords liveSensitiveWords)
+    {
+        return toAjax(liveSensitiveWordsService.updateLiveSensitiveWords(liveSensitiveWords));
+    }
+
+    /**
+     * 删除直播间敏感词过滤
+     */
+    @PreAuthorize("@ss.hasPermi('live:words:remove')")
+    @Log(title = "直播间敏感词过滤", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{wordIds}")
+    public AjaxResult remove(@PathVariable Long[] wordIds)
+    {
+        return toAjax(liveSensitiveWordsService.deleteLiveSensitiveWordsByWordIds(wordIds));
+    }
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveUserFavoriteController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveUserFavorite;
+import com.fs.live.service.ILiveUserFavoriteService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 用户直播收藏Controller
+ *
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/live/liveUserFavorite")
+public class LiveUserFavoriteController extends BaseController
+{
+    @Autowired
+    private ILiveUserFavoriteService liveUserFavoriteService;
+
+    /**
+     * 查询用户直播收藏列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFavorite liveUserFavorite)
+    {
+        startPage();
+        List<LiveUserFavorite> list = liveUserFavoriteService.selectLiveUserFavoriteList(liveUserFavorite);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播收藏列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:export')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFavorite liveUserFavorite)
+    {
+        List<LiveUserFavorite> list = liveUserFavoriteService.selectLiveUserFavoriteList(liveUserFavorite);
+        ExcelUtil<LiveUserFavorite> util = new ExcelUtil<LiveUserFavorite>(LiveUserFavorite.class);
+        return util.exportExcel(list, "用户直播收藏数据");
+    }
+
+    /**
+     * 获取用户直播收藏详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:query')")
+    @GetMapping(value = "/{favoriteId}")
+    public AjaxResult getInfo(@PathVariable("favoriteId") Long favoriteId)
+    {
+        return AjaxResult.success(liveUserFavoriteService.selectLiveUserFavoriteByFavoriteId(favoriteId));
+    }
+
+    /**
+     * 新增用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:add')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFavorite liveUserFavorite)
+    {
+        return toAjax(liveUserFavoriteService.insertLiveUserFavorite(liveUserFavorite));
+    }
+
+    /**
+     * 修改用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:edit')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFavorite liveUserFavorite)
+    {
+        return toAjax(liveUserFavoriteService.updateLiveUserFavorite(liveUserFavorite));
+    }
+
+    /**
+     * 删除用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:remove')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{favoriteIds}")
+    public AjaxResult remove(@PathVariable Long[] favoriteIds)
+    {
+        return toAjax(liveUserFavoriteService.deleteLiveUserFavoriteByFavoriteIds(favoriteIds));
+    }
+}

+ 103 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveUserFirstEntryController.java

@@ -0,0 +1,103 @@
+package com.fs.company.controller.live;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveUserFirstEntry;
+import com.fs.live.service.ILiveUserFirstEntryService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 用户每日首次进入直播间记录Controller
+ *
+ * @author fs
+ * @date 2025-09-04
+ */
+@RestController
+@RequestMapping("/live/entry")
+public class LiveUserFirstEntryController extends BaseController
+{
+    @Autowired
+    private ILiveUserFirstEntryService liveUserFirstEntryService;
+
+    /**
+     * 查询用户每日首次进入直播间记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:entry:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFirstEntry liveUserFirstEntry)
+    {
+        startPage();
+        List<LiveUserFirstEntry> list = liveUserFirstEntryService.selectLiveUserFirstEntryList(liveUserFirstEntry);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户每日首次进入直播间记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:entry:export')")
+    @Log(title = "用户每日首次进入直播间记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFirstEntry liveUserFirstEntry)
+    {
+        List<LiveUserFirstEntry> list = liveUserFirstEntryService.selectLiveUserFirstEntryList(liveUserFirstEntry);
+        ExcelUtil<LiveUserFirstEntry> util = new ExcelUtil<LiveUserFirstEntry>(LiveUserFirstEntry.class);
+        return util.exportExcel(list, "用户每日首次进入直播间记录数据");
+    }
+
+    /**
+     * 获取用户每日首次进入直播间记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:entry:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserFirstEntryService.selectLiveUserFirstEntryById(id));
+    }
+
+    /**
+     * 新增用户每日首次进入直播间记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:entry:add')")
+    @Log(title = "用户每日首次进入直播间记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFirstEntry liveUserFirstEntry)
+    {
+        return toAjax(liveUserFirstEntryService.insertLiveUserFirstEntry(liveUserFirstEntry));
+    }
+
+    /**
+     * 修改用户每日首次进入直播间记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:entry:edit')")
+    @Log(title = "用户每日首次进入直播间记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFirstEntry liveUserFirstEntry)
+    {
+        return toAjax(liveUserFirstEntryService.updateLiveUserFirstEntry(liveUserFirstEntry));
+    }
+
+    /**
+     * 删除用户每日首次进入直播间记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:entry:remove')")
+    @Log(title = "用户每日首次进入直播间记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserFirstEntryService.deleteLiveUserFirstEntryByIds(ids));
+    }
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveUserFollowController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveUserFollow;
+import com.fs.live.service.ILiveUserFollowService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 用户直播关注Controller
+ *
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/live/liveUserFollow")
+public class LiveUserFollowController extends BaseController
+{
+    @Autowired
+    private ILiveUserFollowService liveUserFollowService;
+
+    /**
+     * 查询用户直播关注列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFollow liveUserFollow)
+    {
+        startPage();
+        List<LiveUserFollow> list = liveUserFollowService.selectLiveUserFollowList(liveUserFollow);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播关注列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:export')")
+    @Log(title = "用户直播关注", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFollow liveUserFollow)
+    {
+        List<LiveUserFollow> list = liveUserFollowService.selectLiveUserFollowList(liveUserFollow);
+        ExcelUtil<LiveUserFollow> util = new ExcelUtil<LiveUserFollow>(LiveUserFollow.class);
+        return util.exportExcel(list, "用户直播关注数据");
+    }
+
+    /**
+     * 获取用户直播关注详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserFollowService.selectLiveUserFollowById(id));
+    }
+
+    /**
+     * 新增用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:add')")
+    @Log(title = "用户直播关注", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFollow liveUserFollow)
+    {
+        return toAjax(liveUserFollowService.insertLiveUserFollow(liveUserFollow));
+    }
+
+    /**
+     * 修改用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:edit')")
+    @Log(title = "用户直播关注", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFollow liveUserFollow)
+    {
+        return toAjax(liveUserFollowService.updateLiveUserFollow(liveUserFollow));
+    }
+
+    /**
+     * 删除用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:remove')")
+    @Log(title = "用户直播关注", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserFollowService.deleteLiveUserFollowByIds(ids));
+    }
+}

+ 97 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveUserLikeController.java

@@ -0,0 +1,97 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveUserLike;
+import com.fs.live.service.ILiveUserLikeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 用户直播赞Controller
+ *
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/live/liveUserLike")
+public class LiveUserLikeController extends BaseController
+{
+    @Autowired
+    private ILiveUserLikeService liveUserLikeService;
+
+    /**
+     * 查询用户直播赞列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserLike liveUserLike)
+    {
+        startPage();
+        List<LiveUserLike> list = liveUserLikeService.selectLiveUserLikeList(liveUserLike);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播赞列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:export')")
+    @Log(title = "用户直播赞", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserLike liveUserLike)
+    {
+        List<LiveUserLike> list = liveUserLikeService.selectLiveUserLikeList(liveUserLike);
+        ExcelUtil<LiveUserLike> util = new ExcelUtil<LiveUserLike>(LiveUserLike.class);
+        return util.exportExcel(list, "用户直播赞数据");
+    }
+
+    /**
+     * 获取用户直播赞详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserLikeService.selectLiveUserLikeById(id));
+    }
+
+    /**
+     * 新增用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:add')")
+    @Log(title = "用户直播赞", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserLike liveUserLike)
+    {
+        return toAjax(liveUserLikeService.insertLiveUserLike(liveUserLike));
+    }
+
+    /**
+     * 修改用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:edit')")
+    @Log(title = "用户直播赞", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserLike liveUserLike)
+    {
+        return toAjax(liveUserLikeService.updateLiveUserLike(liveUserLike));
+    }
+
+    /**
+     * 删除用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:remove')")
+    @Log(title = "用户直播赞", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserLikeService.deleteLiveUserLikeByIds(ids));
+    }
+}

+ 107 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveVideoController.java

@@ -0,0 +1,107 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveVideo;
+import com.fs.live.service.ILiveVideoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播视频Controller
+ *
+ * @author fs
+ * @date 2025-01-17
+ */
+@RestController
+@RequestMapping("/live/liveVideo")
+public class LiveVideoController extends BaseController
+{
+    @Autowired
+    private ILiveVideoService liveVideoService;
+
+    /**
+     * 查询直播视频列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveVideo liveVideo)
+    {
+        startPage();
+        List<LiveVideo> list = liveVideoService.selectLiveVideoList(liveVideo);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播视频列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:export')")
+    @Log(title = "直播视频", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveVideo liveVideo)
+    {
+        List<LiveVideo> list = liveVideoService.selectLiveVideoList(liveVideo);
+        ExcelUtil<LiveVideo> util = new ExcelUtil<LiveVideo>(LiveVideo.class);
+        return util.exportExcel(list, "直播视频数据");
+    }
+
+    /**
+     * 获取直播视频详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:query')")
+    @GetMapping(value = "/{videoId}")
+    public AjaxResult getInfo(@PathVariable("videoId") Long videoId)
+    {
+        return AjaxResult.success(liveVideoService.selectLiveVideoByLiveId(videoId));
+    }
+
+    /**
+     * 获取直播视频详细信息
+     */
+    @GetMapping(value = "/liveVideoByLiveId/{liveId}")
+    public AjaxResult getLiveVideoByLiveId(@PathVariable("liveId") Long liveId)
+    {
+        return AjaxResult.success(liveVideoService.selectLiveVideoByLiveId(liveId));
+    }
+
+    /**
+     * 新增直播视频
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:add')")
+    @Log(title = "直播视频", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveVideo liveVideo)
+    {
+        return toAjax(liveVideoService.insertLiveVideo(liveVideo));
+    }
+
+    /**
+     * 修改直播视频
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:edit')")
+    @Log(title = "直播视频", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveVideo liveVideo)
+    {
+        return toAjax(liveVideoService.updateLiveVideo(liveVideo));
+    }
+
+    /**
+     * 删除直播视频
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveVideo:remove')")
+    @Log(title = "直播视频", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{videoIds}")
+    public AjaxResult remove(@PathVariable Long[] videoIds)
+    {
+        return toAjax(liveVideoService.deleteLiveVideoByVideoIds(videoIds));
+    }
+
+}

+ 113 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveWatchConfigController.java

@@ -0,0 +1,113 @@
+package com.fs.company.controller.live;
+
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.fastjson.JSON;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.utils.ServletUtils;
+import com.fs.framework.service.TokenService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.live.domain.LiveWatchConfig;
+import com.fs.live.service.ILiveWatchConfigService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 直播观看奖励设置Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/config")
+public class LiveWatchConfigController extends BaseController
+{
+    @Autowired
+    private ILiveWatchConfigService liveWatchConfigService;
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询直播观看奖励设置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveWatchConfig liveWatchConfig)
+    {
+        startPage();
+        List<LiveWatchConfig> list = liveWatchConfigService.selectLiveWatchConfigList(liveWatchConfig);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播观看奖励设置列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:export')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveWatchConfig liveWatchConfig)
+    {
+        List<LiveWatchConfig> list = liveWatchConfigService.selectLiveWatchConfigList(liveWatchConfig);
+        ExcelUtil<LiveWatchConfig> util = new ExcelUtil<LiveWatchConfig>(LiveWatchConfig.class);
+        return util.exportExcel(list, "直播观看奖励设置数据");
+    }
+
+    /**
+     * 获取直播观看奖励设置详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success("",liveWatchConfigService.selectLiveWatchConfigByLiveId(id));
+    }
+
+    /**
+     * 新增直播观看奖励设置
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:add')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody String jsonConfig)
+    {
+        String userId = tokenService.getLoginUser(ServletUtils.getRequest()).getUser().getUserId().toString();
+        return toAjax(liveWatchConfigService.insertLiveWatchConfig(userId, jsonConfig));
+    }
+
+    /**
+     * 修改直播观看奖励设置
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:edit')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody String jsonConfig)
+    {
+        return toAjax(liveWatchConfigService.updateLiveWatchConfig(jsonConfig));
+    }
+
+    /**
+     * 删除直播观看奖励设置
+     */
+    @PreAuthorize("@ss.hasPermi('live:config:remove')")
+    @Log(title = "直播观看奖励设置", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+
+        return toAjax(liveWatchConfigService.deleteLiveWatchConfigByIds(ids));
+    }
+}

+ 132 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveWatchUserController.java

@@ -0,0 +1,132 @@
+package com.fs.company.controller.live;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveWatchUser;
+import com.fs.live.service.ILiveWatchUserService;
+import com.fs.live.vo.LiveWatchUserVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播间观看用户Controller
+ *
+ * @author fs
+ * @date 2025-01-18
+ */
+@RestController
+@RequestMapping("/live/liveWatchUser")
+public class LiveWatchUserController extends BaseController
+{
+    @Autowired
+    private ILiveWatchUserService liveWatchUserService;
+
+    /**
+     * 查询直播间观看用户列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveWatchUser liveWatchUser)
+    {
+        startPage();
+        List<LiveWatchUser> list = liveWatchUserService.selectLiveWatchUserList(liveWatchUser);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:list')")
+    @GetMapping("/watchUserList")
+    public TableDataInfo watchUserList(@RequestParam Long liveId) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+
+        startPage();
+        List<LiveWatchUserVO> onLineUserList = liveWatchUserService.selectWatchUserList(params);
+        return getDataTable(onLineUserList);
+    }
+
+    /**
+     * 导出直播间观看用户列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:export')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveWatchUser liveWatchUser)
+    {
+        List<LiveWatchUser> list = liveWatchUserService.selectLiveWatchUserList(liveWatchUser);
+        ExcelUtil<LiveWatchUser> util = new ExcelUtil<LiveWatchUser>(LiveWatchUser.class);
+        return util.exportExcel(list, "直播间观看用户数据");
+    }
+
+    /**
+     * 获取直播间观看用户详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveWatchUserService.selectLiveWatchUserById(id));
+    }
+
+    /**
+     * 新增直播间观看用户
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:add')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveWatchUser liveWatchUser)
+    {
+        return toAjax(liveWatchUserService.insertLiveWatchUser(liveWatchUser));
+    }
+
+    /**
+     * 修改直播间观看用户
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveWatchUser liveWatchUser)
+    {
+        return toAjax(liveWatchUserService.updateLiveWatchUser(liveWatchUser));
+    }
+
+    /**
+     * 删除直播间观看用户
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:remove')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveWatchUserService.deleteLiveWatchUserByIds(ids));
+    }
+
+    /**
+     * 修改直播间用户禁言状态
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeUserState")
+    public AjaxResult changeUserState(@RequestParam Long liveId, @RequestParam Long userId) {
+        return toAjax(liveWatchUserService.changeUserState(liveId, userId));
+    }
+
+    /**
+     * 封禁用户账号
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @GetMapping("/blockUser/{userId}")
+    public AjaxResult blockUser(@PathVariable Long userId) {
+        return toAjax(liveWatchUserService.blockUser(userId));
+    }
+
+}

+ 2 - 1
fs-company/src/main/java/com/fs/company/controller/store/FsStoreProductController.java

@@ -47,8 +47,9 @@ public class FsStoreProductController extends BaseController
      */
 
     @GetMapping("/list")
-    public TableDataInfo list(FsStoreProduct fsStoreProduct)
+    public TableDataInfo list(FsStoreProduct fsStoreProduct, @RequestParam(required = false) String liveId)
     {
+        fsStoreProduct.setLiveId(liveId);
         startPage();
         List<FsStoreProductVO> list = fsStoreProductService.selectFsStoreProductListVO(fsStoreProduct);
         return getDataTable(list);

+ 141 - 0
fs-live-app/src/main/java/com/fs/app/config/ProductionWordFilter.java

@@ -0,0 +1,141 @@
+package com.fs.app.config;
+
+import com.fs.common.utils.spring.SpringUtils;
+import com.fs.live.service.ILiveSensitiveWordsService;
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class ProductionWordFilter implements InitializingBean {
+
+    @Autowired
+    private ILiveSensitiveWordsService liveSensitiveWordsService;
+
+
+    private static class TrieNode {
+        @Getter
+        private final Map<Character, TrieNode> children = new HashMap<>();
+        private boolean isEndOfWord;
+
+        public boolean isEndOfWord() {
+            return isEndOfWord;
+        }
+
+        public void setEndOfWord(boolean endOfWord) {
+            isEndOfWord = endOfWord;
+        }
+
+    }
+    @Getter
+    private static class MatchResult {
+        private final String word;
+        private final int endIndex;
+
+        public MatchResult(String word, int endIndex) {
+            this.word = word;
+            this.endIndex = endIndex;
+        }
+
+        public int getLength() {
+            return word.length();
+        }
+    }
+
+    @Getter
+    public static class FilterResult {
+        private final String filteredText;
+        private final Set<String> matchedWords;
+        private final int replacedCount;
+
+        public FilterResult(String filteredText, Set<String> matchedWords, int replacedCount) {
+            this.filteredText = filteredText;
+            this.matchedWords = matchedWords;
+            this.replacedCount = replacedCount;
+        }
+
+    }
+
+    private TrieNode root = new TrieNode();
+    private List<String> wordSources;
+    private final ScheduledExecutorService executor;
+
+    public ProductionWordFilter(List<String> wordSources) {
+        this.wordSources = wordSources;
+        this.executor = Executors.newSingleThreadScheduledExecutor();
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        reload();
+        executor.scheduleWithFixedDelay(this::reload, 1, 1, TimeUnit.HOURS);
+    }
+
+    public synchronized void reload() {
+        wordSources = liveSensitiveWordsService.selectAllWords();
+        TrieNode newRoot = new TrieNode();
+        wordSources.stream()
+                .flatMap(source -> loadWords(source).stream())
+                .forEach(word -> addWord(newRoot, word));
+        this.root = newRoot;
+    }
+
+    public FilterResult filter(String text) {
+        StringBuilder result = new StringBuilder();
+        Set<String> foundWords = new HashSet<>();
+        int replacedCount = 0;
+
+        for (int i = 0; i < text.length(); ) {
+            MatchResult match = findNextMatch(text, i);
+            if (match != null) {
+                foundWords.add(match.getWord());
+                result.append(StringUtils.repeat("", match.getLength()));
+                replacedCount++;
+                i = match.getEndIndex();
+            } else {
+                result.append(text.charAt(i));
+                i++;
+            }
+        }
+
+        return new FilterResult(result.toString(), foundWords, replacedCount);
+    }
+
+
+    private MatchResult findNextMatch(String text, int start) {
+        TrieNode current = root;
+        for (int i = start; i < text.length(); i++) {
+            char c = text.charAt(i);
+            if (!current.getChildren().containsKey(c)) {
+                return null;
+            }
+            current = current.getChildren().get(c);
+            if (current.isEndOfWord()) {
+                return new MatchResult(text.substring(start, i + 1), i + 1);
+            }
+        }
+        return null;
+    }
+
+    private void addWord(TrieNode root, String word) {
+        TrieNode node = root;
+        for (char c : word.toCharArray()) {
+            node = node.getChildren().computeIfAbsent(c, k -> new TrieNode());
+        }
+        node.setEndOfWord(true);
+    }
+
+    private List<String> loadWords(String source) {
+        // 示例:实际应从 source(如 URL 或文件路径)读取
+        return Collections.singletonList(source); // 替换为真实逻辑
+    }
+
+
+}

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

@@ -2,11 +2,22 @@ package com.fs.app.controller;
 
 
 import com.fs.app.utils.JwtUtils;
+import com.fs.common.constant.HttpStatus;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.PageDomain;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.core.page.TableSupport;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.sql.SqlUtil;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import io.jsonwebtoken.Claims;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.List;
+
 
 public class AppBaseController {
 	@Autowired
@@ -14,9 +25,95 @@ public class AppBaseController {
 
 	public String getUserId()
 	{
-		String headValue =  ServletUtils.getRequest().getHeader("APPToken");
+		String headValue =  ServletUtils.getRequest().getHeader("AppToken");
+		if (StringUtils.isEmpty(headValue))
+			headValue = ServletUtils.getRequest().getParameter("APPToken");
 		Claims claims=jwtUtils.getClaimByToken(headValue);
 		String userId = claims.getSubject().toString();
 		return userId;
 	}
+
+	/**
+	 * 响应请求分页数据
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	protected TableDataInfo getDataTable(List<?> list)
+	{
+		TableDataInfo rspData = new TableDataInfo();
+		rspData.setCode(HttpStatus.SUCCESS);
+		rspData.setMsg("查询成功");
+		rspData.setRows(list);
+		rspData.setTotal(new PageInfo(list).getTotal());
+		return rspData;
+	}
+
+	/**
+	 * 设置请求分页数据
+	 */
+	protected void startPage()
+	{
+		PageDomain pageDomain = TableSupport.buildPageRequest();
+		Integer pageNum = pageDomain.getPageNum();
+		Integer pageSize = pageDomain.getPageSize();
+		if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
+		{
+			String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
+			Boolean reasonable = pageDomain.getReasonable();
+			PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
+		}
+	}
+
+	/**
+	 * 响应返回结果
+	 *
+	 * @param rows 影响行数
+	 * @return 操作结果
+	 */
+	protected AjaxResult toAjax(int rows)
+	{
+		return rows > 0 ? AjaxResult.success() : AjaxResult.error();
+	}
+
+	/**
+	 * 响应返回结果
+	 *
+	 * @param result 结果
+	 * @return 操作结果
+	 */
+	protected AjaxResult toAjax(boolean result)
+	{
+		return result ? success() : error();
+	}
+
+	/**
+	 * 返回成功
+	 */
+	public AjaxResult success()
+	{
+		return AjaxResult.success();
+	}
+
+	/**
+	 * 返回失败消息
+	 */
+	public AjaxResult error()
+	{
+		return AjaxResult.error();
+	}
+
+	/**
+	 * 返回成功消息
+	 */
+	public AjaxResult success(String message)
+	{
+		return AjaxResult.success(message);
+	}
+
+	/**
+	 * 返回失败消息
+	 */
+	public AjaxResult error(String message)
+	{
+		return AjaxResult.error(message);
+	}
 }

+ 97 - 0
fs-live-app/src/main/java/com/fs/app/controller/CaptchaController.java

@@ -0,0 +1,97 @@
+package com.fs.app.controller;
+
+import com.fs.common.constant.Constants;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.sign.Base64;
+import com.fs.common.utils.uuid.IdUtils;
+import com.fs.system.service.ISysConfigService;
+import com.google.code.kaptcha.Producer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.FastByteArrayOutputStream;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletResponse;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 验证码操作处理
+ *
+
+ */
+@RestController
+public class CaptchaController
+{
+    @Resource(name = "captchaProducer")
+    private Producer captchaProducer;
+
+    @Resource(name = "captchaProducerMath")
+    private Producer captchaProducerMath;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    // 验证码类型
+    @Value("${fs.captchaType}")
+    private String captchaType;
+
+    @Autowired
+    private ISysConfigService configService;
+    /**
+     * 生成验证码
+     */
+    @GetMapping("/captchaImage")
+    public AjaxResult getCode(HttpServletResponse response) throws IOException
+    {
+        AjaxResult ajax = AjaxResult.success();
+        boolean captchaOnOff = configService.selectCaptchaOnOff();
+        ajax.put("captchaOnOff", captchaOnOff);
+        if (!captchaOnOff)
+        {
+            return ajax;
+        }
+
+        // 保存验证码信息
+        String uuid = IdUtils.simpleUUID();
+        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+
+        String capStr = null, code = null;
+        BufferedImage image = null;
+
+        // 生成验证码
+        if ("math".equals(captchaType))
+        {
+            String capText = captchaProducerMath.createText();
+            capStr = capText.substring(0, capText.lastIndexOf("@"));
+            code = capText.substring(capText.lastIndexOf("@") + 1);
+            image = captchaProducerMath.createImage(capStr);
+        }
+        else if ("char".equals(captchaType))
+        {
+            capStr = code = captchaProducer.createText();
+            image = captchaProducer.createImage(capStr);
+        }
+
+        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+        // 转换流信息写出
+        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
+        try
+        {
+            ImageIO.write(image, "jpg", os);
+        }
+        catch (IOException e)
+        {
+            return AjaxResult.error(e.getMessage());
+        }
+
+        ajax.put("uuid", uuid);
+        ajax.put("img", Base64.encode(os.toByteArray()));
+        return ajax;
+    }
+}

+ 42 - 0
fs-live-app/src/main/java/com/fs/app/controller/CommonController.java

@@ -2,19 +2,30 @@ package com.fs.app.controller;
 
 
 import com.alibaba.fastjson.JSON;
+import com.fs.app.utils.CityTreeUtil;
+import com.fs.app.vo.CityVO;
 import com.fs.app.websocket.bean.SendMsgVo;
 import com.fs.app.websocket.service.WebSocketServer;
 import com.fs.common.core.domain.R;
 import com.fs.company.service.ICompanyWxChatService;
+import com.fs.his.domain.FsCity;
+import com.fs.his.service.IFsCityService;
+import com.fs.system.service.ISysDictDataService;
+import com.fs.system.vo.DictVO;
 import com.fs.wxUser.domain.CompanyWxUser;
 import com.fs.wxUser.service.ICompanyWxUserService;
+import com.google.common.collect.Lists;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import jdk.nashorn.internal.ir.annotations.Ignore;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Arrays;
+import java.util.List;
 
 
 @Slf4j
@@ -29,6 +40,12 @@ public class CommonController {
     private final ICompanyWxUserService companyWxUserService;
     private final ICompanyWxChatService companyWxChatService;
 
+    @Autowired
+    private IFsCityService cityService;
+
+    @Autowired
+    private ISysDictDataService dictDataService;
+
     @GetMapping("/testSend")
     public R testSend(Long userId, String msg) throws Exception{
         return R.ok();
@@ -39,5 +56,30 @@ public class CommonController {
         return R.ok();
     }
 
+    @ApiOperation("获取城市数据")
+    @GetMapping("/getCitys")
+    @Cacheable("cityData")
+    public R getCitys(){
+        List<FsCity> list=cityService.selectFsCityList(new FsCity());
+        List<CityVO> cityVOS = Lists.newArrayList();
+        for (FsCity city : list){
+            CityVO cityVO = new CityVO();
+            cityVO.setV(city.getCityId());
+            cityVO.setN(city.getCityName());
+            cityVO.setPid(city.getParentId());
+            cityVOS.add(cityVO);
+        }
+        return R.ok().put("data", CityTreeUtil.list2TreeConverter(cityVOS, "0"));
+
+    }
+
+    @ApiOperation("获取数据字典")
+    @GetMapping("/getDictByKey")
+    @Cacheable(value="dicts", key="#key")
+    public R getDictByKey(@RequestParam(value = "key", required = false) String key){
+        List<DictVO> dicts=dictDataService.selectDictDataListByType(key);
+        return R.ok().put("data",dicts);
+    }
+
 
 }

+ 69 - 0
fs-live-app/src/main/java/com/fs/app/controller/FsStoreController.java

@@ -0,0 +1,69 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.his.domain.FsStoreProduct;
+import com.fs.his.service.IFsStoreService;
+import com.fs.live.domain.LiveGoods;
+import com.fs.live.service.ILiveGoodsService;
+import com.fs.live.vo.FsStoreLiveVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 店铺管理Controller
+ *
+ * @author fs
+ * @date 2023-06-15
+ */
+@RestController
+@RequestMapping("/app/live/store")
+public class FsStoreController extends AppBaseController
+{
+    @Autowired
+    private IFsStoreService fsStoreService;
+    @Autowired
+    private ILiveGoodsService liveGoodsService;
+
+    /**
+     * 获取店铺管理详细信息(下面小黄车的商品)
+     */
+    @Login
+    @GetMapping("/{storeId}")
+    public AjaxResult getInfo(@PathVariable("storeId") Long storeId,@RequestParam String key,@RequestParam String liveId)
+    {
+        Map<String, Object> params = new HashMap<>();
+        params.put("storeId", storeId);
+        params.put("userId", getUserId());
+        params.put("productName", key);
+        params.put("liveId", liveId);
+        FsStoreLiveVO fsStore = fsStoreService.selectFsStoreLiveByMap(params);
+        if (Objects.nonNull(fsStore)) {
+            fsStore.setGoodsList(liveGoodsService.selectLiveGoodsListByMap(params));
+        }
+
+        return AjaxResult.success(fsStore);
+    }
+
+    /**
+     * 获取店铺所有产品
+     */
+    @Login
+    @GetMapping
+    public TableDataInfo getStoreProducts(LiveGoods storeId)
+    {
+        startPage();
+        List<FsStoreProduct> list = liveGoodsService.selectStoreProducts(storeId);
+        return getDataTable(list);
+    }
+
+
+
+}

+ 105 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveAfterSalesController.java

@@ -0,0 +1,105 @@
+package com.fs.app.controller;
+
+
+import com.fs.app.annotation.Login;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.ParseUtils;
+import com.fs.live.domain.LiveAfterSales;
+import com.fs.live.domain.LiveAfterSalesItem;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.param.LiveAfterSalesApplyParam;
+import com.fs.live.param.LiveAfterSalesDeliveryParam;
+import com.fs.live.param.LiveAfterSalesListUParam;
+import com.fs.live.param.LiveAfterSalesRevokeParam;
+import com.fs.live.service.ILiveAfterSalesItemService;
+import com.fs.live.service.ILiveAfterSalesService;
+import com.fs.live.service.ILiveOrderItemService;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.live.vo.LiveAfterSalesListUVO;
+import com.fs.live.vo.LiveOrderItemListUVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.ParseException;
+import java.util.List;
+
+
+@Api("售后接口")
+@RestController
+@RequestMapping(value="/app/live/storeAfterSales")
+public class LiveAfterSalesController extends  AppBaseController {
+
+    @Autowired
+    private ILiveAfterSalesService storeAfterSalesService;
+
+    @Autowired
+    private ILiveAfterSalesItemService salesItemService;
+    @Autowired
+    private ILiveOrderItemService itemService;
+    @Autowired
+    private ILiveOrderService orderService;
+    @Login
+    @ApiOperation("获取订单项列表")
+    @GetMapping("/getStoreOrderItems")
+    public R getStoreOrderItems(@RequestParam("orderId") Long orderId, HttpServletRequest request){
+        List<LiveOrderItemListUVO> list=itemService.selectLiveOrderItemListUVOByOrderId(orderId);
+        LiveOrder order=orderService.selectLiveOrderByOrderId(String.valueOf(orderId));
+        order.setUserPhone(ParseUtils.parsePhone(order.getUserPhone()));
+        order.setUserAddress(ParseUtils.parseIdCard(order.getUserAddress()));
+        return R.ok().put("order", order).put("items",list);
+    }
+
+
+    @Login
+    @PostMapping("/applyAfterSales")
+    @ApiOperation(value = "申请售后", notes = "申请售后")
+    @RepeatSubmit
+    public R applyAfterSales(@RequestBody LiveAfterSalesApplyParam param) {
+        return storeAfterSalesService.applyAfterSales(getUserId(), param);
+    }
+    @Login
+    @PostMapping("/revoke")
+    @ApiOperation(value = "撤销售后", notes = "撤销售后")
+    @RepeatSubmit
+    public R revoke(@RequestBody LiveAfterSalesRevokeParam param) throws ParseException {
+        return storeAfterSalesService.revoke(getUserId(), param);
+    }
+    @Login
+    @PostMapping("/addDelivery")
+    @ApiOperation(value = "提交物流信息", notes = "提交物流信息")
+    public R addDelivery(@Validated @RequestBody LiveAfterSalesDeliveryParam param) {
+        param.setUserId(Long.parseLong(getUserId()));
+        return storeAfterSalesService.addDelivery(param);
+    }
+
+
+    @Login
+    @GetMapping("/getStoreAfterSalesList")
+    @ApiOperation(value = "获取售后列表", notes = "获取售后列表")
+    public R getStoreAfterSalesList(LiveAfterSalesListUParam param) {
+        param.setUserId(Long.parseLong(getUserId()));
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        List<LiveAfterSalesListUVO> list=storeAfterSalesService.selectLiveAfterSalesListUVO(param);
+        PageInfo<LiveAfterSalesListUVO> listPageInfo=new PageInfo<>(list);
+        return R.ok().put("data",listPageInfo);
+    }
+    @Login
+    @GetMapping("/getStoreAfterSalesById")
+    @ApiOperation(value = "获取售后详情", notes = "获取售后详情")
+    public R getStoreAfterSalesById(@RequestParam("id") Long id) {
+        LiveAfterSales sales=storeAfterSalesService.selectLiveAfterSalesById(id);
+        LiveAfterSalesItem map=new LiveAfterSalesItem();
+        map.setAfterSalesId(id);
+        List<LiveAfterSalesItem>  items=salesItemService.selectLiveAfterSalesItemList(map);
+        LiveOrder order=orderService.selectLiveOrderByOrderId(String.valueOf(sales.getOrderId()));
+        return R.ok().put("sales",sales).put("items", items).put("order",order);
+    }
+
+}

+ 139 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveCartController.java

@@ -0,0 +1,139 @@
+package com.fs.app.controller;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fs.app.annotation.Login;
+import com.fs.common.annotation.Excel;
+import com.fs.common.annotation.Log;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveCart;
+import com.fs.live.service.ILiveCartService;
+import com.fs.live.vo.LiveCartVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 购物车Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveCart")
+@Api(tags = "购物车管理")
+public class LiveCartController extends AppBaseController
+{
+    @Autowired
+    private ILiveCartService liveCartService;
+
+    /**
+     * 查询购物车列表
+     */
+//    @PreAuthorize("@ss.hasPermi('live:liveCart:list')")
+    @GetMapping("/list")
+    @ApiOperation("查询购物车列表")
+    @Login
+    public TableDataInfo list(LiveCart liveCart)
+    {
+        liveCart.setUserId(String.valueOf(getUserId()));
+        startPage();
+        List<LiveCartVo> list = liveCartService.selectLiveCartListVo(liveCart);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出购物车列表
+     */
+//    @PreAuthorize("@ss.hasPermi('live:liveCart:export')")
+    @Log(title = "购物车", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    @ApiOperation("导出购物车列表")
+    @Login
+    public AjaxResult export(LiveCart liveCart)
+    {
+        List<LiveCart> list = liveCartService.selectLiveCartList(liveCart);
+        ExcelUtil<LiveCart> util = new ExcelUtil<LiveCart>(LiveCart.class);
+        return util.exportExcel(list, "购物车数据");
+    }
+
+    /**
+     * 获取购物车详细信息
+     */
+//    @PreAuthorize("@ss.hasPermi('live:liveCart:query')")
+    @GetMapping(value = "/{cardId}")
+    @ApiOperation("获取购物车详细信息")
+    @ApiImplicitParam(name = "cardId", value = "购物车ID", required = true, dataType = "Long", paramType = "path")
+    @Login
+    public AjaxResult getInfo(@PathVariable("cardId") Long cardId)
+    {
+        return AjaxResult.success(liveCartService.selectLiveCartByCartId(cardId));
+    }
+
+    /**
+     * 新增购物车
+     */
+//    @PreAuthorize("@ss.hasPermi('live:liveCart:add')")
+    @PostMapping
+    @ApiOperation("新增购物车")
+    @Login
+    @RepeatSubmit
+    public AjaxResult add(@RequestBody @ApiParam("购物车信息") LiveCart liveCart)
+    {
+        liveCart.setUserId(String.valueOf(getUserId()));
+        return toAjax(liveCartService.insertLiveCart(liveCart));
+    }
+
+    /**
+     * 修改购物车
+     */
+//    @PreAuthorize("@ss.hasPermi('live:liveCart:edit')")
+    @PostMapping("/update")
+    @ApiOperation("修改购物车")
+    @Login
+    @RepeatSubmit
+    public AjaxResult edit(@RequestBody @ApiParam("购物车信息") LiveCart liveCart)
+    {
+        liveCart.setUserId(String.valueOf(getUserId()));
+        return toAjax(liveCartService.updateLiveCart(liveCart));
+    }
+
+    /**
+     * 删除购物车
+     */
+//    @PreAuthorize("@ss.hasPermi('live:liveCart:remove')")
+	@PostMapping("/delete")
+    @ApiOperation("删除购物车")
+    @ApiImplicitParam(name = "cardIds", value = "购物车ID数组", required = true, dataType = "Long", paramType = "path")
+    @Login
+    public AjaxResult remove(@RequestBody Long[] cardIds)
+    {
+        return toAjax(liveCartService.deleteByCartIds(cardIds, Long.valueOf(getUserId())));
+    }
+
+    @GetMapping("/checked")
+    @ApiOperation("查询购物车列表")
+    @Login
+    public TableDataInfo getChecked(LiveCart liveCart)
+    {
+        liveCart.setUserId(String.valueOf(getUserId()));
+        startPage();
+        List<LiveCartVo> list = liveCartService.getChecked(liveCart);
+        return getDataTable(list);
+    }
+
+
+
+}

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

@@ -1,31 +1,47 @@
 package com.fs.app.controller;
 
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fs.aicall.utils.Md5Utils;
 import com.fs.app.annotation.Login;
 import com.fs.app.vo.LiveInfoVo;
 import com.fs.app.vo.LiveVo;
+import com.fs.app.websocket.bean.SendMsgVo;
+import com.fs.app.websocket.service.WebSocketServer;
+import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.BaseEntity;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.bean.BeanUtils;
-import com.fs.live.domain.Live;
-import com.fs.live.domain.LiveMsg;
-import com.fs.live.service.ILiveMsgService;
-import com.fs.live.service.ILiveService;
+import com.fs.his.service.IFsUserService;
+import com.fs.live.domain.*;
+import com.fs.live.service.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 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 org.apache.http.HttpRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Base64Utils;
+import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 @Api("直播信息接口")
@@ -34,9 +50,21 @@ import java.util.List;
 @RequestMapping(value="/app/live")
 public class LiveController extends AppBaseController {
 
+	private static final Logger log = LoggerFactory.getLogger(LiveController.class);
 	private final ILiveService liveService;
 	private final ILiveMsgService liveMsgService;
 
+	@Autowired
+	private WebSocketServer webSocketServer;
+
+	@Autowired
+	private ILiveGoodsService liveGoodsService;
+
+	@Autowired
+	private ILiveVideoService videoService;
+
+
+
 	@ApiOperation("直播封面信息")
 	@GetMapping("/liveInfo")
 	@ApiResponse(code = 200, message = "", response = LiveInfoVo.class)
@@ -51,7 +79,7 @@ public class LiveController extends AppBaseController {
 		return R.ok().put("data", vo);
 	}
 
-	@Login
+//	@Login
 	@ApiOperation("直播间")
 	@GetMapping("/live")
 	@ApiResponse(code = 200, message = "", response = LiveVo.class)
@@ -60,6 +88,7 @@ public class LiveController extends AppBaseController {
 		Live live = liveService.selectLiveByLiveId(id);
 		if(live == null) return R.error("未找到直播");
 		if(live.getIsShow() == 2) return R.error("直播未开放");
+		Long storeId = liveGoodsService.getStoreIdByLiveId(live.getLiveId());
 		LiveVo liveVo = new LiveVo();
 		BeanUtils.copyProperties(live, liveVo);
 		liveVo.setNowDuration(200L);
@@ -67,12 +96,34 @@ public class LiveController extends AppBaseController {
 			long seconds = live.getStartTime().until(now, ChronoUnit.SECONDS);
 			liveVo.setNowDuration(seconds);
 		}
-		if(liveVo.getNowDuration() != null){
-			liveVo.setNowPri(BigDecimal.valueOf(liveVo.getDuration()).divide(BigDecimal.valueOf(liveVo.getNowDuration()), 20, RoundingMode.UP));
-		}
-		return R.ok().put("data", liveVo);
+//		if(liveVo.getNowDuration() != null){
+//			liveVo.setNowPri(BigDecimal.valueOf(liveVo.getDuration()).divide(BigDecimal.valueOf(liveVo.getNowDuration()), 20, RoundingMode.UP));
+//		}
+		return R.ok().put("data", liveVo).put("storeId", storeId);
 	}
-	@Login
+
+//	@Login
+	@ApiOperation("直播间列表")
+	@GetMapping("/liveList")
+	@ApiResponse(code = 200, message = "", response = LiveInfoVo.class)
+	public TableDataInfo liveList() {
+		startPage();
+		return getDataTable(liveService.liveList());
+	}
+
+
+	@ApiOperation("直播间列表")
+	@GetMapping("/list")
+	@ApiResponse(code = 200, message = "", response = LiveInfoVo.class)
+	public TableDataInfo list(@RequestBody Live live) {
+		startPage();
+		return getDataTable(liveService.appList(live));
+	}
+
+
+
+
+//	@Login
 	@ApiOperation("聊天记录(最新30条)")
 	@GetMapping("/msgList")
 	@ApiResponse(code = 200, message = "", response = LiveInfoVo.class)
@@ -82,4 +133,110 @@ public class LiveController extends AppBaseController {
 		return R.ok().put("data", list);
 	}
 
+	@PostMapping("/create")
+	@RepeatSubmit
+	public R createRoom(@RequestBody Map<String, Object> payload) {
+		if (!payload.containsKey("liveId")) {
+			return R.error("直播间id缺失");
+		}
+		Long liveId = Long.valueOf(payload.get("liveId").toString());
+		return liveService.createLiveRoom(liveId);
+	}
+
+
+	@PostMapping("/checkLive")
+	public R checkLiving(@RequestBody Map<String, String> payload) {
+		// 销售端判断是否拥有直播权限
+		return liveService.checkLiving(payload);
+	}
+
+	@GetMapping("/{liveId}")
+	public R getRoom(@PathVariable String liveId) {
+		return liveService.getLiveRoom(liveId);
+	}
+
+
+	// 直播开播回调
+	@PostMapping("/startLiving")
+	public R checkLiving(HttpServletRequest request, @RequestBody  Map<String, String> params) {
+		log.info("请求参数:{}", params);
+		SendMsgVo sendMsgVo = new SendMsgVo();
+		sendMsgVo.setMsg("开始直播");
+		sendMsgVo.setCmd("live_start");
+		webSocketServer.broadcastMessage(Long.valueOf(params.get("stream_id")), JSONObject.toJSONString(R.ok().put("data",sendMsgVo)));
+		return R.ok();
+//		{app=200149.push.tlivecloud.com, appid=1319721001, appname=live, channel_id=667, errcode=0,
+//		errmsg=, event_time=1753840982, event_type=1,
+//		height=1080, idc_id=38, node=113.249.151.16,
+//		sequence=702115889072680959, set_id=2, stream_id=667,
+//		stream_param=txSecret=6E89AECCA08DBEE82E7F5870BCED7132&txTime=688ACD21, user_ip=125.80.218.101, width=1920}
+	}
+
+	// 直播结束回调
+	@PostMapping("/endLiving")
+	public R endLiving(HttpServletRequest request, @RequestBody  Map<String, String> params) {
+		log.info("请求参数:{}", params);
+		SendMsgVo sendMsgVo = new SendMsgVo();
+		sendMsgVo.setMsg("结束直播");
+		sendMsgVo.setCmd("live_end");
+		webSocketServer.broadcastMessage(Long.valueOf(params.get("stream_id")), JSONObject.toJSONString(R.ok().put("data",sendMsgVo)));
+		Live live = new Live();
+		live.setLiveId(Long.valueOf(params.get("stream_id")));
+		live.setStatus(3);
+		live.setFinishTime(LocalDateTime.now());
+		live.setLiveType(2);
+		liveService.updateLive(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,
+//				event_type=0, height=1080, idc_id=38, node=113.250.23.118, push_duration=1051237,
+//				sequence=721865018844564968, set_id=2, stream_id=673,
+//				stream_param=txSecret=A3EF362C9484D3D091C2E9B08C2C08CB&txTime=68A53145,
+//				user_ip=113.248.98.28, width=1920}
+
+	}
+
+	// 直播录制文件回调 腾讯云 cos桶 fs
+	@PostMapping("/liveReplayFile")
+	public R liveReplayFile(HttpServletRequest request, @RequestBody  Map<String, String> params) {
+		log.info("请求参数:{}", params);
+		Long liveId = Long.valueOf(params.get("stream_id"));
+		LiveVideo liveVideo = new LiveVideo();
+		LiveVideo exist = videoService.selectLiveVideoByLiveId(liveId);
+		if (exist != null) {
+			liveVideo = exist;
+		}
+		Date nowDate = DateUtils.getNowDate();
+		liveVideo.setLiveId(liveId);
+		liveVideo.setVideoUrl(params.get("video_url"));
+		liveVideo.setVideoType(2);
+		liveVideo.setDuration(Long.valueOf(params.get("duration")));
+		liveVideo.setCreateTime(nowDate);
+		liveVideo.setUpdateTime(nowDate);
+		videoService.saveOrUpdate(liveVideo);
+		return R.ok();
+//		{app=200149.push.tlivecloud.com, appid=1319721001, appname=live,
+//				callback_ext={"video_codec":"h264","session_id":"1755326625589574166","resolution":"1920x1080"},
+//			channel_id=774, duration=137, end_time=1757387736, end_time_usec=476103, event_type=100, file_format=mp4,
+//					file_id=1319721001_d69054948de44655b465aaf725cafc1c, file_size=45806289, media_start_time=80, record_bps=0,
+//				record_file_id=1319721001_d69054948de44655b465aaf725cafc1c, record_temp_id=1595756, start_time=1757387600, start_time_usec=942579,
+//				stream_id=774, stream_param=txSecret=CBF1E86FB1AD58B9CC25941F6B9DA854&txTime=68C0E304, task_id=1755326625589574166, video_id=1319721001_05396a7c47914b40aa9ffefcb0ea4626,
+//				video_url=http://fs-1319721001.cos.ap-chongqing.myqcloud.com/origin/200149.push.tlivecloud.com/live/774/1755326625589574166-6a9899ea95be4e89be0eeb30cf458579/2025-09-09-11-13-20.mp4}
+
+	}
+	@GetMapping("/currentActivities")
+	@Transactional
+	@Login
+	public R currentActivities(Long liveId) {
+		String userId = getUserId();
+		return liveService.currentActivities(liveId,userId);
+	}
+
+	@GetMapping("/test")
+	@Transactional
+	public void test() {
+
+	}
+
+
 }

+ 115 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveDataController.java

@@ -0,0 +1,115 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.domain.R;
+import com.fs.live.domain.LiveData;
+import com.fs.live.service.ILiveDataService;
+import com.fs.live.service.ILiveWatchUserService;
+import com.fs.live.vo.LiveWatchUserVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/app/live/liveData")
+public class LiveDataController extends AppBaseController{
+
+    @Autowired
+    private ILiveDataService liveDataService;
+
+    @Autowired
+    private ILiveWatchUserService liveWatchUserService;
+    /**
+     * 查询直播数据列表
+     * */
+//    @Login
+    @GetMapping("/list")
+    public List<LiveData> list(LiveData liveData) {
+        return liveDataService.selectLiveDataList(liveData);
+    }
+
+    /**
+     * 查询直播数据详情
+     * */
+//    @Login
+    @GetMapping("/get/{liveId}")
+    public R getLiveData(@PathVariable("liveId") Long liveId) {
+        return R.ok().put("liveData", liveDataService.selectLiveDataByLiveId(liveId));
+    }
+
+    /**
+     * 点赞
+     * */
+//    @Login
+    @GetMapping("/like/{liveId}")
+    public R like(@PathVariable("liveId") Long liveId) {
+        return liveDataService.updateLikeByLiveId(liveId,  Long.parseLong(getUserId()));
+    }
+
+    @GetMapping("/like")
+    public R likeWithUserId(@RequestParam Long liveId,@RequestParam Long userId) {
+        return liveDataService.updateLikeByLiveId(liveId,  userId);
+    }
+
+    /**
+     * 收藏
+     * */
+//    @Login
+    @GetMapping("/collect/{liveId}")
+    public R collect(@PathVariable("liveId") Long liveId) {
+        return R.ok(liveDataService.collect(liveId,  Long.parseLong(getUserId())));
+    }
+
+    /**
+     * 关注
+     * */
+//    @Login
+    @GetMapping("/follow/{liveId}")
+    public R follow(@PathVariable("liveId") Long liveId) {
+        return R.ok(liveDataService.follow(liveId,  Long.parseLong(getUserId())));
+    }
+
+    /**
+     * 收藏/取消收藏店铺
+     * */
+//    @Login
+    @PostMapping("/collectStore")
+    public R collectStore(@RequestParam Long storeId) {
+        return R.ok(liveDataService.collectStore(Long.parseLong(getUserId()), storeId));
+    }
+
+    /**
+     * 收藏/取消收藏商品
+     * */
+//    @Login
+    @PostMapping("/collectGoods")
+    public R collectProduct(@RequestParam Long goodId) {
+        return R.ok(liveDataService.collectProduct(Long.parseLong(getUserId()), goodId));
+    }
+
+    /**
+     * 获取直播内数据
+     * */
+    @GetMapping("/getLiveViewData/{liveId}")
+    public R getLiveViewData(@PathVariable Long liveId) {
+        Map<String,Object> liveViewData =liveDataService.getLiveViewData(liveId);
+        return R.ok(liveViewData);
+    }
+
+    /**
+     * 获取发言最多的三个用户
+     * */
+    @GetMapping("/getRecentLiveViewers/{liveId}")
+    public R getRecentLiveViewers(@PathVariable  Long liveId) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        List<LiveWatchUserVO> recentLiveViewers = liveWatchUserService.selectWatchUserList(params);
+        return R.ok().put("recentLiveViewers", recentLiveViewers);
+    }
+
+
+}

+ 13 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveGiftController.java

@@ -0,0 +1,13 @@
+package com.fs.app.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/app/live/liveGift")
+public class LiveGiftController {
+
+    /**
+     * 送礼物
+     * */
+}

+ 131 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveGoodsController.java

@@ -0,0 +1,131 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.his.service.IFsStoreProductService;
+import com.fs.live.domain.LiveGoods;
+import com.fs.live.service.ILiveGoodsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播商品Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/app/live/liveGoods")
+public class LiveGoodsController extends BaseController
+{
+    @Autowired
+    private ILiveGoodsService liveGoodsService;
+
+    @Autowired
+    private IFsStoreProductService fsStoreProductService;
+
+    /**
+     * 查询直播商品列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveGoods liveGoods)
+    {
+        startPage();
+        List<LiveGoods> list = liveGoodsService.selectLiveGoodsList(liveGoods);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播商品列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:export')")
+    @Log(title = "直播商品", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveGoods liveGoods)
+    {
+        List<LiveGoods> list = liveGoodsService.selectLiveGoodsList(liveGoods);
+        ExcelUtil<LiveGoods> util = new ExcelUtil<LiveGoods>(LiveGoods.class);
+        return util.exportExcel(list, "直播商品数据");
+    }
+
+    /**
+     * 获取直播商品详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:query')")
+    @GetMapping(value = "/{goodsId}")
+    public AjaxResult getInfo(@PathVariable("goodsId") Long goodsId)
+    {
+        return AjaxResult.success(liveGoodsService.selectLiveGoodsByGoodsId(goodsId));
+    }
+
+    /**
+     * 新增直播商品
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:add')")
+    @Log(title = "直播商品", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveGoods liveGoods)
+    {
+        return toAjax(liveGoodsService.insertLiveGoods(liveGoods));
+    }
+
+    /**
+     * 修改直播商品
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:edit')")
+    @Log(title = "直播商品", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public R edit(@RequestBody LiveGoods liveGoods)
+    {
+        return liveGoodsService.updateLiveGoods(liveGoods);
+    }
+
+    /**
+     * 删除直播商品
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveGoods:remove')")
+    @Log(title = "直播商品", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{goodsIds}")
+    public AjaxResult remove(@PathVariable Long[] goodsIds)
+    {
+        return toAjax(liveGoodsService.deleteLiveGoodsByGoodsIds(goodsIds));
+    }
+
+    /**
+     * 获取直播店铺
+     * */
+    @GetMapping("/liveStore/{liveId}")
+    public R liveGoodsStore(@PathVariable Long liveId,@RequestParam String key)
+    {
+        return liveGoodsService.getStoreByLiveId(liveId, key);
+    }
+
+    /**
+     *商品详情
+     */
+    @GetMapping("/liveGoodsDetail/{productId}")
+    public R liveGoodsDetail(@PathVariable Long productId)
+    {
+        return R.ok().put("data",fsStoreProductService.selectFsStoreProductById(productId));
+    }
+
+    /**
+     *当前正在展示的商品
+     */
+    @GetMapping("/showGoods/{liveId}")
+    public R showGoods(@PathVariable Long liveId)
+    {
+        return liveGoodsService.showGoods(liveId);
+    }
+
+
+}

+ 48 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveLotteryController.java

@@ -0,0 +1,48 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.live.param.LotteryPO;
+import com.fs.live.param.RedPO;
+import com.fs.live.service.ILiveLotteryConfService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/app/live/liveLottery")
+public class LiveLotteryController extends AppBaseController{
+
+    @Autowired
+    private ILiveLotteryConfService liveLotteryConfService;
+
+    /**
+     * 参与抽奖
+     * */
+    @RequestMapping("/participate")
+    public String participate(Long liveId, Long userId,Long lotteryId) {
+        return null;
+    }
+
+    /**
+     * 参与抽奖
+     * */
+    @Login
+    @PostMapping("/claim")
+    public R claim(@RequestBody LotteryPO lottery) {
+        lottery.setUserId(Long.parseLong(getUserId()));
+        return liveLotteryConfService.claimLotteryPacket(lottery);
+    }
+
+    /**
+     * 查询抽奖信息
+     * */
+    @Login
+    @PostMapping("/detail")
+    public R detail(@RequestBody LotteryPO lottery) {
+        return liveLotteryConfService.detail(lottery);
+    }
+
+}

+ 89 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveMsgController.java

@@ -0,0 +1,89 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveMsg;
+import com.fs.live.service.ILiveMsgService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 直播讨论Controller
+ *
+ * @author fs
+ * @date 2025-01-17
+ */
+@RestController
+@RequestMapping("/app/live/liveMsg")
+public class LiveMsgController extends BaseController
+{
+    @Autowired
+    private ILiveMsgService liveMsgService;
+
+    /**
+     * 查询直播讨论列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(LiveMsg liveMsg)
+    {
+        startPage();
+        List<LiveMsg> list = liveMsgService.selectLiveMsgList(liveMsg);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出直播讨论列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:export')")
+    @Log(title = "直播讨论", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveMsg liveMsg)
+    {
+        List<LiveMsg> list = liveMsgService.selectLiveMsgList(liveMsg);
+        ExcelUtil<LiveMsg> util = new ExcelUtil<LiveMsg>(LiveMsg.class);
+        return util.exportExcel(list, "直播讨论数据");
+    }
+
+
+
+    /**
+     * 新增直播讨论
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:add')")
+    @Log(title = "直播讨论", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveMsg liveMsg)
+    {
+        return toAjax(liveMsgService.insertLiveMsg(liveMsg));
+    }
+
+    /**
+     * 修改直播讨论
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:edit')")
+    @Log(title = "直播讨论", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveMsg liveMsg)
+    {
+        return toAjax(liveMsgService.updateLiveMsg(liveMsg));
+    }
+
+    /**
+     * 删除直播讨论
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveMsg:remove')")
+    @Log(title = "直播讨论", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{msgIds}")
+    public AjaxResult remove(@PathVariable Long[] msgIds)
+    {
+        return toAjax(liveMsgService.deleteLiveMsgByMsgIds(msgIds));
+    }
+
+}

+ 250 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveOrderController.java

@@ -0,0 +1,250 @@
+package com.fs.app.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fs.app.annotation.Login;
+import com.fs.app.utils.JwtUtils;
+import com.fs.common.annotation.Log;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.param.FsUserLiveOrderPayUParam;
+import com.fs.his.domain.FsStoreOrder;
+import com.fs.his.dto.ExpressInfoDTO;
+import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.param.FsStoreOrderCancelParam;
+import com.fs.his.param.LiveOrderCancelParam;
+import com.fs.his.service.IFsExpressService;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.enums.LiveOrderCancleReason;
+import com.fs.live.param.LiveOrderConfirmParam;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.live.vo.LiveOrderListVo;
+import com.github.pagehelper.PageHelper;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
+
+import static com.fs.his.utils.PhoneUtil.decryptPhone;
+import static com.github.pagehelper.page.PageMethod.startPage;
+
+/**
+ * 订单Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/app/live/liveOrder")
+public class LiveOrderController extends AppBaseController
+{
+    @Autowired
+    private ILiveOrderService liveOrderService;
+
+
+    @Autowired
+    private IFsExpressService expressService;
+    @Autowired
+    private JwtUtils jwtUtils;
+
+    /**
+     * 查询订单列表
+     */
+    @Login
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrder liveOrder)
+    {
+        PageHelper.startPage(liveOrder.getPageNum(), liveOrder.getPageSize());
+        liveOrder.setUserId(getUserId());
+        List<LiveOrderListVo> list = liveOrderService.selectLiveOrderListVo(liveOrder);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单列表
+     */
+    @Log(title = "订单", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrder liveOrder)
+    {
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        ExcelUtil<LiveOrder> util = new ExcelUtil<LiveOrder>(LiveOrder.class);
+        return util.exportExcel(list, "订单数据");
+    }
+
+    /**
+     * 获取订单详细信息
+     */
+    @Login
+    @GetMapping(value = "/info/{orderId}")
+    public AjaxResult getInfo(@PathVariable("orderId") String orderId)
+    {
+        return AjaxResult.success(liveOrderService.selectLiveOrderByOrderId(orderId));
+    }
+
+    @ApiOperation("确认订单")
+    @PostMapping("/confirm")
+    public R confirm(@Validated @RequestBody LiveOrderConfirmParam param, HttpServletRequest request){
+        param.setUserId(Long.parseLong(getUserId()));
+        return liveOrderService.confirmOrder(param);
+    }
+
+    @PostMapping("/buy")
+    @ApiOperation("购物车购买")
+    @Login
+    @RepeatSubmit
+    public R buy(@RequestBody LiveOrder liveOrder)
+    {
+        liveOrder.setUserId(getUserId());
+        return liveOrderService.buy(liveOrder);
+    }
+
+    /**
+     * 新增订单
+     */
+    @Login
+    @Log(title = "订单", businessType = BusinessType.INSERT)
+    @PostMapping("/create")
+    @RepeatSubmit
+    public R add(@RequestBody LiveOrder liveOrder)
+    {
+        liveOrder.setUserId(getUserId());
+        return liveOrderService.createLiveOrder(liveOrder);
+    }
+
+    /**
+     * 修改订单
+     */
+    @Login
+    @Log(title = "订单", businessType = BusinessType.UPDATE)
+    @PutMapping("/update")
+    @RepeatSubmit
+    public R edit(@RequestBody LiveOrder liveOrder)
+    {
+        return R.ok().put("orderId",liveOrder.getOrderId());
+    }
+
+
+    /**
+     * 查看物流状态
+     * */
+    @Login
+    @GetMapping(value = "/getExpress/{id}")
+    public R getExpress(@PathVariable("id") String id)
+    {
+        LiveOrder order=liveOrderService.selectLiveOrderByOrderId(id);
+        ExpressInfoDTO expressInfoDTO=null;
+        if(StringUtils.isNotEmpty(order.getDeliverySn())){
+            String lastFourNumber = "";
+            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+
+                lastFourNumber = order.getUserPhone();
+                if (lastFourNumber.length() == 11) {
+                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                }else if (lastFourNumber.length()>11){
+                    String jm = decryptPhone(lastFourNumber);
+                    lastFourNumber = StrUtil.sub(jm, jm.length(), -4);
+                }
+            }
+            expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            if((expressInfoDTO.getStateEx()!=null&&expressInfoDTO.getStateEx().equals("0"))&&(expressInfoDTO.getState()!=null&&expressInfoDTO.getState().equals("0"))){
+                lastFourNumber = "19923690275";
+                if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+                    if (lastFourNumber.length() == 11) {
+                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                    }
+                }
+
+                expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            }
+        }
+        return R.ok().put("data",expressInfoDTO);
+    }
+
+    /**
+     * 支付订单
+     * */
+    @PostMapping(value = "/pay")
+    public void pay(LiveOrder liveOrder)
+    {
+       liveOrderService.handlePay(liveOrder);
+    }
+
+    @Login
+    @ApiOperation("支付宝支付")
+    @PostMapping("/aliPayment")
+    @RepeatSubmit
+    public R aliPayment(@Validated @RequestBody FsUserLiveOrderPayUParam param)
+    {
+        param.setUserId(Long.parseLong(getUserId()));
+        return liveOrderService.aliPayment(param);
+    }
+
+    @Login
+    @ApiOperation("微信支付")
+    @PostMapping("/weChatPayment")
+    @RepeatSubmit
+    public R payment(@Validated @RequestBody FsUserLiveOrderPayUParam param)
+    {
+        param.setUserId(Long.parseLong(getUserId()));
+        return liveOrderService.wxPayment(param);
+    }
+
+    /**
+     * 订单确认
+     * */
+    @Login
+    @GetMapping(value = "/updateConfirm/{orderId}/{type}")
+    @RepeatSubmit
+    public R cancelConfirm(@PathVariable String orderId,@PathVariable String type)
+    {
+        LiveOrder byId = liveOrderService.getById(orderId);
+        List<Map<String, String>> allCodeDescMap = null;
+        if (type.equals("0"))
+            allCodeDescMap = LiveOrderCancleReason.getAllCodeDescMap();
+        return R.ok().put("reason",allCodeDescMap).put("data",byId);
+    }
+
+    /**
+     *正在购买的用户
+     * */
+    @GetMapping(value = "/liveOrderUser/{liveId}")
+    public R liveOrderUser(@PathVariable  String liveId)
+    {
+        return liveOrderService.liveOrderUser(liveId);
+    }
+
+    @Login
+    @ApiOperation("取消订单")
+    @PostMapping("/cancelOrder")
+    public R cancelOrder(@Validated @RequestBody LiveOrderCancelParam param, HttpServletRequest request){
+        LiveOrder order=liveOrderService.selectLiveOrderByOrderId(String.valueOf(param.getOrderId()));
+        if (ObjectUtil.isNull(order)) {
+            throw new CustomException("订单不存在");
+        }
+        return liveOrderService.cancelOrder(order);
+
+    }
+
+    @Login
+    @ApiOperation("完成订单")
+    @PostMapping("/finishOrder")
+    public R finishOrder(@Validated @RequestBody LiveOrderCancelParam param, HttpServletRequest request){
+        return liveOrderService.finishOrder(param.getOrderId());
+    }
+
+
+
+}

+ 97 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveOrderLogsController.java

@@ -0,0 +1,97 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveOrderLogs;
+import com.fs.live.service.ILiveOrderLogsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 订单操作记录Controller
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@RestController
+@RequestMapping("/live/liveOrderLogs")
+public class LiveOrderLogsController extends BaseController
+{
+    @Autowired
+    private ILiveOrderLogsService liveOrderLogsService;
+
+    /**
+     * 查询订单操作记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrderLogs liveOrderLogs)
+    {
+        startPage();
+        List<LiveOrderLogs> list = liveOrderLogsService.selectLiveOrderLogsList(liveOrderLogs);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单操作记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:export')")
+    @Log(title = "订单操作记录", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrderLogs liveOrderLogs)
+    {
+        List<LiveOrderLogs> list = liveOrderLogsService.selectLiveOrderLogsList(liveOrderLogs);
+        ExcelUtil<LiveOrderLogs> util = new ExcelUtil<LiveOrderLogs>(LiveOrderLogs.class);
+        return util.exportExcel(list, "订单操作记录数据");
+    }
+
+    /**
+     * 获取订单操作记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:query')")
+    @GetMapping(value = "/{logsId}")
+    public AjaxResult getInfo(@PathVariable("logsId") String logsId)
+    {
+        return AjaxResult.success(liveOrderLogsService.selectLiveOrderLogsByLogsId(logsId));
+    }
+
+    /**
+     * 新增订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:add')")
+    @Log(title = "订单操作记录", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveOrderLogs liveOrderLogs)
+    {
+        return toAjax(liveOrderLogsService.insertLiveOrderLogs(liveOrderLogs));
+    }
+
+    /**
+     * 修改订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:edit')")
+    @Log(title = "订单操作记录", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveOrderLogs liveOrderLogs)
+    {
+        return toAjax(liveOrderLogsService.updateLiveOrderLogs(liveOrderLogs));
+    }
+
+    /**
+     * 删除订单操作记录
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrderLogs:remove')")
+    @Log(title = "订单操作记录", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{logsIds}")
+    public AjaxResult remove(@PathVariable String[] logsIds)
+    {
+        return toAjax(liveOrderLogsService.deleteLiveOrderLogsByLogsIds(logsIds));
+    }
+}

+ 104 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveOrderPaymentController.java

@@ -0,0 +1,104 @@
+package com.fs.app.controller;
+
+import java.util.List;
+
+import com.fs.live.domain.LiveOrderPayment;
+import com.fs.live.service.ILiveOrderPaymentService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 支付明细Controller
+ *
+ * @author fs
+ * @date 2025-08-07
+ */
+@RestController
+@RequestMapping("/app/payment")
+public class LiveOrderPaymentController extends BaseController
+{
+    @Autowired
+    private ILiveOrderPaymentService liveOrderPaymentService;
+
+    /**
+     * 查询支付明细列表
+     */
+    @PreAuthorize("@ss.hasPermi('app:payment:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveOrderPayment liveOrderPayment)
+    {
+        startPage();
+        List<LiveOrderPayment> list = liveOrderPaymentService.selectLiveOrderPaymentList(liveOrderPayment);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出支付明细列表
+     */
+    @PreAuthorize("@ss.hasPermi('app:payment:export')")
+    @Log(title = "支付明细", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveOrderPayment liveOrderPayment)
+    {
+        List<LiveOrderPayment> list = liveOrderPaymentService.selectLiveOrderPaymentList(liveOrderPayment);
+        ExcelUtil<LiveOrderPayment> util = new ExcelUtil<LiveOrderPayment>(LiveOrderPayment.class);
+        return util.exportExcel(list, "支付明细数据");
+    }
+
+    /**
+     * 获取支付明细详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('app:payment:query')")
+    @GetMapping(value = "/{paymentId}")
+    public AjaxResult getInfo(@PathVariable("paymentId") Long paymentId)
+    {
+        return AjaxResult.success(liveOrderPaymentService.selectLiveOrderPaymentByPaymentId(paymentId));
+    }
+
+    /**
+     * 新增支付明细
+     */
+    @PreAuthorize("@ss.hasPermi('app:payment:add')")
+    @Log(title = "支付明细", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveOrderPayment liveOrderPayment)
+    {
+        return toAjax(liveOrderPaymentService.insertLiveOrderPayment(liveOrderPayment));
+    }
+
+    /**
+     * 修改支付明细
+     */
+    @PreAuthorize("@ss.hasPermi('app:payment:edit')")
+    @Log(title = "支付明细", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveOrderPayment liveOrderPayment)
+    {
+        return toAjax(liveOrderPaymentService.updateLiveOrderPayment(liveOrderPayment));
+    }
+
+    /**
+     * 删除支付明细
+     */
+    @PreAuthorize("@ss.hasPermi('app:payment:remove')")
+    @Log(title = "支付明细", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{paymentIds}")
+    public AjaxResult remove(@PathVariable Long[] paymentIds)
+    {
+        return toAjax(liveOrderPaymentService.deleteLiveOrderPaymentByPaymentIds(paymentIds));
+    }
+}

+ 30 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveRedController.java

@@ -0,0 +1,30 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.live.param.RedPO;
+import com.fs.live.service.ILiveRedConfService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/app/live/liveRed")
+public class LiveRedController extends AppBaseController{
+
+    @Autowired
+    private ILiveRedConfService liveRedConfService;
+
+    /**
+     * 领取红包
+     * */
+    @Login
+    @PostMapping("/claim")
+    public R claim(@RequestBody RedPO red) {
+        red.setUserId(Long.parseLong(getUserId()));
+        return liveRedConfService.claimRedPacket(red);
+    }
+
+}

+ 97 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveUserFavoriteController.java

@@ -0,0 +1,97 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveUserFavorite;
+import com.fs.live.service.ILiveUserFavoriteService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 用户直播收藏Controller
+ *
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/app/live/liveUserFavorite")
+public class LiveUserFavoriteController extends BaseController
+{
+    @Autowired
+    private ILiveUserFavoriteService liveUserFavoriteService;
+
+    /**
+     * 查询用户直播收藏列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFavorite liveUserFavorite)
+    {
+        startPage();
+        List<LiveUserFavorite> list = liveUserFavoriteService.selectLiveUserFavoriteList(liveUserFavorite);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播收藏列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:export')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFavorite liveUserFavorite)
+    {
+        List<LiveUserFavorite> list = liveUserFavoriteService.selectLiveUserFavoriteList(liveUserFavorite);
+        ExcelUtil<LiveUserFavorite> util = new ExcelUtil<LiveUserFavorite>(LiveUserFavorite.class);
+        return util.exportExcel(list, "用户直播收藏数据");
+    }
+
+    /**
+     * 获取用户直播收藏详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:query')")
+    @GetMapping(value = "/{favoriteId}")
+    public AjaxResult getInfo(@PathVariable("favoriteId") Long favoriteId)
+    {
+        return AjaxResult.success(liveUserFavoriteService.selectLiveUserFavoriteByFavoriteId(favoriteId));
+    }
+
+    /**
+     * 新增用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:add')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFavorite liveUserFavorite)
+    {
+        return toAjax(liveUserFavoriteService.insertLiveUserFavorite(liveUserFavorite));
+    }
+
+    /**
+     * 修改用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:edit')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFavorite liveUserFavorite)
+    {
+        return toAjax(liveUserFavoriteService.updateLiveUserFavorite(liveUserFavorite));
+    }
+
+    /**
+     * 删除用户直播收藏
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFavorite:remove')")
+    @Log(title = "用户直播收藏", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{favoriteIds}")
+    public AjaxResult remove(@PathVariable Long[] favoriteIds)
+    {
+        return toAjax(liveUserFavoriteService.deleteLiveUserFavoriteByFavoriteIds(favoriteIds));
+    }
+}

+ 97 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveUserFollowController.java

@@ -0,0 +1,97 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveUserFollow;
+import com.fs.live.service.ILiveUserFollowService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 用户直播关注Controller
+ *
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/app/live/liveUserFollow")
+public class LiveUserFollowController extends BaseController
+{
+    @Autowired
+    private ILiveUserFollowService liveUserFollowService;
+
+    /**
+     * 查询用户直播关注列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserFollow liveUserFollow)
+    {
+        startPage();
+        List<LiveUserFollow> list = liveUserFollowService.selectLiveUserFollowList(liveUserFollow);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播关注列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:export')")
+    @Log(title = "用户直播关注", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserFollow liveUserFollow)
+    {
+        List<LiveUserFollow> list = liveUserFollowService.selectLiveUserFollowList(liveUserFollow);
+        ExcelUtil<LiveUserFollow> util = new ExcelUtil<LiveUserFollow>(LiveUserFollow.class);
+        return util.exportExcel(list, "用户直播关注数据");
+    }
+
+    /**
+     * 获取用户直播关注详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserFollowService.selectLiveUserFollowById(id));
+    }
+
+    /**
+     * 新增用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:add')")
+    @Log(title = "用户直播关注", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserFollow liveUserFollow)
+    {
+        return toAjax(liveUserFollowService.insertLiveUserFollow(liveUserFollow));
+    }
+
+    /**
+     * 修改用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:edit')")
+    @Log(title = "用户直播关注", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserFollow liveUserFollow)
+    {
+        return toAjax(liveUserFollowService.updateLiveUserFollow(liveUserFollow));
+    }
+
+    /**
+     * 删除用户直播关注
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserFollow:remove')")
+    @Log(title = "用户直播关注", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserFollowService.deleteLiveUserFollowByIds(ids));
+    }
+}

+ 60 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveUserGiftController.java

@@ -0,0 +1,60 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
+import com.fs.live.domain.LiveGift;
+import com.fs.live.domain.LiveUserGift;
+import com.fs.live.service.ILiveGiftService;
+import com.fs.live.service.ILiveUserGiftService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/app/live/liveUserGift")
+public class LiveUserGiftController extends AppBaseController{
+
+    @Autowired
+    private ILiveUserGiftService liveUserGiftService;
+
+    @Autowired
+    private ILiveGiftService liveGiftService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private IFsUserService  fsUserService;
+
+    /**
+     *给直播间送礼物
+     */
+    @Login
+    @PostMapping("/send")
+    @Transactional
+    public String send(@RequestBody LiveUserGift liveUserGift) {
+        liveUserGift.setUserId(Long.parseLong(getUserId()));
+        long giftValue;
+        List<LiveGift> liveGifts = redisCache.getCacheList("liveGift");
+        LiveGift liveGift = liveGifts.stream().filter(gift ->
+                gift.getGiftId().equals(liveUserGift.getGiftId()))
+                .findFirst().orElse(null);
+        if (liveGift == null) {
+            return "礼物信息不存在";
+        }else{
+            giftValue = liveGift.getPrice().longValue() * liveUserGift.getCn();
+        }
+        FsUser user=fsUserService.selectFsUserByUserId(liveUserGift.getUserId());
+        if (user.getIntegral() < giftValue) {
+            return "账户余额不足";
+        }
+        user.setIntegral(user.getIntegral() - giftValue);
+        fsUserService.updateFsUser(user);
+        return liveUserGiftService.save(liveUserGift)?"赠送礼物成功":"赠送礼物失败";
+    }
+
+}

+ 97 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveUserLikeController.java

@@ -0,0 +1,97 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveUserLike;
+import com.fs.live.service.ILiveUserLikeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 用户直播赞Controller
+ *
+ * @author fs
+ * @date 2025-07-11
+ */
+@RestController
+@RequestMapping("/app/live/liveUserLike")
+public class LiveUserLikeController extends BaseController
+{
+    @Autowired
+    private ILiveUserLikeService liveUserLikeService;
+
+    /**
+     * 查询用户直播赞列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LiveUserLike liveUserLike)
+    {
+        startPage();
+        List<LiveUserLike> list = liveUserLikeService.selectLiveUserLikeList(liveUserLike);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出用户直播赞列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:export')")
+    @Log(title = "用户直播赞", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(LiveUserLike liveUserLike)
+    {
+        List<LiveUserLike> list = liveUserLikeService.selectLiveUserLikeList(liveUserLike);
+        ExcelUtil<LiveUserLike> util = new ExcelUtil<LiveUserLike>(LiveUserLike.class);
+        return util.exportExcel(list, "用户直播赞数据");
+    }
+
+    /**
+     * 获取用户直播赞详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveUserLikeService.selectLiveUserLikeById(id));
+    }
+
+    /**
+     * 新增用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:add')")
+    @Log(title = "用户直播赞", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveUserLike liveUserLike)
+    {
+        return toAjax(liveUserLikeService.insertLiveUserLike(liveUserLike));
+    }
+
+    /**
+     * 修改用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:edit')")
+    @Log(title = "用户直播赞", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveUserLike liveUserLike)
+    {
+        return toAjax(liveUserLikeService.updateLiveUserLike(liveUserLike));
+    }
+
+    /**
+     * 删除用户直播赞
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveUserLike:remove')")
+    @Log(title = "用户直播赞", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveUserLikeService.deleteLiveUserLikeByIds(ids));
+    }
+}

+ 98 - 0
fs-live-app/src/main/java/com/fs/app/controller/LiveWatchUserController.java

@@ -0,0 +1,98 @@
+package com.fs.app.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.live.domain.LiveWatchUser;
+import com.fs.live.service.ILiveWatchUserService;
+import com.fs.live.vo.LiveWatchUserVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 直播间观看用户Controller
+ *
+ * @author fs
+ * @date 2025-01-18
+ */
+@RestController
+@RequestMapping("/app/live/liveWatchUser")
+public class LiveWatchUserController extends BaseController
+{
+    @Autowired
+    private ILiveWatchUserService liveWatchUserService;
+
+
+
+
+    @GetMapping("/watchUserList")
+    public TableDataInfo watchUserList(LiveWatchUser param) {
+        param.setOnline(0);
+        List<LiveWatchUserVO> onLineUserList = liveWatchUserService.selectOnlineUserList(param);
+        return getDataTable(onLineUserList);
+    }
+
+
+    /**
+     * 获取直播间观看用户详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(liveWatchUserService.selectLiveWatchUserById(id));
+    }
+
+    /**
+     * 新增直播间观看用户
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:add')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LiveWatchUser liveWatchUser)
+    {
+        return toAjax(liveWatchUserService.insertLiveWatchUser(liveWatchUser));
+    }
+
+    /**
+     * 修改直播间观看用户
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LiveWatchUser liveWatchUser)
+    {
+        return toAjax(liveWatchUserService.updateLiveWatchUser(liveWatchUser));
+    }
+
+    /**
+     * 删除直播间观看用户
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:remove')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(liveWatchUserService.deleteLiveWatchUserByIds(ids));
+    }
+
+    /**
+     * 修改直播间用户禁言状态
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveWatchUser:edit')")
+    @Log(title = "直播间观看用户", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeUserState")
+    public AjaxResult changeUserState(@RequestParam Long liveId, @RequestParam Long userId) {
+        return toAjax(liveWatchUserService.changeUserState(liveId, userId));
+    }
+
+}

+ 148 - 0
fs-live-app/src/main/java/com/fs/app/controller/UserAddressController.java

@@ -0,0 +1,148 @@
+package com.fs.app.controller;
+
+
+import cn.hutool.core.bean.BeanUtil;
+import com.fs.app.annotation.Login;
+import com.fs.app.param.FsAddressParseParam;
+import com.fs.app.param.FsUserAddressAddEditParam;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.FsUserAddress;
+import com.fs.his.service.IFsCityService;
+import com.fs.his.service.IFsExpressService;
+import com.fs.his.service.IFsUserAddressService;
+import com.fs.his.service.IFsUserIntegralLogsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.List;
+
+import static com.fs.his.utils.PhoneUtil.decryptPhone;
+
+
+@Api("地址接口")
+@RestController
+@RequestMapping(value="/app/userAddress")
+public class UserAddressController extends  AppBaseController {
+
+
+    @Autowired
+    private IFsUserAddressService addressService;
+
+    @Autowired
+    private IFsCityService cityService;
+    @Autowired
+    private IFsExpressService expressService;
+    @Autowired
+    private IFsUserIntegralLogsService fsUserIntegralLogsService;
+
+
+
+
+    @Login
+    @ApiOperation("获取地址列表")
+    @GetMapping("/getAddressList")
+    public R getAddressList(HttpServletRequest request){
+        try {
+            FsUserAddress map=new FsUserAddress();
+            map.setUserId(Long.parseLong(getUserId()));
+            map.setIsDel(0);
+            List<FsUserAddress> list=addressService.selectFsUserAddressList(map);
+            for (FsUserAddress fsUserAddress : list) {
+
+                if (fsUserAddress.getPhone()!=null&&fsUserAddress.getPhone().length()>11&&!fsUserAddress.getPhone().matches("\\d+")){
+                    fsUserAddress.setPhone(decryptPhone(fsUserAddress.getPhone()));
+                }
+            }
+            return R.ok().put("data",list);
+        } catch (Exception e){
+            return R.error("操作异常");
+        }
+    }
+    @Login
+    @ApiOperation("获取地址信息")
+    @GetMapping("/getAddressById")
+    public R getAddressById(@RequestParam("addressId")Long addressId, HttpServletRequest request){
+        FsUserAddress address=addressService.selectFsUserAddressByAddressId(addressId);
+
+        if (address.getPhone()!=null&&address.getPhone().length()>11&&!address.getPhone().matches("\\d+")){
+            address.setPhone(decryptPhone(address.getPhone()));
+        }
+        if(!address.getUserId().equals(Long.parseLong(getUserId()))){
+            return R.error("非法操作");
+        }
+        return R.ok().put("data",address);
+    }
+    @Login
+    @RepeatSubmit
+    @ApiOperation("添加地址")
+    @PostMapping("/addAddress")
+    public R addAddress(@Valid @RequestBody FsUserAddressAddEditParam address, HttpServletRequest request){
+        //处理地址数量 最大20个
+        Integer count=addressService.selectFsUserAddressCountsByUserId(Long.parseLong(getUserId()));
+        if(count>10){
+            return R.error("最多可创建10个地址");
+        }
+        if(address.getIsDefault()==1){
+            //处理默认地址
+            addressService.clearIsDefalut(Long.parseLong(getUserId()));
+        }
+        FsUserAddress userAddress=new FsUserAddress();
+        BeanUtil.copyProperties(address, userAddress);
+        address.setPhone(address.getPhone().trim());
+        userAddress.setUserId(Long.parseLong(getUserId()));
+        addressService.insertFsUserAddress(userAddress);
+        fsUserIntegralLogsService.addUserAddressIntegral(Long.parseLong(getUserId()),userAddress.getAddressId());
+        return R.ok("操作成功");
+    }
+
+    @Login
+    @ApiOperation("编辑地址")
+    @PostMapping("/editAddress")
+    public R editAddress(@Valid @RequestBody FsUserAddressAddEditParam address, HttpServletRequest request){
+        if(address.getIsDefault()==1){
+            //处理默认地址
+            addressService.clearIsDefalut(Long.parseLong(getUserId()));
+        }
+        FsUserAddress userAddress=new FsUserAddress();
+        BeanUtil.copyProperties(address, userAddress);
+        addressService.updateFsUserAddress(userAddress);
+        return R.ok("操作成功");
+    }
+
+    @Login
+    @ApiOperation("删除地址")
+    @PostMapping("/delAddress")
+    public R delAddress(@RequestBody FsUserAddressAddEditParam address, HttpServletRequest request){
+        addressService.deleteFsUserAddressByAddressId(address.getAddressId());
+        return R.ok("操作成功");
+    }
+
+    @Login
+    @ApiOperation("地址解析")
+    @PostMapping("/parseAddress")
+    public R parseAddress(@RequestBody FsAddressParseParam param){
+        return expressService.parseAddress(param.getContent());
+    }
+
+    @Login
+    @ApiOperation("获取默认地址信息")
+    @GetMapping("/getAddressByDefault")
+    public R getAddressByDefault( HttpServletRequest request){
+        FsUserAddress address=addressService.selectFsUserAddressByDefault(Long.parseLong(getUserId()));
+        if (address!=null&&address.getPhone()!=null&&address.getPhone().length()>11&&!address.getPhone().matches("\\d+")){
+            address.setPhone(decryptPhone(address.getPhone()));
+        }
+        if (null!=address){
+            if(!address.getUserId().equals(Long.parseLong(getUserId()))){
+                return R.error("非法操作");
+            }
+        }
+        return R.ok().put("data",address);
+    }
+
+}

+ 443 - 65
fs-live-app/src/main/java/com/fs/app/controller/UserController.java

@@ -3,23 +3,33 @@ package com.fs.app.controller;
 
 import cn.hutool.core.date.DateTime;
 import com.fs.app.annotation.Login;
+import com.fs.app.param.FsUserEditPhoneParam;
+import com.fs.app.param.FsUserLoginByWeChatParam;
+import com.fs.app.param.FsUserLoginParam;
 import com.fs.app.param.LoginParam;
-import com.fs.app.vo.UserListVO;
-import com.fs.app.vo.UserVO;
-import com.fs.chat.service.IChatRoleService;
+import com.fs.app.utils.WxUtil;
+import com.fs.app.websocket.constant.NickNameConstant;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.constant.Constants;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.PinYinUtil;
-import com.fs.common.utils.SecurityUtils;
+import com.fs.common.exception.user.CaptchaException;
+import com.fs.common.exception.user.CaptchaExpireException;
+import com.fs.common.utils.MessageUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.sign.Md5Utils;
 import com.fs.company.domain.CompanyUser;
-import com.fs.company.domain.CompanyWxAccount;
 import com.fs.company.service.ICompanyPostService;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.company.service.ICompanyWxAccountService;
-import com.fs.company.vo.CompanyUserVO;
+import com.fs.framework.manager.AsyncManager;
+import com.fs.framework.manager.factory.AsyncFactory;
 import com.fs.his.domain.FsUser;
+import com.fs.his.domain.FsUserAddress;
+import com.fs.his.mapper.FsUserMapper;
+import com.fs.his.service.IFsUserNewTaskService;
 import com.fs.his.service.IFsUserService;
+import com.fs.his.vo.FsUserRegisterParam;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -30,13 +40,19 @@ import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.WxMpUserService;
 import me.chanjar.weixin.mp.bean.result.WxMpUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
+
+import static com.fs.his.utils.PhoneUtil.decryptPhoneMk;
+import static com.fs.his.utils.PhoneUtil.encryptPhone;
 
 
 @Api("用户接口")
@@ -50,77 +66,72 @@ public class UserController extends AppBaseController {
 	private final WxMpService wxMpService;
 	private final IFsUserService userService;
 
+	private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+	@Autowired
+	private FsUserMapper userMapper;
+	@Autowired
+	private IFsUserNewTaskService userNewTaskService;
+
+	private static final String APP_ID = "wxd70f99287830cb51";
+	private static final String APP_SECRET = "51129ad15e25fb63b4e6c025df56a541";
+
 
 	@ApiOperation("课程短链公众号登录")
 	@PostMapping("/loginByMp")
 	public R loginByMp( @RequestBody LoginParam param) {
-//		if (org.apache.commons.lang3.StringUtils.isBlank(param.getCode())) {
-//			return R.error("code不存在");
-//		}
-//		try{
-//			WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
-//			WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
-//			WxMpUserService wxMpUserService = wxMpService.getUserService();
-//			WxMpUser userInfo = wxMpUserService.userInfo(wxMpUser.getOpenid());
-//      if (!userInfo.getSubscribe()){
-//        return R.error("请关注公众号进行登录");
-//      }
+		if (StringUtils.isBlank(param.getCode())) {
+			return R.error("code不存在");
+		}
+		try{
+			WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
+			WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
+			WxMpUserService wxMpUserService = wxMpService.getUserService();
+			WxMpUser userInfo = wxMpUserService.userInfo(wxMpUser.getOpenid());
+			if (!userInfo.getSubscribe()){
+				return R.error("请关注公众号进行登录");
+			}
 			FsUser user=userService.selectFsUserByUnionid(param.getUnionId());
-//			if(user!=null){
-//				FsUser userMap=new FsUser();
-//				userMap.setUserId(user.getUserId());
-//				userMap.setNickName(wxMpUser.getNickname());
-//				userMap.setAvatar(wxMpUser.getHeadImgUrl());
-//				userMap.setMpOpenId(wxMpUser.getOpenid());
-//				userMap.setUpdateTime(new DateTime());
-//				userService.updateFsUser(userMap);
-//			}
-//			else{
-//				//写入
-//				user=new FsUser();
-//				user.setNickName(wxMpUser.getNickname());
-//				user.setAvatar(wxMpUser.getHeadImgUrl());
-//				user.setStatus(1);
-//				user.setSex(wxMpUser.getSex());
-//				user.setMpOpenId(wxMpUser.getOpenid());
-//				user.setUnionId(wxMpUser.getUnionId());
-//				user.setCreateTime(new Date());
-//				userService.insertFsUser(user);
-//			}
+			if(user!=null){
+				FsUser userMap=new FsUser();
+				userMap.setUserId(user.getUserId());
+				userMap.setNickName(wxMpUser.getNickname());
+				userMap.setAvatar(wxMpUser.getHeadImgUrl());
+				userMap.setMpOpenId(wxMpUser.getOpenid());
+				userMap.setUpdateTime(new DateTime());
+				userService.updateFsUser(userMap);
+			}
+			else{
+				//写入
+				user=new FsUser();
+				user.setNickName(wxMpUser.getNickname());
+				user.setAvatar(wxMpUser.getHeadImgUrl());
+				user.setStatus(1);
+				user.setSex(wxMpUser.getSex());
+				user.setMpOpenId(wxMpUser.getOpenid());
+				user.setUnionId(wxMpUser.getUnionId());
+				user.setCreateTime(new Date());
+				userService.insertFsUser(user);
+			}
 			String token = jwtUtils.generateToken(user.getUserId());
 			redisCache.setCacheObject("token:"+user.getUserId(),token,604800, TimeUnit.SECONDS);
 			Map<String,Object> map=new HashMap<>();
 			map.put("token",token);
 			map.put("user",user);
 			return R.ok(map);
-//		}
-//		catch (WxErrorException e){
-//			if(e.getError().getErrorCode()==40163){
-//				return R.error(40163,e.getError().getErrorMsg());
-//			}
-//			else{
-//				return R.error("授权失败,"+e.getMessage());
-//			}
-//		}
-
-	}
-
-	@ApiOperation("检测是否登录")
-	@GetMapping("/checkLogin")
-	public R checkLogin(){
-		if(StringUtils.isEmpty(getUserId())){
-			//未登录
-			return R.error("未登录");
 		}
-		else{
-			//登录
-			String token = jwtUtils.generateToken(Long.parseLong(getUserId()));
-			Map<String,Object> map=new HashMap<>();
-			map.put("token",token);
-			return R.ok("认证成功").put("userId",getUserId()).put("token",token);
+		catch (WxErrorException e){
+			if(e.getError().getErrorCode()==40163){
+				return R.error(40163,e.getError().getErrorMsg());
+			}
+			else{
+				return R.error("授权失败,"+e.getMessage());
+			}
 		}
+
 	}
 
+
 	/**
 	 * 获取用户信息
 	 */
@@ -165,4 +176,371 @@ public class UserController extends AppBaseController {
 		}
 	}
 
+//	@Login
+	@ApiOperation("获取用户名称")
+	@GetMapping("/getUserNickName")
+	public R getUserInfoByUserId(@RequestParam(value = "userId") Long userId){
+		try {
+			FsUser user=userMapper.selectFsUserByUserId(userId);
+			if(user==null){
+				return R.error(40001,"用户不存在");
+			}
+			return R.ok().put("nickName", user.getNickName());
+		} catch (Exception e){
+			return R.error("操作异常");
+		}
+	}
+
+	@ApiOperation("检测是否登录")
+	@GetMapping("/checkLogin")
+	public R checkLogin(HttpServletRequest request){
+		if(StringUtils.isEmpty(getUserId())){
+			//未登录
+			return R.error("未登录");
+		}
+		else{
+			//登录
+			String token = jwtUtils.generateToken(Long.parseLong(getUserId()));
+			Map<String,Object> map=new HashMap<>();
+			map.put("token",token);
+			return R.ok("认证成功").put("userId",getUserId()).put("token",token);
+		}
+	}
+
+	@ApiOperation("注册app用户")
+	@PostMapping("/register")
+	@RepeatSubmit
+	public R registerDoctor(@Validated @RequestBody FsUserRegisterParam param){
+		FsUser fsUser = findUserByPhone(param.getPhone());
+
+//        if (fsUser == null) {
+//            // 尝试使用加密后的手机号查询
+//            fsUser = userService.selectFsUserByPhone(encryptPhone(param.getPhone()));
+//        }
+
+		if (fsUser != null && org.apache.commons.lang3.StringUtils.isNotEmpty(fsUser.getPassword())) {
+			return R.error("此账号已经注册");
+		}
+
+		FsUser user = new FsUser();
+		if (fsUser != null) {
+			// 更新已有用户的密码
+			user.setUserId(fsUser.getUserId());
+			user.setPassword(Md5Utils.hash(param.getPassword()));
+			user.setUpdateTime(new DateTime());
+			userService.updateFsUser(user);
+			return R.ok("注册成功");
+		} else {
+			// 创建新用户
+			user.setPhone(param.getPhone());
+			user.setNickName("app用户" + param.getPhone().substring(param.getPhone().length() - 4));
+			user.setStatus(1);
+			user.setAvatar("https://cos.his.cdwjyyh.com/fs/20240926/420728ee06e54575ba82665dedb4756b.png");
+			user.setPassword(Md5Utils.hash(param.getPassword()));
+			user.setCreateTime(new Date());
+
+			if (userService.insertFsUser(user) > 0) {
+				return R.ok("注册成功");
+			} else {
+				return R.error("注册失败");
+			}
+		}
+
+	}
+
+
+	/**
+	 * app登录
+	 * */
+	@ApiOperation("登录")
+	@PostMapping("/loginByApp")
+	@Transactional
+	public R login(@Validated @RequestBody FsUserLoginParam param) {
+		int loginType = param.getLoginType();
+		switch (loginType) {
+			case 1:
+				return handleLoginType1(param); // 手机密码登录
+			case 3:
+				return handleLoginType3(param);
+			default:
+				return R.error("请选择正确的登陆类型!");
+		}
+	}
+
+	@ApiOperation("获取用户收货地址")
+	@GetMapping(value = "/getUserAddr/{userId}")
+	public AjaxResult getUserAddr(@PathVariable("userId") Long userId)
+	{
+		List<FsUserAddress> fsUserAddresses = userService.selectFsUserAddressByUserId(userId);
+		for (FsUserAddress fsUserAddress : fsUserAddresses) {
+			if (fsUserAddress.getPhone()!=null&&fsUserAddress.getPhone()!=""){
+				if (fsUserAddress.getPhone().length()>11){
+					fsUserAddress.setPhone(decryptPhoneMk(fsUserAddress.getPhone()));
+				}else {
+					fsUserAddress.setPhone(fsUserAddress.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+				}
+			}
+		}
+
+		return AjaxResult.success(fsUserAddresses);
+	}
+
+	@ApiOperation("微信登录")
+	@PostMapping("/loginByWeChat")
+	@Transactional
+	public R loginByWeChat(@Validated @RequestBody FsUserLoginByWeChatParam param) {
+		try {
+			if (org.apache.commons.lang3.StringUtils.isBlank(param.getCode())) {
+				return R.error("code不存在");
+			}
+			logger.info("zyp app微信登录,param:{}", param);
+			Map result = WxUtil.getAccessToken(param.getCode(),APP_ID,APP_SECRET);
+			String accessToken = result.get("access_token").toString();
+			String unionid = result.get("unionid").toString();
+
+			String openid = result.get("openid").toString();
+
+			Map userInfo = WxUtil.getUserInfo(accessToken, openid);
+
+			String nickname = userInfo.get("nickname").toString();
+			Integer sex = (Integer) userInfo.get("sex");
+			String avatar = userInfo.get("headimgurl").toString();
+			FsUser user = userService.selectFsUserByUnionid(unionid);
+
+			Map<String, Object> map = new HashMap<>();
+			if (user == null) {
+				user = new FsUser();
+				user.setLoginDevice(param.getLoginDevice()!=null ? param.getLoginDevice() : null);
+				user.setSource(param.getSource()!=null ? param.getSource() : null);
+				user.setNickName(nickname);
+				user.setAvatar(avatar);
+				if (sex!=0){
+					user.setSex(sex);
+				}
+				user.setUnionId(unionid);
+				user.setCreateTime(new Date());
+				user.setStatus(1);
+				if (org.apache.commons.lang3.StringUtils.isNotEmpty(param.getJpushId())) {
+					user.setJpushId(param.getJpushId());
+				}
+				userService.insertFsUser(user);
+				map.put("isNew", true);
+				map.put("unionid",unionid);
+//				if (org.apache.commons.lang3.StringUtils.isNotEmpty(param.getJpushId())) {
+//					try {
+//						//发送注册优惠券
+//						fsUserCouponService.sendRegisterCoupon(user);
+//					} catch (Exception e) {
+//						logger.error("发送注册优惠券失败:{}",e.getMessage());
+//					}
+//				}
+				return R.ok(map);
+			} else {
+				if (org.apache.commons.lang3.StringUtils.isNotEmpty(param.getJpushId())) {
+					updateExistingUserJpushId(user, param.getJpushId());
+//					try {
+//						//发送注册优惠券
+//						fsUserCouponService.sendRegisterCoupon(user);
+//					} catch (Exception e) {
+//						logger.error("发送注册优惠券失败:{}",e.getMessage());
+//					}
+				}
+				if (org.apache.commons.lang3.StringUtils.isEmpty(user.getPhone())) {
+					map.put("isNew", true);
+					map.put("unionid",user.getUnionId());
+					return R.ok(map);
+				}
+			}
+			if (user.getStatus()==0&& org.apache.commons.lang3.StringUtils.isNotEmpty(param.getSource())&&!param.getSource().equals("iOS")){
+				return R.error("登录失败,账户被禁用");
+			}
+			int isFirstLogin = userNewTaskService.performTaskOne(user.getUserId());
+			String token = jwtUtils.generateToken(user.getUserId());
+			redisCache.setCacheObject("userToken:" + user.getUserId(), token, 604800, TimeUnit.SECONDS);
+			map.put("token", token);
+			map.put("user", user);
+			map.put("isFirst",isFirstLogin);
+			return R.ok(map);
+		}catch (Exception e){
+			logger.error("zyp 登录失败:{}", e.getMessage());
+			return R.error("登录失败");
+		}
+
+	}
+
+	@ApiOperation("绑定手机号")
+	@PostMapping("/setIPhoneNumber")
+	public R setIPhoneNumber(@Validated @RequestBody FsUserEditPhoneParam param) {
+		FsUser userMap = findUserByPhone(param.getPhone());
+		if (userMap != null) {
+			if (org.apache.commons.lang3.StringUtils.isNotEmpty(userMap.getAppleKey()) && !param.getAppleKey().equals(userMap.getAppleKey())) {
+				return R.error("该手机号已绑定其他账号");
+			}
+			if (param.getSimExist() == 0 && !Md5Utils.hash(param.getPassword()).equals(userMap.getPassword())) {
+				return R.error("密码不正确");
+			}
+		} else {
+			userMap = createNewAppleUser(param, param.getPhone());
+		}
+
+		userMap.setLoginDevice(param.getLoginDevice());
+		userMap.setSource(param.getSource());
+		if (userMap.getNickName().equals("匿名用户**")) {
+			userMap.setNickName("苹果用户" + param.getPhone().substring(param.getPhone().length() - 4));
+		}
+		userMap.setAppleKey(param.getAppleKey());
+		if (userService.updateFsUser(userMap)>0){
+			return generateTokenAndReturn(userMap);
+		}
+		return R.error("绑定手机号失败");
+	}
+
+	@ApiOperation("绑定手机号")
+	@PostMapping("/setPhone")
+	public R setPhone(@Validated @RequestBody FsUserEditPhoneParam param) {
+		FsUser user = userService.selectFsUserByUnionid(param.getUnionId());
+		if (user == null) {
+			return R.error("用户数据不存在");
+		}
+		FsUser userMap = findUserByPhone(param.getPhone());
+		if (userMap != null) {
+			return R.error("该手机号已绑定其他账号");
+		}
+		user.setPhone(param.getPhone());
+		user.setLoginDevice(param.getLoginDevice() != null ? param.getLoginDevice() : null );
+		user.setSource(param.getSource()!= null ? param.getSource() : null);
+		userMap = new FsUser();
+		userMap.setLoginDevice(param.getLoginDevice());
+		userMap.setSource(param.getSource());
+		if (user.getNickName().equals("匿名用户**")) {
+			userMap.setNickName("匿名用户" + param.getPhone().substring(param.getPhone().length() - 4));
+		}
+		userMap.setUserId(user.getUserId());
+		userMap.setPhone(param.getPhone());
+		if (userService.updateFsUser(userMap)>0){
+			return generateTokenAndReturn(user);
+		}
+		return R.error("绑定手机号失败");
+	}
+
+	private R handleLoginType1(FsUserLoginParam param) {
+
+		if (org.apache.commons.lang3.StringUtils.isEmpty(param.getPhone()) || org.apache.commons.lang3.StringUtils.isEmpty(param.getPassword())) {
+			return R.error("账号或密码不能为空");
+		}
+
+		FsUser user = findUserByPhone(param.getPhone());
+
+		// 校验用户是否存在及账号状态
+		if (user == null) {
+			return R.error("账号不存在,请先注册账号");
+		} else if (user.getStatus() == 0) {
+			return R.error("账号已停用");
+		} else if (org.apache.commons.lang3.StringUtils.isEmpty(user.getPassword())) {
+			return R.error("账号不存在,请先注册账号");
+		}
+
+		if (!Md5Utils.hash(param.getPassword()).equals(user.getPassword())) {
+			return R.error("密码不正确");
+		}
+
+		return generateTokenAndReturn(user);
+
+	}
+
+	private R handleLoginType3(FsUserLoginParam param) {
+		if (org.apache.commons.lang3.StringUtils.isEmpty(param.getPhone())) {
+			return R.error("获取手机号失败");
+		}
+		// 根据手机号查询用户
+		FsUser user = findUserByPhone(param.getPhone());
+		if (user == null) {
+			createNewUser(param);
+			return R.ok().put("isNew",true).put("phone",encryptPhone(param.getPhone()));
+		} else {
+			if (user.getUnionId()==null){
+				if (user.getPhone().length()<=11){
+					FsUser fsUser = new FsUser();
+					fsUser.setUserId(user.getUserId());
+					fsUser.setPhone(param.getPhone());
+					userMapper.updateFsUser(fsUser);
+					logger.info("zyp \n【手机加密】:{}",encryptPhone(param.getPhone()));
+				}
+				return R.ok().put("isNew",true).put("phone",encryptPhone(param.getPhone()));
+			}
+			/*if (org.apache.commons.lang3.StringUtils.isNotEmpty(param.getJpushId())) {
+				updateExistingUserJpushId(user, param.getJpushId());
+			}*/
+		}
+		return generateTokenAndReturn(user);
+	}
+
+	private FsUser createNewAppleUser(FsUserEditPhoneParam param, String phoneNumber) {
+		FsUser newUser = new FsUser();
+		newUser.setLoginDevice(param.getLoginDevice()!=null ? param.getLoginDevice() : null);
+		newUser.setSource(param.getSource()!=null ? param.getSource() : null);
+		newUser.setAppleKey(param.getAppleKey());
+		newUser.setPhone(param.getPhone());
+		newUser.setPassword(Md5Utils.hash(param.getPassword()));
+		newUser.setNickName("苹果用户" + param.getPhone().substring(param.getPhone().length() - 4));
+		newUser.setCreateTime(new Date());
+		newUser.setStatus(1);
+		newUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20240926/420728ee06e54575ba82665dedb4756b.png");
+		if (org.apache.commons.lang3.StringUtils.isNotEmpty(param.getJpushId())) {
+			newUser.setJpushId(param.getJpushId());
+		}
+		userService.insertFsUser(newUser);
+		return newUser;
+
+	}
+
+	private void updateExistingUserJpushId(FsUser user, String jpushId) {
+		FsUser userMap = new FsUser();
+		userMap.setUserId(user.getUserId());
+		userMap.setJpushId(jpushId);
+		userService.updateFsUser(userMap);
+	}
+
+	private R generateTokenAndReturn(FsUser user) {
+		String token = jwtUtils.generateToken(user.getUserId());
+		redisCache.setCacheObject("userToken:" + user.getUserId(), token, 604800, TimeUnit.SECONDS);
+		int isFirstLogin = userNewTaskService.performTaskOne(user.getUserId());
+		Map<String, Object> map = new HashMap<>();
+		map.put("token", token);
+		map.put("user", user);
+		map.put("isFirst",isFirstLogin);
+		return R.ok(map);
+	}
+
+	private FsUser findUserByPhone(String phone) {
+		// 先根据加密手机号查询用户
+		String jiami = (encryptPhone(phone));
+		FsUser user = userMapper.selectFsUserByPhoneLimitOne(jiami);
+
+		// 如果没有找到用户,再根据手机号查询
+		if (user == null) {
+			user = userMapper.selectFsUserByPhoneLimitOne(phone);
+
+		}
+		return user;
+	}
+
+	private FsUser createNewUser(FsUserLoginParam param) {
+		FsUser newUser = new FsUser();
+		newUser.setLoginDevice(param.getLoginDevice() != null ? param.getLoginDevice() : null);
+		newUser.setSource(param.getSource() != null ? param.getSource() : null );
+		newUser.setNickName(NickNameConstant.getNickName());
+		newUser.setPhone(param.getPhone());
+		newUser.setCreateTime(new Date());
+		newUser.setStatus(1);
+		newUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20240926/420728ee06e54575ba82665dedb4756b.png");
+		/*if (org.apache.commons.lang3.StringUtils.isNotEmpty(param.getJpushId())) {
+			newUser.setJpushId(param.getJpushId());
+		}*/
+		userService.insertFsUser(newUser);
+		return newUser;
+	}
+
+	//
+
 }

+ 18 - 0
fs-live-app/src/main/java/com/fs/app/param/FsAddressParseParam.java

@@ -0,0 +1,18 @@
+package com.fs.app.param;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+@Getter
+@Setter
+public class FsAddressParseParam implements Serializable {
+
+
+    private String content;
+
+
+
+
+}

+ 59 - 0
fs-live-app/src/main/java/com/fs/app/param/FsUserAddressAddEditParam.java

@@ -0,0 +1,59 @@
+package com.fs.app.param;
+
+import com.fs.common.annotation.Excel;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Getter
+@Setter
+public class FsUserAddressAddEditParam implements Serializable {
+
+    /** ID */
+    private Long addressId;
+
+    /** 收货人姓名 */
+    @NotBlank(message = "收货人姓名不能为空")
+    private String realName;
+
+    /** 收货人电话 */
+    @NotBlank(message = "收货人电话不能为空")
+    @Pattern(regexp="^1[3456789]\\d{9}$",message="手机号格式不正确")
+    private String phone;
+
+    /** 收货人所在省 */
+    @NotBlank(message = "收货人地址不能为空")
+    private String province;
+
+    /** 收货人所在市 */
+    @NotBlank(message = "收货人地址不能为空")
+    private String city;
+
+    /** 收货人所在区 */
+    @NotBlank(message = "收货人地址不能为空")
+    private String district;
+
+    /** 城市IDS */
+    @Excel(name = "城市IDS")
+    private String cityIds;
+
+    /** 收货人详细地址 */
+    @NotBlank(message = "收货人详细地址不能为空")
+    private String detail;
+
+    /** 邮编 */
+    private String postCode;
+
+    /** 经度 */
+    private String longitude;
+
+    /** 纬度 */
+    private String latitude;
+
+    private Integer isDefault;
+
+
+}

+ 32 - 0
fs-live-app/src/main/java/com/fs/app/param/FsUserEditPhoneParam.java

@@ -0,0 +1,32 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class FsUserEditPhoneParam implements Serializable {
+
+    @NotBlank(message = "手机号不能为空")
+    @Pattern(regexp="^1[3456789]\\d{9}$",message="手机号格式不正确")
+    private String phone;
+    @NotNull(message = "unionId不能为空")
+    private String unionId;
+
+    private String loginDevice; //当前登陆设备
+
+    private String jpushId;
+
+    private String source;
+
+    private String appleKey;
+
+    private String password;
+    /**
+     * 是否有SIM卡 0不存在 1存在
+     */
+    private Integer simExist;
+}

+ 19 - 0
fs-live-app/src/main/java/com/fs/app/param/FsUserLoginByWeChatParam.java

@@ -0,0 +1,19 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+@Data
+public class FsUserLoginByWeChatParam implements Serializable {
+    private String jpushId;
+
+    @NotBlank(message = "code参数缺失")
+    private String code;
+
+    private String loginDevice;//当前登陆设备
+
+    private String source; //app来源
+
+}

+ 26 - 0
fs-live-app/src/main/java/com/fs/app/param/FsUserLoginParam.java

@@ -0,0 +1,26 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class FsUserLoginParam implements Serializable {
+    private String phone;
+
+    private String password;
+
+    @NotNull(message = "登录类型不能为空")
+    private Integer loginType;//登录类型 1密码登录  2微信登录  3手机号一键登录
+
+    private String code;
+    private String uuid;
+
+    private String jpushId;
+
+    private String openId;
+
+    private String loginDevice;
+    private String source;
+}

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

@@ -1,14 +1,35 @@
 package com.fs.app.task;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.fs.live.domain.Live;
-import com.fs.live.service.ILiveService;
+import com.fs.app.vo.LotteryVo;
+import com.fs.app.websocket.bean.SendMsgVo;
+import com.fs.app.websocket.service.WebSocketServer;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.spring.SpringUtils;
+import com.fs.his.service.IFsUserService;
+import com.fs.live.domain.*;
+import com.fs.live.mapper.LiveLotteryRegistrationMapper;
+import com.fs.live.param.LiveReplayParam;
+import com.fs.live.service.*;
+import com.fs.live.vo.LiveLotteryConfVo;
+import com.fs.live.vo.LiveLotteryProductListVo;
 import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.websocket.Session;
+import java.math.BigDecimal;
+import java.time.Instant;
 import java.time.LocalDateTime;
-import java.util.List;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
 
 @Component
 @AllArgsConstructor
@@ -16,21 +37,268 @@ public class Task {
 
     private final ILiveService liveService;
 
+    private final ILiveDataService liveDataService;
+
+    private final RedisCache redisCache;
+
+    @Autowired
+    private ILiveWatchUserService liveWatchUserService;
+    @Autowired
+    private IFsUserService fsUserService;
+    @Autowired
+    private ILiveRewardRecordService liveRewardRecordService;
+    @Autowired
+    private WebSocketServer webSocketServer;
+    @Autowired
+    private ILiveAutoTaskService liveAutoTaskService;
+    @Autowired
+    private ILiveLotteryConfService liveLotteryConfService;
+    @Autowired
+    private ILiveUserLotteryRecordService liveUserLotteryRecordService;
+    @Autowired
+    private LiveLotteryRegistrationMapper liveLotteryRegistrationMapper;
+    @Autowired
+    private ILiveRedConfService liveRedConfService;
+
     @Scheduled(cron = "0 0/1 * * * ?")
-    public void selectSopUserLogsListByTime() {
+    //public void selectSopUserLogsListByTime() {
+    public void updateLiveStatusByTime() {
+        List<Live> list = liveService.list(new QueryWrapper<Live>().ne("status", 3).in("live_type", 2, 3).eq("is_audit", 1));
+        if (list.isEmpty())
+            return;
+        List<Long> liveIdLists = list.stream().map(Live::getLiveId).collect(Collectors.toList());
+        List<LiveAutoTask> liveAutoTasks = liveAutoTaskService.selectLiveAutoTaskByLiveIds(liveIdLists);
+        List<Live> activeLiveList = new ArrayList<>();
         LocalDateTime now = LocalDateTime.now();
-        List<Live> list = liveService.list(new QueryWrapper<Live>().ne("status", 3));
         list.forEach(live -> {
-            if (now.isAfter(live.getStartTime()) && now.isBefore(live.getFinishTime())) {
-                live.setStatus(2);
-            } else if (now.isBefore(live.getStartTime())) {
-                live.setStatus(1);
-            } else if (now.isAfter(live.getFinishTime())) {
-                live.setStatus(3);
+            if (live.getLiveType() != 3) {
+                if (live.getFinishTime() == null) {
+                    if (now.isAfter(live.getStartTime().minusSeconds(2L))){
+                        live.setStatus(2);
+                        activeLiveList.add( live);
+                    } else if (now.isBefore(live.getStartTime())) {
+                        live.setStatus(1);
+                    }
+                } else {
+                    if (now.isAfter(live.getStartTime().minusSeconds(2L)) && now.isBefore(live.getFinishTime())) {
+                        live.setStatus(2);
+                        activeLiveList.add( live);
+                    } else if (now.isBefore(live.getStartTime().minusSeconds(2L))) {
+                        live.setStatus(1);
+                    } else if (now.isAfter(live.getFinishTime().minusSeconds(2L))) {
+                        live.setStatus(3);
+                    }
+                }
+            } else {
+                // 直播回放只需要检测结束时间就好了
+                LiveReplayParam liveReplayParam = JSON.parseObject(live.getLiveConfig(), LiveReplayParam.class);
+                if (liveReplayParam.getIsPlaybackOpen()) {
+                    if (liveReplayParam.getFinishTime() != null) {
+                        if (now.isAfter(live.getFinishTime().minusSeconds(2L))) {
+                            live.setStatus(3);
+                        }
+                    }
+                }
             }
+
         });
+        String key = "live:auto_task:";
+        if(!activeLiveList.isEmpty()){
+            activeLiveList.forEach(live -> {
+                List<LiveAutoTask> collect = liveAutoTasks.stream().filter(liveAutoTask -> liveAutoTask.getLiveId().equals(live.getLiveId())).collect(Collectors.toList());
+                if (!collect.isEmpty()) {
+                    collect.forEach(liveAutoTask -> {
+                        liveAutoTask.setCreateTime(null);
+                        liveAutoTask.setUpdateTime(null);
+                        redisCache.redisTemplate.opsForZSet().add(key + live.getLiveId(), JSON.toJSONString(liveAutoTask),liveAutoTask.getAbsValue().getTime());
+                        redisCache.redisTemplate.expire(key+live.getLiveId(), 30, java.util.concurrent.TimeUnit.MINUTES);
+                    });
+                }
+            });
+        }
+
         if(!list.isEmpty()){
             liveService.updateBatchById(list);
         }
     }
+    @Scheduled(cron = "0/1 * * * * ?")
+    public void liveLotteryTask() {
+        long currentTime = Instant.now().toEpochMilli(); // 当前时间戳(毫秒)
+        String lotteryKey = "live:lottery_task:*";
+        Set<String> allLiveKeys = redisCache.redisTemplate.keys(lotteryKey);
+        if (allLiveKeys != null && !allLiveKeys.isEmpty()) {
+            for (String liveKey : allLiveKeys) {
+                Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
+                if (range == null || range.isEmpty()) {
+                    continue;
+                }
+                processLotteryTask(range);
+                redisCache.redisTemplate.opsForZSet()
+                        .removeRangeByScore(liveKey, 0, currentTime);
+            }
+        }
+
+        String redKey = "live:red_task:*";
+        allLiveKeys = redisCache.redisTemplate.keys(redKey);
+        if (allLiveKeys == null || allLiveKeys.isEmpty()) {
+            return;
+        }
+        for (String liveKey : allLiveKeys) {
+            Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
+            if (range == null || range.isEmpty()) {
+                continue;
+            }
+            updateRedStatus(range);
+            redisCache.redisTemplate.opsForZSet()
+                    .removeRangeByScore(liveKey, 0, currentTime);
+        }
+    }
+
+    private void updateRedStatus(Set<String> range) {
+        liveRedConfService.finishRedStatusBySetIds(range);
+    }
+
+    private void processLotteryTask(Set<String> range) {
+        List<LiveLotteryConfVo> liveLotteries = liveLotteryConfService.selectVoListByLotteryIds(range);
+        if(liveLotteries.isEmpty()) return;
+        Date now = new Date();
+        for (LiveLotteryConfVo liveLottery : liveLotteries) {
+            // 查询抽奖数量
+            List<LiveLotteryProductListVo> products = liveLottery.getProducts();
+            Integer totalLots = products.stream().mapToInt(liveLotteryProductListVo -> Math.toIntExact(liveLotteryProductListVo.getTotalLots())).sum();
+            if(totalLots <= 0) continue;
+            // 查询在线用户 并且参与了抽奖的用户
+            List<LiveWatchUser> liveWatchUsers = liveWatchUserService.selectLiveWatchAndRegisterUser(liveLottery.getLiveId(),liveLottery.getLotteryId(), totalLots);
+            if(liveWatchUsers.isEmpty()) continue;
+            LiveLotteryRegistration liveLotteryRegistration;
+            // 收集中奖信息
+            List<LotteryVo> lotteryVos = new ArrayList<>();
+            for (LiveLotteryProductListVo liveLotteryProductListVo : products) {
+                // 随机抽奖一个用户获取奖品
+                Long totalLotsPerProduct = liveLotteryProductListVo.getTotalLots();
+                for (int i = 0; i < totalLotsPerProduct && !liveWatchUsers.isEmpty(); i++) {
+                    // 随机选择一个用户
+                    int randomIndex = new java.util.Random().nextInt(liveWatchUsers.size());
+                    LiveWatchUser winningUser = liveWatchUsers.get(randomIndex);
+
+                    // 创建中奖记录
+                    LiveUserLotteryRecord record = new LiveUserLotteryRecord();
+                    record.setLotteryId(liveLottery.getLotteryId());
+                    record.setLiveId(liveLottery.getLiveId());
+                    record.setUserId(winningUser.getUserId());
+                    record.setProductId(liveLotteryProductListVo.getProductId());
+                    record.setCreateTime(new Date());
+
+                    // 保存中奖记录
+                    liveUserLotteryRecordService.insertLiveUserLotteryRecord(record);
+                    liveLotteryRegistration = new LiveLotteryRegistration();
+                    liveLotteryRegistration.setLotteryId(liveLottery.getLotteryId());
+                    liveLotteryRegistration.setLiveId(liveLottery.getLotteryId());
+                    liveLotteryRegistration.setUserId(winningUser.getUserId());
+                    liveLotteryRegistration.setIsWin(1L);
+                    liveLotteryRegistration.setUpdateTime(now);
+                    liveLotteryRegistration.setRizeLevel(liveLotteryProductListVo.getPrizeLevel());
+                    liveLotteryRegistrationMapper.updateLiveLotteryRegistrationNoId(liveLotteryRegistration);
+                    // 从候选列表中移除该用户,确保每人只能中奖一次
+                    liveWatchUsers.remove(randomIndex);
+                    LotteryVo lotteryVo = new LotteryVo();
+                    lotteryVo.setUserId(winningUser.getUserId());
+                    lotteryVo.setUserName(winningUser.getNickName());
+                    lotteryVo.setPrizeLevel(liveLotteryProductListVo.getPrizeLevel());
+                    lotteryVo.setProductName(liveLotteryProductListVo.getProductName());
+                    lotteryVos.add(lotteryVo);
+                }
+            }
+            SendMsgVo sendMsgVo = new SendMsgVo();
+            sendMsgVo.setLiveId(liveLottery.getLiveId());
+            sendMsgVo.setCmd("LotteryDetail");
+            sendMsgVo.setData(JSON.toJSONString(lotteryVos));
+            webSocketServer.broadcastMessage(liveLottery.getLiveId(), JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
+        }
+
+        List<Long> collect = liveLotteries.stream().map(LiveLotteryConfVo::getLotteryId).collect(Collectors.toList());
+        liveLotteryConfService.finishStatusByLotteryIds(collect);
+    }
+
+    @Scheduled(cron = "0/1 * * * * ?")
+    public void liveAutoTask() {
+        long currentTime = Instant.now().toEpochMilli(); // 当前时间戳(毫秒)
+
+        Set<String> allLiveKeys = redisCache.redisTemplate.keys("live:auto_task:*");
+        if (allLiveKeys == null || allLiveKeys.isEmpty()) {
+            return; // 没有数据,直接返回
+        }
+        // 2. 遍历每个直播间的ZSet键
+        for (String liveKey : allLiveKeys) {
+            // 3. 获取当前直播间ZSet中所有元素(按score排序)
+            // range方法:0表示第一个元素,-1表示最后一个元素,即获取全部
+            Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
+            if (range == null || range.isEmpty()) {
+                continue; // 没有数据,直接返回
+            }
+            redisCache.redisTemplate.opsForZSet()
+                    .removeRangeByScore(liveKey, 0, currentTime);
+            processAutoTask(range);
+        }
+    }
+
+    private void processAutoTask(Set<String> range) {
+        for (String liveAutoTask : range) {
+            LiveAutoTask task = JSON.parseObject(liveAutoTask, LiveAutoTask.class);
+            webSocketServer.handleAutoTask(task);
+            task.setFinishStatus(1L);
+            liveAutoTaskService.finishLiveAutoTask(task);
+        }
+    }
+
+    @Scheduled(cron = "0 0/1 * * * ?")
+    @Transactional
+    public void autoUpdateWatchReward() {
+
+        // 1.查询所有直播中的直播间
+        List<Live> lives = liveService.liveList();
+
+
+        // 2.检查是否开启观看奖励
+        List<Live> openRewardLives = lives.stream().filter(live -> StringUtils.isNotEmpty(live.getConfigJson())).collect(Collectors.toList());
+        Date now = new Date();
+
+        for (Live openRewardLive : openRewardLives) {
+            String configJson = openRewardLive.getConfigJson();
+            LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
+            if (config.getEnabled()) {
+                // 3.检查当前直播间的在线用户(可以传入一个时间,然后查出来当天没领取奖励的用户)
+                List<LiveWatchUser> onlineUser = liveWatchUserService.checkOnlineNoRewardUser(openRewardLive.getLiveId(), now)
+                        .stream().filter(user -> now.getTime() - user.getUpdateTime().getTime() > config.getWatchDuration() * 60 * 1000)
+                        .collect(Collectors.toList());
+                if(onlineUser.isEmpty()) continue;
+
+                List<Long> userIds = onlineUser.stream().map(LiveWatchUser::getUserId).collect(Collectors.toList());
+                // 4.保存用户领取记录
+                saveUserRewardRecord(openRewardLive.getLiveId(), userIds,config.getScoreAmount());
+                // 5.更新用户积分(芳华币
+                fsUserService.increaseIntegral(userIds,config.getScoreAmount());
+                // 6.发送websocket事件消息 通知用户自动领取成功
+                userIds.forEach(userId -> webSocketServer.sendIntegralMessage(openRewardLive.getLiveId(),userId,config.getScoreAmount()));
+
+            }
+        }
+    }
+    private void saveUserRewardRecord(Long liveId, List<Long> userIds,Long scoreAmount) {
+        for (Long userId : userIds) {
+            LiveRewardRecord record = new LiveRewardRecord();
+            record.setLiveId(liveId);
+            record.setUserId(userId);
+            record.setIncomeType(1L);
+            record.setSourceType(1L);
+            record.setSourceId(0L);
+            record.setRewardType(2L);
+            record.setNum(BigDecimal.valueOf(scoreAmount));
+            record.setRewardType(2L);
+            record.setCreateTime(new Date());
+            record.setCreateBy(String.valueOf(userId));
+            liveRewardRecordService.insertLiveRewardRecord(record);
+        }
+    }
+
 }

+ 85 - 0
fs-live-app/src/main/java/com/fs/app/utils/CityTreeUtil.java

@@ -0,0 +1,85 @@
+package com.fs.app.utils;
+import com.fs.app.vo.CityVO;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName 树形工具类
+ **/
+public class CityTreeUtil {
+    /**
+     * 获得指定节点下所有归档
+     *
+     * @param list
+     * @param parentId
+     * @return
+     */
+    public static List<CityVO> list2TreeConverter(List<CityVO> list, String parentId) {
+        List<CityVO> returnList = new ArrayList<>();
+
+        for (CityVO res : list) {
+            //判断对象是否为根节点
+
+            if (res.getPid().equals(parentId)) {
+                //该节点为根节点,开始递归
+
+                //通过递归为节点设置childList
+                recursionFn(list, res);
+
+                returnList.add(res);
+            }
+        }
+
+        return returnList;
+    }
+
+    /**
+     * 递归列表
+     * 通过递归,给指定t节点设置childList
+     *
+     * @param list
+     * @param t
+     */
+    public static void recursionFn(List<CityVO> list, CityVO t) {
+        //只能获取当前t节点的子节点集,并不是所有子节点集
+        List<CityVO> childsList = getChildList(list, t);
+
+        //设置他的子集对象集
+        t.setC(childsList);
+
+        //迭代子集对象集
+
+        //遍历完,则退出递归
+        for (CityVO nextChild : childsList) {
+
+            //判断子集对象是否还有子节点
+            if (!CollectionUtils.isEmpty(childsList)) {
+                //有下一个子节点,继续递归
+                recursionFn(list, nextChild);
+            }
+        }
+    }
+
+    /**
+     * 获得指定节点下的所有子节点
+     *
+     * @param list
+     * @param t
+     * @return
+     */
+    public static List<CityVO> getChildList(List<CityVO> list, CityVO t) {
+        List<CityVO> childsList = new ArrayList<>();
+        //遍历集合元素,如果元素的Parentid==指定元素的id,则说明是该元素的子节点
+        for (CityVO t1 : list) {
+            if (t1.getPid().equals(t.getV())) {
+                childsList.add(t1);
+            }
+        }
+
+        return childsList;
+    }
+
+
+}

+ 46 - 0
fs-live-app/src/main/java/com/fs/app/utils/VerifyUtils.java

@@ -0,0 +1,46 @@
+package com.fs.app.utils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+
+public class VerifyUtils {
+
+    /**
+     * 验证签名
+     */
+    public static boolean verifySignature(String liveId, String userId, String userType, String secret, String signature) throws Exception {
+        String expected = generateSignature(liveId, userId, userType, secret);
+        return expected.equals(signature);
+    }
+
+    /**
+     * 生成签名:将 liveId、userId、userType 按顺序拼接后,用 HMAC-SHA256 算法生成签名
+     *
+     * @param liveId   直播间ID
+     * @param userId   用户ID
+     * @param userType 用户类型
+     * @param secret   共享密钥
+     * @return 十六进制格式的签名
+     * @throws Exception e
+     */
+    private static String generateSignature(String liveId, String userId, String userType, String secret) throws Exception {
+        String data = liveId + userId + userType + secret;
+        Mac mac = Mac.getInstance("HmacSHA256");
+        SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
+        mac.init(keySpec);
+        byte[] rawHmac = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
+        return bytesToHex(rawHmac);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     */
+    private static String bytesToHex(byte[] bytes) {
+        StringBuilder sb = new StringBuilder();
+        for (byte b : bytes) {
+            sb.append(String.format("%02x", b));
+        }
+        return sb.toString();
+    }
+}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio