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

直播间总台 销售端直播代码

yuhongqi 1 месяц назад
Родитель
Сommit
f3ed134b22
24 измененных файлов с 956 добавлено и 118 удалено
  1. 47 8
      fs-company/src/main/java/com/fs/company/controller/live/LiveController.java
  2. 30 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveGoodsController.java
  3. 134 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryConfController.java
  4. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryRecordController.java
  5. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveLotteryRegistrationController.java
  6. 115 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveRedConfController.java
  7. 1 1
      fs-company/src/main/java/com/fs/company/controller/store/FsStoreProductController.java
  8. 12 59
      fs-live-app/src/main/java/com/fs/app/controller/LiveController.java
  9. 1 1
      fs-live-app/src/main/java/com/fs/framework/config/SecurityConfig.java
  10. 3 5
      fs-service/src/main/java/com/fs/his/mapper/FsStoreProductMapper.java
  11. 1 2
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreProductServiceImpl.java
  12. 17 0
      fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java
  13. 11 0
      fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java
  14. 18 0
      fs-service/src/main/java/com/fs/live/service/ILiveGoodsService.java
  15. 20 0
      fs-service/src/main/java/com/fs/live/service/ILiveService.java
  16. 20 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveGoodsServiceImpl.java
  17. 147 15
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  18. 82 0
      fs-service/src/main/java/com/fs/live/utils/ProcessManager.java
  19. 25 0
      fs-service/src/main/java/com/fs/live/vo/LiveGoodsListVo.java
  20. 1 0
      fs-service/src/main/java/com/fs/live/vo/LiveGoodsVo.java
  21. 21 0
      fs-service/src/main/java/com/fs/live/vo/LiveListVo.java
  22. 16 1
      fs-service/src/main/resources/mapper/live/LiveGoodsMapper.xml
  23. 34 21
      fs-service/src/main/resources/mapper/live/LiveMapper.xml
  24. 6 5
      fs-service/src/main/resources/mapper/live/LiveMsgMapper.xml

+ 47 - 8
fs-company/src/main/java/com/fs/company/controller/live/LiveController.java

@@ -1,6 +1,5 @@
 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;
@@ -10,22 +9,16 @@ import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.CompanyUser;
+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 okhttp3.FormBody;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -173,6 +166,42 @@ public class LiveController extends BaseController
         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 直播间
@@ -182,4 +211,14 @@ public class LiveController extends BaseController
         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());
+    }
 }

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

@@ -3,6 +3,7 @@ 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;
@@ -11,7 +12,9 @@ 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.*;
@@ -121,4 +124,31 @@ public class LiveGoodsController extends BaseController
         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);
+    }
+
+    /**
+     * 设置企业ID和企业用户ID
+     */
+    private void setListCompanyId(LiveGoodsListVo live) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        live.setCompanyId(user.getCompanyId());
+        live.setCompanyUserId(user.getUserId());
+    }
 }

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

@@ -0,0 +1,134 @@
+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)
+    {
+        liveLotteryConfService.updateLiveLotteryConf(liveLotteryConf);
+        return R.ok(liveLotteryConf.getLotteryStatus());
+    }
+
+    /**
+     * 删除直播抽奖配置
+     */
+    @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));
+    }
+}

+ 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());
+    }
+
+
+
+}

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

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

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

@@ -129,65 +129,18 @@ public class LiveController extends AppBaseController {
 	}
 
 
-	@PostMapping("/checkLiving")
+	@PostMapping("/startLiving")
 	public R checkLiving(HttpServletRequest request, @RequestBody  Map<String, String> params) {
-		// srs直播流服务器 判断是否拥有各种权限
-		String action = params.get("action");
-		if ("on_publish".equals(action)) {
-			System.out.println("Handling on_publish event for stream: " + params.get("stream"));
-			Map<String, String> urlParamsMap = parseQueryParams(params.get("param"));
-			if (urlParamsMap.isEmpty() || urlParamsMap.get("timestamp") == null || urlParamsMap.get("sign") == null) {
-				return R.error();
-			}
-			String s = urlParamsMap.get("timestamp");
-			long timestamp = Long.parseLong(s);
-			String sign = urlParamsMap.get("sign");
-			Date now = new Date();
-			if (((now.getTime() / 1000) - timestamp) > 5 * 60 ) {
-				log.error("直播时间戳过期");
-				return R.error();
-			}
-			String currentSign = Base64Utils.encodeToString(Md5Utils.md5(params.get("stream") + params.get("stream") + timestamp + timestamp)).replace("/","");
-			if (!currentSign.equals(sign)) {
-				return R.error();
-			}
-			Live live = liveService.selectLiveByLiveId(Long.valueOf(params.get("stream")));
-			if (live.getStatus() != 2) {
-				return R.error("直播未开始");
-			}
-			SendMsgVo sendMsgVo = new SendMsgVo();
-			sendMsgVo.setMsg("开始直播");
-			sendMsgVo.setCmd("live_start");
-			webSocketServer.broadcastMessage(Long.valueOf(params.get("stream")), JSONObject.toJSONString(R.ok().put("data",sendMsgVo)));
-			// 在这里添加你的推流校验逻辑
-		} else if ("on_play".equals(action)) {
-			System.out.println("Handling on_play event for stream: " + params.get("stream"));
-			// 在这里添加你的播放校验逻辑
-		}
-		R ok = R.ok();
-		// 允许连接的状态码必须是0
-		ok.put("code", 0);
-		// 返回 0 OK 表示允许连接
-		return ok;
-	}
-
-	public static Map<String, String> parseQueryParams(String url) {
-		Map<String, String> resultMap = new HashMap<>();
-		if (url == null || !url.contains("?")) {
-			return resultMap;
-		}
-		String[] queryParams = url.substring(url.indexOf('?') + 1).split("&");
-		if (queryParams.length != 2) {
-			return resultMap;
-		}
-		for (String param : queryParams) {
-
-			String[] keyValue = param.split("=",2);
-			if (keyValue.length == 2) {
-				resultMap.put(keyValue[0], keyValue[1]);
-			}
-		}
-
-		return resultMap;
+		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}
 	}
 }

+ 1 - 1
fs-live-app/src/main/java/com/fs/framework/config/SecurityConfig.java

@@ -36,7 +36,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
     {
         http.authorizeRequests()
                 .antMatchers("/**").permitAll()
-                .antMatchers("/app/live/checkLiving").permitAll()
+                .antMatchers("/app/live/startLiving").permitAll()
                 .anyRequest().authenticated()
                 .and().csrf().disable();
     }

+ 3 - 5
fs-service/src/main/java/com/fs/his/mapper/FsStoreProductMapper.java

@@ -283,13 +283,11 @@ public interface FsStoreProductMapper {
             "<if test = 'maps.barCode != null    '> " +
             "and p.product_id in(SELECT product_id FROM fs_store_product_attr_value WHERE bar_code =#{maps.barCode}) " +
             "</if>" +
-            "<if test='ids != null and !ids.isEmpty()'> " +
+            "<if test='maps.liveId != null and !maps.liveId.isEmpty()'> " +
             "AND p.product_id NOT IN " +
-            "<foreach collection='ids' item='id' open='(' separator=',' close=')'> " +
-            "          #{id} " +
-            "</foreach> " +
+            " ( select product_id from live_goods where live_id = #{maps.liveId} ) " +
             "</if>"+
             " order by p.product_id desc " +
             "</script>"})
-    List<FsStoreProductVO> selectFsStoreProductListEx(@Param("maps") FsStoreProduct fsStoreProduct,@Param("ids")  List<String> exceptionProductIds);
+    List<FsStoreProductVO> selectFsStoreProductListEx(@Param("maps") FsStoreProduct fsStoreProduct);
 }

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

@@ -154,8 +154,7 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
     public List<FsStoreProductVO> selectFsStoreProductListVO(FsStoreProduct fsStoreProduct) {
 
         if (StringUtils.isNotEmpty(fsStoreProduct.getLiveId())) {
-            List<String> exceptionProductIds = liveGoodsMapper.selectProductIdsByLiveId(Long.valueOf(fsStoreProduct.getLiveId()));
-            return fsStoreProductMapper.selectFsStoreProductListEx(fsStoreProduct, exceptionProductIds);
+            return fsStoreProductMapper.selectFsStoreProductListEx(fsStoreProduct);
         }
 
         return fsStoreProductMapper.selectFsStoreProductListVO(fsStoreProduct);

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

@@ -4,6 +4,7 @@ import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.his.domain.FsStoreProduct;
 import com.fs.live.domain.LiveGoods;
+import com.fs.live.vo.LiveGoodsListVo;
 import com.fs.live.vo.LiveGoodsVo;
 import org.apache.ibatis.annotations.Param;
 
@@ -87,4 +88,20 @@ public interface LiveGoodsMapper extends BaseMapper<LiveGoods>{
      * @return 商品信息集合
      */
     List<LiveGoodsVo> selectProductListByLiveId(LiveGoods liveGoods);
+
+    /**
+     * 批量更新商品信息
+     *
+     * @param listVo 直播商品
+     * @return 批量更新结果
+     */
+    int updateBatchList(@Param("listVo") LiveGoodsListVo listVo);
+
+/**
+     * 批量删除商品信息
+     *
+     * @param listVo 直播商品
+     * @return 批量删除结果
+     */
+    int deleteBatchList(@Param("listVo") LiveGoodsListVo listVo);
 }

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

@@ -2,6 +2,7 @@ package com.fs.live.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.live.domain.Live;
+import com.fs.live.vo.LiveListVo;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
@@ -81,4 +82,14 @@ public interface LiveMapper extends BaseMapper<Live>
     @Select("select * from live where talent_id=#{talentId}")
     Live selectLiveByTalentId(@Param("talentId") String talentId);
 
+    /**
+     * 批量更新直播上下架状态
+     * @return 更新记录数
+     */
+    int updateBatchLiveList(@Param("liveVo") LiveListVo liveVo);
+    /**
+     * 批量删除直播
+     * @return 更新记录数
+     */
+    int deleteBatchLiveList(@Param("liveVo") LiveListVo listVo);
 }

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

@@ -4,11 +4,13 @@ import java.util.List;
 import java.util.Map;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.entity.SysUser;
 import com.fs.company.domain.CompanyUser;
 import com.fs.his.domain.FsStore;
 import com.fs.his.domain.FsStoreProduct;
 import com.fs.live.domain.LiveGoods;
+import com.fs.live.vo.LiveGoodsListVo;
 import com.fs.live.vo.LiveGoodsVo;
 
 /**
@@ -86,4 +88,20 @@ public interface ILiveGoodsService extends IService<LiveGoods>{
     Map<String, Object> getStoreByLiveId(Long liveId);
 
     int insertLiveGoodsAdmin(Map<String, Object> payload, SysUser user);
+
+    /**
+     * 批量处理商品上下架
+     *
+     * @param listVo 直播商品
+     * @return 直播商品集合
+     */
+    R handleShelfOrUn(LiveGoodsListVo listVo);
+
+    /**
+     * 批量处理商品删除
+     *
+     * @param listVo 直播商品
+     * @return 直播商品集合
+     */
+    R handleDeleteSelected(LiveGoodsListVo listVo);
 }

+ 20 - 0
fs-service/src/main/java/com/fs/live/service/ILiveService.java

@@ -1,8 +1,10 @@
 package com.fs.live.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.live.domain.Live;
+import com.fs.live.vo.LiveListVo;
 
 import java.util.List;
 import java.util.Map;
@@ -118,4 +120,22 @@ public interface ILiveService extends IService<Live>
      */
     R verifyIdInfo(Map<String, String> payload);
 
+    /**
+     * 开始循环播放视频
+     */
+    R startLoopPlay(Live live);
+
+    /**
+     * 停止循环播放
+     */
+    R stopLoopPlay(Live live);
+
+    /**
+     * 批量上下架视频
+     */
+    R handleShelfOrUn(LiveListVo listVo);
+    /**
+     * 批量删除视频
+     */
+    R handleDeleteSelected(LiveListVo listVo);
 }

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

@@ -6,6 +6,7 @@ import java.util.Map;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.entity.SysUser;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -16,6 +17,7 @@ import com.fs.his.mapper.FsStoreProductMapper;
 import com.fs.his.domain.FsStore;
 import com.fs.his.service.IFsStoreProductService;
 import com.fs.his.service.IFsStoreService;
+import com.fs.live.vo.LiveGoodsListVo;
 import com.fs.live.vo.LiveGoodsVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -209,4 +211,22 @@ public class LiveGoodsServiceImpl extends ServiceImpl<LiveGoodsMapper, LiveGoods
 //        // 批量插入
         return baseMapper.insertLiveGoodsList(liveGoodsList);
     }
+
+    @Override
+    public R handleShelfOrUn(LiveGoodsListVo listVo) {
+        int updatedCount = baseMapper.updateBatchList(listVo);
+        if (updatedCount > 0) {
+            return R.ok("操作成功");
+        }
+        return R.error();
+    }
+
+    @Override
+    public R handleDeleteSelected(LiveGoodsListVo listVo) {
+        int deleteCount = baseMapper.deleteBatchList(listVo);
+        if (deleteCount > 0) {
+            return R.ok("操作成功");
+        }
+        return R.error();
+    }
 }

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

@@ -3,6 +3,7 @@ package com.fs.live.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.ad.yk.utils.Md5Util;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.DateUtils;
@@ -16,6 +17,8 @@ import com.fs.live.mapper.LiveMapper;
 import com.fs.live.service.ILiveDataService;
 import com.fs.live.service.ILiveService;
 import com.fs.live.service.ILiveVideoService;
+import com.fs.live.utils.ProcessManager;
+import com.fs.live.vo.LiveListVo;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
 import lombok.AllArgsConstructor;
@@ -52,6 +55,9 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
     @Autowired
     private IFsUserTalentService fsUserTalentService;
 
+    @Autowired
+    private ProcessManager processManager;
+
     /**
      * 查询直播
      *
@@ -217,9 +223,9 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
             return R.error("缺失直播配置");
         }
         String rtmpPushUrl = generateRtmpPushUrl(livingConfigMap.get("domain"), livingConfigMap.get("app"), liveId.toString());
-        String flvPlayUrl = generateFlvPlayUrl(livingConfigMap.get("http"), livingConfigMap.get("app"), liveId.toString());
+        String hlvPlayUrl = generateHlvPlayUrl(livingConfigMap.get("http"), livingConfigMap.get("app"), liveId.toString());
         live.setRtmpUrl(rtmpPushUrl);
-        live.setFlvHlsUrl(flvPlayUrl);
+        live.setFlvHlsUrl(hlvPlayUrl);
         live.setStartTime(LocalDateTime.now());
         live.setStatus(2);
         live.setLiveType(1);
@@ -276,6 +282,102 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
         liveMapper.updateLive(live);
         return R.ok();
     }
+    /**
+     * 循环播放
+     * @param live 直播
+     * @return R
+     */
+    @Override
+    public R startLoopPlay(Live live) {
+        try {
+            Live curLive = liveMapper.selectLiveByLiveId(live.getLiveId());
+            if (curLive == null) {
+                return R.error("直播间不存在");
+            }
+            LiveVideo curLiveVideo = liveVideoService.selectLiveVideoByLiveId(live.getLiveId());
+            if (curLiveVideo == null) {
+                return R.error("录播不存在");
+            }
+            Date now = new Date();
+
+            // 生成唯一的流密钥
+            String streamKey = "stream_" + live.getLiveId() + "_" + System.currentTimeMillis();
+
+            // 构建FFmpeg推流命令
+            String ffmpegCmd = buildFFmpegCommand(curLiveVideo.getVideoUrl(), streamKey);
+
+            // 启动推流进程
+            Process process = processManager.startProcess(ffmpegCmd);
+
+            // 保存流信息到数据库
+            curLive.setLiveType(2);
+            curLive.setRtmpUrl("rtmp://your-srs-server/live/" + streamKey);
+            curLive.setUpdateTime(now);
+
+
+            liveMapper.updateLive(curLive);
+
+            return R.ok();
+        } catch (Exception e) {
+            return R.error("启动推流失败: " + e.getMessage());
+        }
+    }
+    /**
+     * 停止循环播放
+     * @param live 直播
+     * @return R
+     */
+    @Override
+    public R stopLoopPlay(Live live) {
+        try {
+            Live curLive = liveMapper.selectLiveByLiveId(live.getLiveId());
+            if (curLive == null) {
+                return R.error("直播间不存在");
+            }
+            // 停止推流进程
+            boolean stopped = processManager.stopProcess(curLive.getRemark());
+            if (!stopped) {
+                return R.error("停止播放失败");
+            }
+            // 更新流状态
+            curLive.setStatus(2);
+            curLive.setUpdateTime(new Date());
+            liveMapper.updateLive(curLive);
+
+            return R.ok();
+        } catch (Exception e) {
+            return R.error("停止播放失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public R handleShelfOrUn(LiveListVo listVo) {
+        int updatedCount = liveMapper.updateBatchLiveList(listVo);
+        if (updatedCount > 0) {
+            return R.ok("操作成功");
+        }
+        return R.error();
+    }
+
+    @Override
+    public R handleDeleteSelected(LiveListVo listVo) {
+        int deleteCount = liveMapper.deleteBatchLiveList(listVo);
+        if (deleteCount > 0) {
+            return R.ok("操作成功");
+        }
+        return R.error();
+    }
+
+    /**
+     * 构建FFmpeg推流命令
+     */
+    private String buildFFmpegCommand(String videoPath, String streamKey) {
+        return String.format(
+                "ffmpeg -re -stream_loop -1 -i \"%s\" -c:v libx264 -preset ultrafast -b:v 1000k " +
+                        "-c:a aac -b:a 128k -f flv rtmp://your-srs-server/live/%s",
+                videoPath, streamKey
+        );
+    }
 
     /**
      * 身份证信息验证 阿里商品购买接口
@@ -291,9 +393,8 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
         if (live == null) {
             return R.error("直播间不存在");
         }
-        String url = "https://puhui.shumaidata.com/idcard-ocr/photo/puhui";
-        // todo 买的产品 appcode 个人  需要更换为公司的
-        String appCode = "ed8f0f22564b48c5abdb18a02c1d701c";
+        String url = "https://idcardside.market.alicloudapi.com/idcard_ocr";
+        String appCode = "0a01beb5322e49ca802423fe29df9582";
         try {
             Map<String, String> params = new HashMap<>();
             //image 和 url 二选一 ,选择其中一个时,请注释另外一个参数,默认使用image
@@ -302,7 +403,6 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
             String result = postForm(appCode, url, params);
             JSONObject jsonObject = JSONObject.parseObject(result);
             if (200 == jsonObject.getIntValue("code") && jsonObject.getBooleanValue("success")) {
-                // todo  后面修改先写死
                 live.setIdCardUrl(payload.get("idCardUrl"));
                 liveMapper.updateLive(live);
                 return R.ok();
@@ -338,19 +438,51 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
 
 
     public static String generateRtmpPushUrl(String domain, String app, String liveId) {
-        long timestamp = System.currentTimeMillis() / 1000; // 秒级时间戳
-        String SECRET_KEY = liveId + timestamp;
-        String sign = Base64Utils.encodeToString(Md5Utils.md5(liveId + SECRET_KEY + timestamp)).replace("/","") ;
-        return String.format("rtmp://%s/%s/%s?timestamp=%d&sign=%s", domain, app, liveId,timestamp,sign);
+        Date now = new Date();
+        now.setTime(now.getTime() + 24 * 3600 * 1000);
+
+        return domain +
+                "/" +
+                app +
+                "/" +
+                liveId +
+                "?" +
+                "txSecret=" +
+                Md5Util.MD5("a61df75ae15271d7ef922f308e61e92e" + liveId + to16Hex(now)) +
+                "&" +
+                "txTime=" +
+                to16Hex(now);
     }
 
     /**
      * 生成 FLV 播放地址(用于前端播放)
      */
-    public static String generateFlvPlayUrl(String domain, String app, String liveId) {
-        long timestamp = System.currentTimeMillis() / 1000;
-        String SECRET_KEY = liveId + timestamp;
-        String sign = Base64Utils.encodeToString(Md5Utils.md5(liveId + SECRET_KEY + timestamp)).replace("/","");
-        return String.format("http://%s/%s/%s.m3u8?timestamp=%d&sign=%s", domain, app, liveId, timestamp, sign);
+    public static String generateHlvPlayUrl(String domain, String app, String liveId) {
+        Date now = new Date();
+        now.setTime(now.getTime() + 24 * 3600 * 1000);
+
+        return domain +
+                "/" +
+                app +
+                "/" +
+                liveId +
+                ".m3u8?" +
+                "txSecret=" +
+                Md5Util.MD5("NiMfMYG5HQxZQ5bk88ri" + liveId + to16Hex(now)) +
+                "&" +
+                "txTime=" +
+                to16Hex(now);
+    }
+
+    /**
+     * 将传入的时间转换为 16进制
+     *
+     * @param date
+     * @return
+     */
+    public static String to16Hex(Date date) {
+        Long aLong = date.getTime() / 1000;
+        String hexString = Long.toHexString(aLong);
+        return hexString.toUpperCase();
     }
 }

+ 82 - 0
fs-service/src/main/java/com/fs/live/utils/ProcessManager.java

@@ -0,0 +1,82 @@
+package com.fs.live.utils;
+
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * &#064;Description:  专门使用 ff mpg 推流srs直播
+ * &#064;Author:  yhq
+ * &#064;Date:  20250723
+ */
+@Component
+public class ProcessManager {
+    private final Map<String, Process> processMap = new ConcurrentHashMap<>();
+
+    /**
+     * 启动进程
+     */
+    public Process startProcess(String command) throws IOException {
+        ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
+        Process process = processBuilder.start();
+
+        String processId = getProcessId(process);
+        processMap.put(processId, process);
+
+        // 监听进程结束
+        CompletableFuture.runAsync(() -> {
+            try {
+                process.waitFor();
+                processMap.remove(processId);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        });
+
+        return process;
+    }
+
+    /**
+     * 获取进程ID
+     */
+    private String getProcessId(Process process) {
+        try {
+            if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
+                Field pidField = process.getClass().getDeclaredField("pid");
+                pidField.setAccessible(true);
+                return String.valueOf(pidField.get(process));
+            } else {
+                // 对于Windows系统或其他Process实现
+                return String.valueOf(process.hashCode());
+            }
+        } catch (Exception e) {
+            // 如果获取失败,使用进程的hashCode作为备选方案
+            return String.valueOf(process.hashCode());
+        }
+    }
+
+    /**
+     * 停止进程
+     */
+    public boolean stopProcess(String processId) {
+        Process process = processMap.get(processId);
+        if (process != null && process.isAlive()) {
+            process.destroy();
+            processMap.remove(processId);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 检查进程是否存活
+     */
+    public boolean isProcessAlive(String processId) {
+        Process process = processMap.get(processId);
+        return process != null && process.isAlive();
+    }
+}

+ 25 - 0
fs-service/src/main/java/com/fs/live/vo/LiveGoodsListVo.java

@@ -0,0 +1,25 @@
+package com.fs.live.vo;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class LiveGoodsListVo {
+    List<Long> goodsIds;
+    Integer status;
+    /**
+     * 企业ID
+     */
+    private Long companyId;
+
+    /**
+     * 企业用户ID
+     */
+    private Long companyUserId;
+}

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

@@ -14,5 +14,6 @@ public class LiveGoodsVo {
     private String productName;
     private BigDecimal price;
     private Integer stock;
+    private Integer status;
     private Integer sales;
 }

+ 21 - 0
fs-service/src/main/java/com/fs/live/vo/LiveListVo.java

@@ -0,0 +1,21 @@
+package com.fs.live.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class LiveListVo {
+    List<Long> liveIds;
+    Integer isShow;
+    /**
+     * 企业ID
+     */
+    private Long companyId;
+
+    /**
+     * 企业用户ID
+     */
+    private Long companyUserId;
+
+}

+ 16 - 1
fs-service/src/main/resources/mapper/live/LiveGoodsMapper.xml

@@ -159,7 +159,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectProductListByLiveId" parameterType="LiveGoods" resultType="com.fs.live.vo.LiveGoodsVo">
 
-        select lg.goods_id,sp.img_url,sp.product_name,sp.price,sp.stock,sp.sales from live_goods lg
+        select lg.goods_id,sp.img_url,sp.product_name,sp.price,sp.stock,sp.sales,lg.status from live_goods lg
         INNER JOIN fs_store_product sp
         ON lg.store_id = sp.store_id AND lg.product_id = sp.product_id
 
@@ -178,4 +178,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
     </select>
 
+    <update id="updateBatchList" parameterType="com.fs.live.vo.LiveGoodsListVo">
+        update live_goods set status = #{listVo.status} where company_id = #{listVo.companyId} and company_user_id = #{listVo.companyUserId} and goods_id in
+        <foreach item="goodsId" collection="listVo.goodsIds" open="(" separator="," close=")">
+            #{goodsId}
+        </foreach>
+    </update>
+
+    <delete id="deleteBatchList" parameterType="com.fs.live.vo.LiveGoodsListVo">
+        delete from live_goods
+        WHERE company_id = #{listVo.companyId} and company_user_id = #{listVo.companyUserId} and goods_id IN
+        <foreach item="goodsId" collection="listVo.goodsIds" open="(" separator="," close=")">
+            #{goodsId}
+        </foreach>
+    </delete>
+
 </mapper>

+ 34 - 21
fs-service/src/main/resources/mapper/live/LiveMapper.xml

@@ -38,27 +38,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectLiveList" parameterType="Live" resultMap="LiveResult">
         <include refid="selectLiveVo"/>
-        <where>
-            <if test="companyId != null "> and company_id = #{companyId}</if>
-            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
-            <if test="talentId != null "> and talent_id = #{talentId}</if>
-            <if test="liveName != null  and liveName != ''"> and live_name like concat('%', #{liveName}, '%')</if>
-            <if test="liveDesc != null  and liveDesc != ''"> and live_desc = #{liveDesc}</if>
-            <if test="showType != null "> and show_type = #{showType}</if>
-            <if test="status != null "> and status = #{status}</if>
-            <if test="anchorId != null "> and anchor_id = #{anchorId}</if>
-            <if test="liveType != null "> and live_type = #{liveType}</if>
-            <if test="startTime != null "> and start_time = #{startTime}</if>
-            <if test="finishTime != null "> and finish_time = #{finishTime}</if>
-            <if test="liveImgUrl != null  and liveImgUrl != ''"> and live_img_url = #{liveImgUrl}</if>
-            <if test="liveConfig != null  and liveConfig != ''"> and live_config = #{liveConfig}</if>
-            <if test="isShow != null "> and is_show = #{isShow}</if>
-            <if test="isDel != null "> and is_del = #{isDel}</if>
-            <if test="qwQrCode != null  and qwQrCode != ''"> and qw_qr_code = #{qwQrCode}</if>
-            <if test="rtmpUrl != null  and rtmpUrl != ''"> and rtmp_url = #{rtmpUrl}</if>
-            <if test="flvHlsUrl != null  and flvHlsUrl != ''"> and flv_hls_url = #{flvHlsUrl}</if>
-            <if test="isAudit != null  and isAudit != ''"> and is_audit = #{isAudit}</if>
-        </where>
+        where 1=1 and is_del = 0
+        <if test="companyId != null "> and company_id = #{companyId}</if>
+        <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+        <if test="talentId != null "> and talent_id = #{talentId}</if>
+        <if test="liveName != null  and liveName != ''"> and live_name like concat('%', #{liveName}, '%')</if>
+        <if test="liveDesc != null  and liveDesc != ''"> and live_desc = #{liveDesc}</if>
+        <if test="showType != null "> and show_type = #{showType}</if>
+        <if test="status != null "> and status = #{status}</if>
+        <if test="anchorId != null "> and anchor_id = #{anchorId}</if>
+        <if test="liveType != null "> and live_type = #{liveType}</if>
+        <if test="startTime != null "> and start_time = #{startTime}</if>
+        <if test="finishTime != null "> and finish_time = #{finishTime}</if>
+        <if test="liveImgUrl != null  and liveImgUrl != ''"> and live_img_url = #{liveImgUrl}</if>
+        <if test="liveConfig != null  and liveConfig != ''"> and live_config = #{liveConfig}</if>
+        <if test="isShow != null "> and is_show = #{isShow}</if>
+        <if test="qwQrCode != null  and qwQrCode != ''"> and qw_qr_code = #{qwQrCode}</if>
+        <if test="rtmpUrl != null  and rtmpUrl != ''"> and rtmp_url = #{rtmpUrl}</if>
+        <if test="flvHlsUrl != null  and flvHlsUrl != ''"> and flv_hls_url = #{flvHlsUrl}</if>
+        <if test="isAudit != null  and isAudit != ''"> and is_audit = #{isAudit}</if>
     </select>
 
     <select id="selectLiveByLiveId" parameterType="Long" resultMap="LiveResult">
@@ -183,4 +181,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{liveId}
         </foreach>
     </delete>
+
+    <update id="updateBatchLiveList" parameterType="com.fs.live.vo.LiveListVo">
+        update live set is_show = #{liveVo.isShow} where company_id = #{liveVo.companyId} and company_user_id = #{liveVo.companyUserId} and live_id in
+        <foreach item="liveId" collection="liveVo.liveIds" open="(" separator="," close=")">
+            #{liveId}
+        </foreach>
+    </update>
+
+    <update id="deleteBatchLiveList" parameterType="com.fs.live.vo.LiveListVo">
+        update live set is_del = 1
+        WHERE company_id = #{liveVo.companyId} and company_user_id = #{liveVo.companyUserId} and live_id IN
+        <foreach item="liveId" collection="liveVo.liveIds" open="(" separator="," close=")">
+            #{liveId}
+        </foreach>
+    </update>
 </mapper>

+ 6 - 5
fs-service/src/main/resources/mapper/live/LiveMsgMapper.xml

@@ -3,7 +3,7 @@
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.live.mapper.LiveMsgMapper">
-    
+
     <resultMap type="LiveMsg" id="LiveMsgResult">
         <result property="msgId"    column="msg_id"    />
         <result property="liveId"    column="live_id"    />
@@ -22,13 +22,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectLiveMsgList" parameterType="LiveMsg" resultMap="LiveMsgResult">
         <include refid="selectLiveMsgVo"/>
-        <where>  
+        <where>
             <if test="liveId != null "> and live_id = #{liveId}</if>
             <if test="userId != null "> and user_id = #{userId}</if>
             <if test="msg != null  and msg != ''"> and msg = #{msg}</if>
         </where>
+        order by create_time desc
     </select>
-    
+
     <select id="selectLiveMsgByMsgId" parameterType="Long" resultMap="LiveMsgResult">
         <include refid="selectLiveMsgVo"/>
         where msg_id = #{msgId}
@@ -83,9 +84,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </delete>
 
     <delete id="deleteLiveMsgByMsgIds" parameterType="String">
-        delete from live_msg where msg_id in 
+        delete from live_msg where msg_id in
         <foreach item="msgId" collection="array" open="(" separator="," close=")">
             #{msgId}
         </foreach>
     </delete>
-</mapper>
+</mapper>