Browse Source

直播间主播网站创建,直播间身份认证,srs服务器创建链接,直播推流校验

yuhongqi 2 ngày trước cách đây
mục cha
commit
d927ae1743
19 tập tin đã thay đổi với 1071 bổ sung51 xóa
  1. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveCartController.java
  2. 42 5
      fs-company/src/main/java/com/fs/company/controller/live/LiveController.java
  3. 162 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java
  4. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderItemController.java
  5. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderLogsController.java
  6. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserFavoriteController.java
  7. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserFollowController.java
  8. 97 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveUserLikeController.java
  9. 88 14
      fs-live-app/src/main/java/com/fs/app/controller/LiveController.java
  10. 1 1
      fs-live-app/src/main/java/com/fs/app/controller/UserController.java
  11. 2 1
      fs-live-app/src/main/java/com/fs/framework/config/SecurityConfig.java
  12. 4 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserTalentMapper.java
  13. 3 0
      fs-service/src/main/java/com/fs/course/service/IFsUserTalentService.java
  14. 5 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserTalentServiceImpl.java
  15. 1 0
      fs-service/src/main/java/com/fs/live/domain/Live.java
  16. 4 0
      fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java
  17. 32 2
      fs-service/src/main/java/com/fs/live/service/ILiveService.java
  18. 143 27
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  19. 2 1
      fs-service/src/main/resources/mapper/live/LiveMapper.xml

+ 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.selectLiveCartByCardId(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.deleteLiveCartByCardIds(cardIds));
+    }
+}

+ 42 - 5
fs-company/src/main/java/com/fs/company/controller/live/LiveController.java

@@ -1,20 +1,31 @@
 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.utils.ServletUtils;
 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.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;
 
@@ -30,6 +41,8 @@ public class LiveController extends BaseController
 {
     @Autowired
     private ILiveService liveService;
+    @Autowired
+    private TokenService tokenService;
 
     /**
      * 查询直播列表
@@ -128,12 +141,36 @@ public class LiveController extends BaseController
 
     @GetMapping("/living/{liveId}")
     public R getRoom(@PathVariable String liveId) {
-        Map<String, Object> resultMap = liveService.getLiveRoom(liveId);
-        if ("200".equals(resultMap.get("code"))) {
-            return R.ok().put("livingUrl", resultMap.get("livingUrl"));
-        } else {
-            return R.error((String) resultMap.get("msg"));
+        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);
     }
 
     /**

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

@@ -0,0 +1,162 @@
+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.his.dto.ExpressInfoDTO;
+import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.service.IFsExpressService;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.enums.LiveOrderCancleReason;
+import com.fs.live.service.ILiveOrderService;
+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;
+
+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;
+
+    /**
+     * 查询订单列表
+     */
+    @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);
+    }
+
+
+}

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

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

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

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

@@ -1,10 +1,15 @@
 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.core.domain.BaseEntity;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
@@ -17,15 +22,21 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import lombok.AllArgsConstructor;
+import org.apache.http.HttpRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+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.Map;
+import java.util.*;
 
 
 @Api("直播信息接口")
@@ -34,9 +45,13 @@ import java.util.Map;
 @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;
+
 	@ApiOperation("直播封面信息")
 	@GetMapping("/liveInfo")
 	@ApiResponse(code = 200, message = "", response = LiveInfoVo.class)
@@ -98,22 +113,81 @@ public class LiveController extends AppBaseController {
 			return R.error("直播间id缺失");
 		}
 		Long liveId = Long.valueOf(payload.get("liveId").toString());
-		Map<String, Object> resultMap = liveService.createLiveRoom(liveId);
-		if ("200".equals(resultMap.get("code"))) {
-			return R.ok();
-		} else {
-			return R.error(resultMap.get("msg").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) {
-		Map<String, Object> resultMap = liveService.getLiveRoom(liveId);
-		if ("200".equals(resultMap.get("code"))) {
-			return R.ok(resultMap);
-		} else {
-			return R.error((String) resultMap.get("msg"));
+		return liveService.getLiveRoom(liveId);
+	}
+
+
+	@PostMapping("/checkLiving")
+	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;
+	}
 }

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

@@ -191,7 +191,7 @@ public class UserController extends AppBaseController {
 		int loginType = param.getLoginType();
 		switch (loginType) {
 			case 1:
-				return handleLoginType1(param);
+				return handleLoginType1(param); // 手机密码登录
 			case 3:
 				return handleLoginType3(param);
 			default:

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

@@ -9,7 +9,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
 
 /**
  * spring security配置
- * 
+ *
 
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@@ -36,6 +36,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
     {
         http.authorizeRequests()
                 .antMatchers("/**").permitAll()
+                .antMatchers("/app/live/checkLiving").permitAll()
                 .anyRequest().authenticated()
                 .and().csrf().disable();
     }

+ 4 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserTalentMapper.java

@@ -2,6 +2,7 @@ package com.fs.course.mapper;
 
 import java.util.List;
 import com.fs.course.domain.FsUserTalent;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
@@ -70,4 +71,7 @@ public interface FsUserTalentMapper
 
     @Select("select nick_name,talent_id from fs_user_talent where company_id=#{companyId}")
     List<FsUserTalent> selectCompanyTalent(String companyId);
+
+    @Select("select * from fs_user_talent where user_id=#{userId}")
+    FsUserTalent selectTalentByUserId(@Param("userId") String userId);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/course/service/IFsUserTalentService.java

@@ -68,4 +68,7 @@ public interface IFsUserTalentService
      * @return 达人
      */
     List<FsUserTalent> selectCompanyTalent(String companyId);
+
+
+    FsUserTalent selectTalentByUserId(String userId);
 }

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

@@ -108,4 +108,9 @@ public class FsUserTalentServiceImpl implements IFsUserTalentService
     public List<FsUserTalent> selectCompanyTalent(String companyId) {
         return fsUserTalentMapper.selectCompanyTalent(companyId);
     }
+
+    @Override
+    public FsUserTalent selectTalentByUserId(String userId) {
+        return fsUserTalentMapper.selectTalentByUserId(userId);
+    }
 }

+ 1 - 0
fs-service/src/main/java/com/fs/live/domain/Live.java

@@ -98,6 +98,7 @@ public class Live extends BaseEntity {
     @Excel(name = "直播地址")
     private String rtmpUrl;
     private String flvHlsUrl;
+    private String idCardUrl;
 
     @TableField(exist = false)
     private String videoUrl;

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

@@ -77,4 +77,8 @@ public interface LiveMapper extends BaseMapper<Live>
 
     @Select("select * from live where status = 2 and is_show=1 and is_del != 1")
     List<Live> liveList();
+
+    @Select("select * from live where talent_id=#{talentId}")
+    Live selectLiveByTalentId(@Param("talentId") String talentId);
+
 }

+ 32 - 2
fs-service/src/main/java/com/fs/live/service/ILiveService.java

@@ -1,6 +1,7 @@
 package com.fs.live.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
 import com.fs.live.domain.Live;
 
 import java.util.List;
@@ -84,8 +85,37 @@ public interface ILiveService extends IService<Live>
      * @return
      */
     List<Live> liveList();
+    /**
+     * 创建直播 获取直播地址
+     * @param liveId
+     * @return
+     */
+    R createLiveRoom(Long liveId);
+    /**
+     * 获取直播地址
+     * @param streamKey
+     * @return
+     */
+    R getLiveRoom(String streamKey);
+    /**
+     * 检测直播 相关权限和配置
+     * @param payload
+     * @return
+     */
+    R checkLiving(Map<String, String> payload);
+
+    /**
+     * 结束直播
+     * @param payload
+     * @return
+     */
+    R closeLiving(Map<String, String> payload);
 
-    Map<String, Object> createLiveRoom(Long liveId);
+    /**
+     * 验证身份证信息
+     * @param payload
+     * @return
+     */
+    R verifyIdInfo(Map<String, String> payload);
 
-    Map<String, Object> getLiveRoom(String streamKey);
 }

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

@@ -1,11 +1,14 @@
 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.common.core.domain.R;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.course.domain.FsUserTalent;
+import com.fs.course.service.IFsUserTalentService;
 import com.fs.live.domain.Live;
 import com.fs.live.domain.LiveData;
 import com.fs.live.domain.LiveVideo;
@@ -15,15 +18,19 @@ import com.fs.live.service.ILiveService;
 import com.fs.live.service.ILiveVideoService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
-import com.qcloud.cos.utils.Md5Utils;
 import lombok.AllArgsConstructor;
+import okhttp3.FormBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import com.fs.aicall.utils.Md5Utils;
+import org.springframework.util.Base64Utils;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.*;
 
 /**
  * 直播Service业务层处理
@@ -42,6 +49,9 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
     @Autowired
     private ISysConfigService sysConfigService;
 
+    @Autowired
+    private IFsUserTalentService fsUserTalentService;
+
     /**
      * 查询直播
      *
@@ -112,10 +122,17 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
      */
     @Override
     public int insertLive(Live live){
+
+
+        Live exist = liveMapper.selectLiveByTalentId(String.valueOf(live.getTalentId()));
+        if (exist != null) {
+            return 0;
+        }
         if(live.getLiveType() == 2 && StringUtils.isEmpty(live.getVideoUrl())) {
             throw new BaseException("录播必须上传视屏");
         }
         live.setCreateTime(DateUtils.getNowDate());
+        live.setStatus(1);
         boolean save = save(live);
         LiveVideo liveVideo = new LiveVideo();
         liveVideo.setLiveId(live.getLiveId());
@@ -179,50 +196,149 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
     }
 
     @Override
-    public Map<String, Object> createLiveRoom(Long liveId) {
-        Map<String, Object> resultMap = new HashMap<>();
+    public R createLiveRoom(Long liveId) {
         Live live = this.selectLiveByLiveId(liveId);
-        if (live == null || live.getStatus() != 1 || live.getIsShow() != 1 || live.getIsAudit() != 1) {
-            resultMap.put("code", "500");
-            resultMap.put("msg", "您未拥有直播权限");
-            return resultMap;
+        if (live == null) {
+            return R.error("直播不存在");
+        }
+
+        if(live.getStatus() == 2){
+            return R.ok().put("rtmpUrl", live.getRtmpUrl());
+        }
+
+        if (live.getStatus() != 1 || live.getIsShow() != 1 || live.getIsAudit() != 1) {
+            return R.error("您未拥有直播权限");
         }
         SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("living.config");
         Map<String, String> livingConfigMap = JSON.parseObject(sysConfig.getConfigValue(), Map.class);
         if (livingConfigMap == null || livingConfigMap.isEmpty()) {
-            resultMap.put("code", "500");
-            resultMap.put("msg", "缺失直播配置");
-            return Collections.emptyMap();
+            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());
         live.setRtmpUrl(rtmpPushUrl);
         live.setFlvHlsUrl(flvPlayUrl);
+        live.setStartTime(LocalDateTime.now());
+        live.setStatus(2);
+        live.setLiveType(1);
         this.updateLive(live);
-        resultMap.put("code", "200");
-        return resultMap;
+        return R.ok().put("rtmpUrl", rtmpPushUrl);
     }
 
     @Override
-    public Map<String, Object> getLiveRoom(String liveId) {
-        Map<String, Object> resultMap = new HashMap<>();
+    public R getLiveRoom(String liveId) {
         Live live = this.selectLiveByLiveId(Long.valueOf(liveId));
         if (live == null) {
-            resultMap.put("code", "500");
-            resultMap.put("msg", "未查询到直播间");
-            return resultMap;
+            return R.error("未查询到直播间");
+        }
+        return R.ok().put("livingUrl", live.getFlvHlsUrl()).put("liveStatus", live.getStatus());
+    }
+
+    @Override
+    public R checkLiving(Map<String, String> payload) {
+        if (payload == null || payload.isEmpty() || !payload.containsKey("userId") || !payload.containsKey("companyId")) {
+            return R.error("系统错误,请联系管理员");
+        }
+        // todo 后面修改
+        FsUserTalent fsUserTalent = fsUserTalentService.selectTalentByUserId(payload.get("userId"));
+//        if (fsUserTalent == null) {
+//            return R.error("您还未成为达人,无法开启直播!");
+//        }
+//        Live live = liveMapper.selectLiveByUserIdAndCompanyId(String.valueOf(fsUserTalent.getTalentId()), payload.get("companyId"));
+        Live live = liveMapper.selectLiveByTalentId("42");
+        if (live == null) {
+            return R.error("您未拥有直播权限!");
+        }
+        if (live.getIsAudit() == 0) {
+            return R.error("直播间审核中!");
+        }
+
+
+        return R.ok().put("data", live);
+    }
+
+    @Override
+    public R closeLiving(Map<String, String> payload) {
+        if (!payload.containsKey("liveId")) {
+            return R.error("直播间id缺失");
+        }
+        if (!payload.containsKey("userId")) {
+            return R.error("关闭直播异常,请联系管理员!");
+        }
+        FsUserTalent fsUserTalent = fsUserTalentService.selectTalentByUserId(payload.get("userId"));
+        // todo  后面修改先写死
+        Live live = liveMapper.selectLiveByTalentId("42");
+        live.setStatus(1);
+        live.setFinishTime(LocalDateTime.now());
+        live.setLiveType(2);
+        liveMapper.updateLive(live);
+        return R.ok();
+    }
+
+    /**
+     * 身份证信息验证 阿里商品购买接口
+     * @param payload
+     * @return
+     */
+    @Override
+    public R verifyIdInfo(Map<String, String> payload) {
+        if (!payload.containsKey("idCardUrl")) {
+            return R.error("身份证信息缺失");
+        }
+        Live live = liveMapper.selectLiveByLiveId(Long.valueOf(payload.get("liveId")));
+        if (live == null) {
+            return R.error("直播间不存在");
         }
-        resultMap.put("code", "200");
-        resultMap.put("livingUrl", live.getFlvHlsUrl());
-        return resultMap;
+        String url = "https://puhui.shumaidata.com/idcard-ocr/photo/puhui";
+        // todo 买的产品 appcode 个人  需要更换为公司的
+        String appCode = "ed8f0f22564b48c5abdb18a02c1d701c";
+        try {
+            Map<String, String> params = new HashMap<>();
+            //image 和 url 二选一 ,选择其中一个时,请注释另外一个参数,默认使用image
+            params.put("url", payload.get("idCardUrl"));
+//            params.put("image", "data:image/jpeg;base64," + base64String);
+            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();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.error("身份证信息校验异常");
+        }
+        return R.error("身份证信息校验失败");
     }
 
+    /** 上面方法的数据解析
+     * 用到的HTTP工具包:okhttp 3.13.1
+     * <dependency>
+     * <groupId>com.squareup.okhttp3</groupId>
+     * <artifactId>okhttp</artifactId>
+     * <version>3.13.1</version>
+     * </dependency>
+     */
+    public static String postForm(String appCode, String url, Map<String, String> params) throws IOException {
+        OkHttpClient client = new OkHttpClient.Builder().build();
+        FormBody.Builder formbuilder = new FormBody.Builder();
+        Iterator<String> it = params.keySet().iterator();
+        while (it.hasNext()) {
+            String key = it.next();
+            formbuilder.add(key, params.get(key));
+        }
+        FormBody body = formbuilder.build();
+        Request request = new Request.Builder().url(url).addHeader("Authorization", "APPCODE " + appCode).post(body).build();
+        Response response = client.newCall(request).execute();
+        return response.body().string();
+    }
 
 
     public static String generateRtmpPushUrl(String domain, String app, String liveId) {
         long timestamp = System.currentTimeMillis() / 1000; // 秒级时间戳
         String SECRET_KEY = liveId + timestamp;
-        String sign = Md5Utils.md5Hex(liveId + SECRET_KEY + 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);
     }
 
@@ -232,7 +348,7 @@ public class LiveServiceImpl extends ServiceImpl<LiveMapper, Live> implements IL
     public static String generateFlvPlayUrl(String domain, String app, String liveId) {
         long timestamp = System.currentTimeMillis() / 1000;
         String SECRET_KEY = liveId + timestamp;
-        String sign = Md5Utils.md5Hex(liveId + SECRET_KEY + timestamp);
-        return String.format("http://%s/%s/%s.flv?timestamp=%d&sign=%s", domain, app, liveId, timestamp, sign);
+        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);
     }
 }

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

@@ -33,7 +33,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectLiveVo">
-        select live_id, company_id, company_user_id,talent_id, live_name, is_audit, live_desc, show_type, status, anchor_id, live_type, start_time, finish_time, live_img_url, live_config, is_show, is_del, qw_qr_code, rtmp_url, flv_hls_url, create_time, create_by, update_by, update_time, remark,config_json from live
+        select live_id, company_id, company_user_id,talent_id, live_name, is_audit, live_desc, show_type, status, anchor_id, live_type, start_time, finish_time, live_img_url, live_config, id_card_url, is_show, is_del, qw_qr_code, rtmp_url, flv_hls_url, create_time, create_by, update_by, update_time, remark,config_json from live
     </sql>
 
     <select id="selectLiveList" parameterType="Live" resultMap="LiveResult">
@@ -168,6 +168,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="configJson != null">config_json = #{configJson},</if>
             <if test="flvHlsUrl != null">flv_hls_url = #{flvHlsUrl},</if>
             <if test="isAudit != null">is_audit = #{isAudit},</if>
+            <if test="idCardUrl != null">id_card_url = #{idCardUrl},</if>
         </trim>
         where live_id = #{liveId}
     </update>