Преглед изворни кода

Merge branch 'saas-api' of http://1.14.104.71:10880/txl/ylrz_saas_his_scrm into saas-api

云联一号 пре 1 недеља
родитељ
комит
991f4c5e08
36 измењених фајлова са 1112 додато и 376 уклоњено
  1. 0 2
      fs-ad-api/src/main/java/com/fs/app/controller/CommonController.java
  2. 2 2
      fs-admin-saas/src/main/java/com/fs/FSAdminSaasApplication.java
  3. 1 1
      fs-admin-saas/src/main/java/com/fs/FSServletInitializer.java
  4. 9 6
      fs-admin-saas/src/main/java/com/fs/admin/controller/AdminVideoResourceController.java
  5. 10 10
      fs-admin-saas/src/main/java/com/fs/web/controller/common/CaptchaController.java
  6. 1 1
      fs-admin-saas/src/main/java/com/fs/web/controller/system/SysLoginController.java
  7. 0 43
      fs-admin/src/main/java/com/fs/admin/controller/AdminLiveVideoController.java
  8. 0 119
      fs-admin/src/main/java/com/fs/admin/controller/LiveAdminController.java
  9. 0 140
      fs-admin/src/main/java/com/fs/admin/controller/ProductAdminController.java
  10. 1 17
      fs-admin/src/main/java/com/fs/admin/controller/audit/AdminCompanyBridgeController.java
  11. 28 0
      fs-admin/src/main/java/com/fs/admin/controller/audit/AdminLiveVideoController.java
  12. 7 15
      fs-admin/src/main/java/com/fs/admin/controller/audit/AdminVideoResourceController.java
  13. 56 0
      fs-admin/src/main/java/com/fs/admin/controller/audit/AdminVoiceRoboticController.java
  14. 106 0
      fs-admin/src/main/java/com/fs/admin/controller/audit/LiveAdminController.java
  15. 113 0
      fs-admin/src/main/java/com/fs/admin/controller/audit/ProductAdminController.java
  16. 17 20
      fs-framework/src/main/java/com/fs/framework/web/service/SysLoginService.java
  17. 14 0
      fs-service/src/main/java/com/fs/admin/mapper/AdminLiveMapper.java
  18. 11 0
      fs-service/src/main/java/com/fs/admin/mapper/AdminLiveVideoMapper.java
  19. 19 0
      fs-service/src/main/java/com/fs/admin/mapper/AdminProductMapper.java
  20. 13 0
      fs-service/src/main/java/com/fs/admin/mapper/AdminVideoResourceMapper.java
  21. 13 0
      fs-service/src/main/java/com/fs/admin/service/IAdminLiveService.java
  22. 9 0
      fs-service/src/main/java/com/fs/admin/service/IAdminLiveVideoService.java
  23. 19 0
      fs-service/src/main/java/com/fs/admin/service/IAdminProductService.java
  24. 10 0
      fs-service/src/main/java/com/fs/admin/service/IAdminVideoResourceService.java
  25. 64 0
      fs-service/src/main/java/com/fs/admin/service/impl/AdminLiveServiceImpl.java
  26. 39 0
      fs-service/src/main/java/com/fs/admin/service/impl/AdminLiveVideoServiceImpl.java
  27. 76 0
      fs-service/src/main/java/com/fs/admin/service/impl/AdminProductServiceImpl.java
  28. 21 0
      fs-service/src/main/java/com/fs/admin/service/impl/AdminVideoResourceServiceImpl.java
  29. 35 0
      fs-service/src/main/java/com/fs/admin/vo/AdminLiveVO.java
  30. 21 0
      fs-service/src/main/java/com/fs/admin/vo/AdminLiveVideoVO.java
  31. 84 0
      fs-service/src/main/java/com/fs/admin/vo/AdminProductVO.java
  32. 29 0
      fs-service/src/main/java/com/fs/admin/vo/AdminVideoResourceVO.java
  33. 63 0
      fs-service/src/main/resources/mapper/admin/AdminLiveMapper.xml
  34. 37 0
      fs-service/src/main/resources/mapper/admin/AdminLiveVideoMapper.xml
  35. 141 0
      fs-service/src/main/resources/mapper/admin/AdminProductMapper.xml
  36. 43 0
      fs-service/src/main/resources/mapper/admin/AdminVideoResourceMapper.xml

+ 0 - 2
fs-ad-api/src/main/java/com/fs/app/controller/CommonController.java

@@ -7,7 +7,6 @@ import com.fs.ad.service.IAdHtmlClickLogService;
 import com.fs.common.core.domain.R;
 import com.fs.qw.vo.AdUploadVo;
 import io.swagger.annotations.Api;
-import jdk.nashorn.internal.ir.annotations.Ignore;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
@@ -20,7 +19,6 @@ import org.springframework.web.bind.annotation.RestController;
 @Api("公共接口")
 @RestController
 @AllArgsConstructor
-@Ignore
 @RequestMapping(value="/app/common")
 public class CommonController {
     private IAdHtmlClickLogService adHtmlClickLogService;

+ 2 - 2
fs-admin-saas/src/main/java/com/fs/FSApplication.java → fs-admin-saas/src/main/java/com/fs/FSAdminSaasApplication.java

@@ -31,10 +31,10 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional
 @EnableAsync
 @EnableScheduling
-public class FSApplication {
+public class FSAdminSaasApplication {
     public static void main(String[] args) {
         // System.setProperty("spring.devtools.restart.enabled", "false");
-        SpringApplication.run(FSApplication.class, args);
+        SpringApplication.run(FSAdminSaasApplication.class, args);
         System.out.println("admin启动成功");
     }
 }

+ 1 - 1
fs-admin-saas/src/main/java/com/fs/FSServletInitializer.java

@@ -9,6 +9,6 @@ public class FSServletInitializer extends SpringBootServletInitializer
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
     {
-        return application.sources(FSApplication.class);
+        return application.sources(FSAdminSaasApplication.class);
     }
 }

+ 9 - 6
fs-admin-saas/src/main/java/com/fs/admin/controller/AdminVideoResourceController.java

@@ -30,16 +30,19 @@ public class AdminVideoResourceController extends BaseController {
     public TableDataInfo list(@RequestParam(required = false) Long companyId,
                               @RequestParam(required = false) String companyName,
                               @RequestParam(required = false) String videoName) {
-        String sql = "SELECT id, title as videoName, video_type as videoType, " +
-                "play_url as playUrl, duration, status, create_time as createTime " +
+        String sql = "SELECT video_id AS id, title AS videoName, upload_type AS videoType, " +
+                "video_url AS playUrl, duration, status, create_time AS createTime " +
                 "FROM fs_user_course_video WHERE 1=1";
-        StringBuilder sb = new StringBuilder(sql);
+        StringBuilder sqlBuilder = new StringBuilder(sql);
+        List<Object> params = new ArrayList<>();
         if (videoName != null && !videoName.isEmpty()) {
-            sb.append(" AND title LIKE '%").append(videoName.replace("'", "''")).append("%'");
+            sqlBuilder.append(" AND title LIKE ?");
+            params.add("%" + videoName + "%");
         }
-        sb.append(" ORDER BY create_time DESC");
+        sqlBuilder.append(" ORDER BY create_time DESC");
 
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(companyId, companyName, sb.toString());
+        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
+                companyId, companyName, sqlBuilder.toString(), params.toArray());
         return getDataTable(allList);
     }
 }

+ 10 - 10
fs-admin-saas/src/main/java/com/fs/web/controller/common/CaptchaController.java

@@ -22,10 +22,10 @@ import org.springframework.context.annotation.Profile;
 
 /**
  * 验证码操作处理
- * 
+ *
 
  */
-@Profile("admin")
+//@Profile("admin")
 @RestController
 public class CaptchaController
 {
@@ -37,11 +37,11 @@ public class CaptchaController
 
     @Autowired
     private RedisCache redisCache;
-    
+
     // 验证码类型
     @Value("${fs.captchaType}")
     private String captchaType;
-    
+
     @Autowired
     private ISysConfigService configService;
     /**
@@ -51,12 +51,12 @@ public class CaptchaController
     public AjaxResult getCode(HttpServletResponse response) throws IOException
     {
         AjaxResult ajax = AjaxResult.success();
-        boolean captchaOnOff = configService.selectCaptchaOnOff();
-        ajax.put("captchaOnOff", captchaOnOff);
-        if (!captchaOnOff)
-        {
-            return ajax;
-        }
+//        boolean captchaOnOff = configService.selectCaptchaOnOff();
+//        ajax.put("captchaOnOff", captchaOnOff);
+//        if (!captchaOnOff)
+//        {
+//            return ajax;
+//        }
 
         // 保存验证码信息
         String uuid = IdUtils.simpleUUID();

+ 1 - 1
fs-admin-saas/src/main/java/com/fs/web/controller/system/SysLoginController.java

@@ -42,7 +42,7 @@ import com.fs.system.service.IAdminMenuService;
  *
 
  */
-@Profile("admin")
+//@Profile("admin")
 @RestController
 public class SysLoginController
 {

+ 0 - 43
fs-admin/src/main/java/com/fs/admin/controller/AdminLiveVideoController.java

@@ -1,43 +0,0 @@
-package com.fs.admin.controller;
-
-import java.util.*;
-
-import com.fs.admin.helper.AdminCrossTenantHelper;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.page.TableDataInfo;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 总后台直播视频审计控制器
- * 遍历所有租户库查询 live_video_record 数据
- */
-@RestController
-@RequestMapping("/admin/liveVideo")
-public class AdminLiveVideoController extends BaseController {
-
-    @Autowired
-    private AdminCrossTenantHelper crossTenantHelper;
-
-    /**
-     * 查询所有租户的直播视频列表
-     */
-    @PreAuthorize("@ss.hasPermi('admin:liveVideo:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(@RequestParam(required = false) Long companyId,
-                              @RequestParam(required = false) String companyName,
-                              @RequestParam(required = false) String videoTitle) {
-        String sql = "SELECT id, title, live_id as liveId, play_url as playUrl, " +
-                "duration, status, create_time as createTime " +
-                "FROM live_video_record WHERE 1=1";
-        StringBuilder sb = new StringBuilder(sql);
-        if (videoTitle != null && !videoTitle.isEmpty()) {
-            sb.append(" AND title LIKE '%").append(videoTitle.replace("'", "''")).append("%'");
-        }
-        sb.append(" ORDER BY create_time DESC");
-
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(companyId, companyName, sb.toString());
-        return getDataTable(allList);
-    }
-}

+ 0 - 119
fs-admin/src/main/java/com/fs/admin/controller/LiveAdminController.java

@@ -1,119 +0,0 @@
-package com.fs.admin.controller;
-
-import java.util.*;
-
-import com.fs.admin.helper.AdminCrossTenantHelper;
-import com.fs.common.annotation.Excel;
-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 lombok.Data;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 总后台直播内容管理控制器
- * 遍历所有租户库查询 live_video 数据
- */
-@RestController
-@RequestMapping("/admin/live")
-public class LiveAdminController extends BaseController {
-
-    @Autowired
-    private AdminCrossTenantHelper crossTenantHelper;
-
-    private String str(Object o) { return o == null ? "" : o.toString(); }
-
-    @Data
-    public static class LiveExportVO {
-        @Excel(name = "租户名称") private String companyName;
-        @Excel(name = "直播标题") private String title;
-        @Excel(name = "状态") private String liveStatus;
-        @Excel(name = "开始时间") private String startTime;
-        @Excel(name = "结束时间") private String endTime;
-        @Excel(name = "创建时间") private String createTime;
-    }
-
-    @Log(title = "导出直播", businessType = BusinessType.EXPORT)
-    @PreAuthorize("@ss.hasPermi('admin:live:list')")
-    @GetMapping("/export")
-    public AjaxResult export(@RequestParam(required = false) String liveName,
-                             @RequestParam(required = false) Long companyId,
-                             @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) -> {
-                    StringBuilder sql = new StringBuilder(
-                            "SELECT v.video_id, v.title, v.cover_url, v.live_status, " +
-                            "v.start_time, v.end_time, v.create_time " +
-                            "FROM live_video v WHERE 1=1");
-                    List<Object> params = new ArrayList<>();
-                    if (liveName != null && !liveName.isEmpty()) {
-                        sql.append(" AND v.title LIKE ?");
-                        params.add("%" + liveName + "%");
-                    }
-                    sql.append(" ORDER BY v.create_time DESC");
-                    return params.isEmpty()
-                            ? jdbc.queryForList(sql.toString())
-                            : jdbc.queryForList(sql.toString(), params.toArray());
-                });
-        List<LiveExportVO> voList = new ArrayList<>();
-        for (Map<String, Object> m : allList) {
-            LiveExportVO vo = new LiveExportVO();
-            vo.setCompanyName(str(m.get("company_name")));
-            vo.setTitle(str(m.get("title")));
-            vo.setLiveStatus(str(m.get("live_status")));
-            vo.setStartTime(str(m.get("start_time")));
-            vo.setEndTime(str(m.get("end_time")));
-            vo.setCreateTime(str(m.get("create_time")));
-            voList.add(vo);
-        }
-        ExcelUtil<LiveExportVO> util = new ExcelUtil<>(LiveExportVO.class);
-        return util.exportExcel(voList, "直播数据");
-    }
-
-    /**
-     * 查询所有租户的直播列表
-     */
-    @PreAuthorize("@ss.hasPermi('admin:live:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(@RequestParam(required = false) String liveName,
-                              @RequestParam(required = false) Long companyId,
-                              @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) -> {
-                    StringBuilder sql = new StringBuilder(
-                            "SELECT v.video_id, v.title, v.cover_url, v.live_status, " +
-                            "v.start_time, v.end_time, v.create_time " +
-                            "FROM live_video v WHERE 1=1");
-                    List<Object> params = new ArrayList<>();
-                    if (liveName != null && !liveName.isEmpty()) {
-                        sql.append(" AND v.title LIKE ?");
-                        params.add("%" + liveName + "%");
-                    }
-                    sql.append(" ORDER BY v.create_time DESC LIMIT 200");
-                    return params.isEmpty()
-                            ? jdbc.queryForList(sql.toString())
-                            : jdbc.queryForList(sql.toString(), params.toArray());
-                });
-        return getDataTable(allList);
-    }
-
-    /**
-     * 直播统计信息
-     */
-    @PreAuthorize("@ss.hasPermi('admin:live:query')")
-    @GetMapping("/statistics")
-    public AjaxResult statistics(@RequestParam(required = false) Long companyId,
-                                 @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) ->
-                        jdbc.queryForList("SELECT video_id, live_status FROM live_video"));
-        Map<String, Object> result = new HashMap<>();
-        result.put("totalCount", allList.size());
-        return AjaxResult.success(result);
-    }
-}

+ 0 - 140
fs-admin/src/main/java/com/fs/admin/controller/ProductAdminController.java

@@ -1,140 +0,0 @@
-package com.fs.admin.controller;
-
-import java.util.*;
-
-import com.fs.admin.helper.AdminCrossTenantHelper;
-import com.fs.common.annotation.Excel;
-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 lombok.Data;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 总后台商品审核控制器
- * 遍历所有租户库查询 fs_store_product 数据
- */
-@RestController
-@RequestMapping("/admin/product")
-public class ProductAdminController extends BaseController {
-
-    @Autowired
-    private AdminCrossTenantHelper crossTenantHelper;
-
-    private String str(Object o) { return o == null ? "" : o.toString(); }
-
-    @Data
-    public static class ProductExportVO {
-        @Excel(name = "租户名称") private String companyName;
-        @Excel(name = "商品名称") private String productName;
-        @Excel(name = "分类") private String categoryName;
-        @Excel(name = "价格") private String price;
-        @Excel(name = "库存") private String stock;
-        @Excel(name = "状态") private String status;
-        @Excel(name = "创建时间") private String createTime;
-    }
-
-    @Log(title = "导出商品", businessType = BusinessType.EXPORT)
-    @PreAuthorize("@ss.hasPermi('admin:product:list')")
-    @GetMapping("/export")
-    public AjaxResult export(@RequestParam(required = false) String productName,
-                             @RequestParam(required = false) Long companyId,
-                             @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) -> {
-                    StringBuilder sql = new StringBuilder(
-                            "SELECT p.product_id, p.product_name, p.product_image, p.category_name, " +
-                            "p.price, p.stock, p.create_time, p.status " +
-                            "FROM fs_store_product p WHERE 1=1");
-                    List<Object> params = new ArrayList<>();
-                    if (productName != null && !productName.isEmpty()) {
-                        sql.append(" AND p.product_name LIKE ?");
-                        params.add("%" + productName + "%");
-                    }
-                    sql.append(" ORDER BY p.create_time DESC");
-                    return params.isEmpty()
-                            ? jdbc.queryForList(sql.toString())
-                            : jdbc.queryForList(sql.toString(), params.toArray());
-                });
-        List<ProductExportVO> voList = new ArrayList<>();
-        for (Map<String, Object> m : allList) {
-            ProductExportVO vo = new ProductExportVO();
-            vo.setCompanyName(str(m.get("company_name")));
-            vo.setProductName(str(m.get("product_name")));
-            vo.setCategoryName(str(m.get("category_name")));
-            vo.setPrice(str(m.get("price")));
-            vo.setStock(str(m.get("stock")));
-            vo.setStatus(str(m.get("status")));
-            vo.setCreateTime(str(m.get("create_time")));
-            voList.add(vo);
-        }
-        ExcelUtil<ProductExportVO> util = new ExcelUtil<>(ProductExportVO.class);
-        return util.exportExcel(voList, "商品数据");
-    }
-
-    /**
-     * 查询所有租户的商品列表
-     */
-    @PreAuthorize("@ss.hasPermi('admin:product:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(@RequestParam(required = false) String productName,
-                              @RequestParam(required = false) Long companyId,
-                              @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) -> {
-                    StringBuilder sql = new StringBuilder(
-                            "SELECT p.product_id, p.product_name, p.product_image, p.category_name, " +
-                            "p.price, p.stock, p.create_time, p.status " +
-                            "FROM fs_store_product p WHERE 1=1");
-                    List<Object> params = new ArrayList<>();
-                    if (productName != null && !productName.isEmpty()) {
-                        sql.append(" AND p.product_name LIKE ?");
-                        params.add("%" + productName + "%");
-                    }
-                    sql.append(" ORDER BY p.create_time DESC LIMIT 200");
-                    return params.isEmpty()
-                            ? jdbc.queryForList(sql.toString())
-                            : jdbc.queryForList(sql.toString(), params.toArray());
-                });
-        return getDataTable(allList);
-    }
-
-    /**
-     * 查询待审核商品列表
-     */
-    @PreAuthorize("@ss.hasPermi('admin:product:list')")
-    @GetMapping("/pending")
-    public TableDataInfo pendingList(@RequestParam(required = false) Long companyId,
-                                     @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) ->
-                        jdbc.queryForList(
-                                "SELECT p.product_id, p.product_name, p.product_image, p.category_name, " +
-                                "p.price, p.stock, p.create_time, p.status " +
-                                "FROM fs_store_product p WHERE p.status = 0 ORDER BY p.create_time DESC LIMIT 200"));
-        return getDataTable(allList);
-    }
-
-    /**
-     * 商品统计信息
-     */
-    @PreAuthorize("@ss.hasPermi('admin:product:query')")
-    @GetMapping("/statistics")
-    public AjaxResult statistics(@RequestParam(required = false) Long companyId,
-                                 @RequestParam(required = false) String companyName) {
-        List<Map<String, Object>> allList = crossTenantHelper.queryAcrossTenants(
-                companyId, companyName, (tenant, jdbc) ->
-                        jdbc.queryForList("SELECT product_id, status FROM fs_store_product"));
-        Map<String, Object> result = new HashMap<>();
-        result.put("totalCount", allList.size());
-        result.put("pendingCount", allList.stream().filter(r -> "0".equals(String.valueOf(r.get("status")))).count());
-        result.put("onlineCount", allList.stream().filter(r -> "1".equals(String.valueOf(r.get("status")))).count());
-        result.put("rejectedCount", allList.stream().filter(r -> "2".equals(String.valueOf(r.get("status")))).count());
-        return AjaxResult.success(result);
-    }
-}

+ 1 - 17
fs-admin/src/main/java/com/fs/admin/controller/audit/AdminCompanyBridgeController.java

@@ -72,8 +72,7 @@ public class AdminCompanyBridgeController extends BaseController {
 
     @Autowired(required = false)
     private ICompanyVoiceRoboticCallBlacklistService companyVoiceRoboticCallBlacklistService;
-    @Autowired(required = false)
-    private com.fs.company.service.ICompanyVoiceRoboticService companyVoiceRoboticService;
+
     @Autowired(required = false)
     private com.fs.company.service.ICompanyVoiceMobileService companyVoiceMobileService;
     @Autowired(required = false)
@@ -643,21 +642,6 @@ public class AdminCompanyBridgeController extends BaseController {
         return AjaxResult.success(data);
     }
 
-    // ========== [Admin] 外呼任务列表 /admin/voice-robotic ==========
-    @GetMapping("/admin/voice-robotic/list")
-    public TableDataInfo adminVoiceRoboticList(com.fs.company.domain.CompanyVoiceRobotic param) {
-        startPage();
-        List<com.fs.company.domain.CompanyVoiceRobotic> list = companyVoiceRoboticService != null ?
-            companyVoiceRoboticService.selectCompanyVoiceRoboticList(param) : new ArrayList<>();
-        return getDataTable(list);
-    }
-
-    @GetMapping("/admin/voice-robotic/{id}")
-    public AjaxResult adminVoiceRoboticGet(@PathVariable Long id) {
-        if (companyVoiceRoboticService == null) return AjaxResult.error("服务不可用");
-        return AjaxResult.success(companyVoiceRoboticService.selectCompanyVoiceRoboticById(id));
-    }
-
     // ========== [Admin] 号码管理 /admin/voice-number ==========
     @GetMapping("/admin/voice-number/list")
     public TableDataInfo adminVoiceNumberList(com.fs.company.domain.CompanyVoiceMobile param) {

+ 28 - 0
fs-admin/src/main/java/com/fs/admin/controller/audit/AdminLiveVideoController.java

@@ -0,0 +1,28 @@
+package com.fs.admin.controller.audit;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fs.admin.service.IAdminLiveVideoService;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/admin/liveVideo")
+public class AdminLiveVideoController extends BaseController {
+
+    @Autowired
+    private IAdminLiveVideoService adminLiveVideoService;
+
+    @PreAuthorize("@ss.hasPermi('admin:liveVideo:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(@RequestParam(required = false) Long companyId,
+                              @RequestParam(required = false) String companyName,
+                              @RequestParam(required = false) String videoTitle) {
+        List<Map<String, Object>> allList = adminLiveVideoService.selectLiveVideoList(companyId, companyName, videoTitle);
+        return getDataTable(allList);
+    }
+}

+ 7 - 15
fs-admin/src/main/java/com/fs/admin/controller/AdminVideoResourceController.java → fs-admin/src/main/java/com/fs/admin/controller/audit/AdminVideoResourceController.java

@@ -1,24 +1,25 @@
-package com.fs.admin.controller;
+package com.fs.admin.controller.audit;
 
-import java.util.*;
+import java.util.List;
 
+import com.fs.admin.service.IAdminVideoResourceService;
+import com.fs.admin.vo.AdminVideoResourceVO;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.page.TableDataInfo;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 /**
  * 总后台视频资源审计控制器
- * 通过拦截器切库后直接查询当前租户 fs_user_course_video 数据
+ * 通过拦截器切库后查询当前租户 fs_user_course_video 数据
  */
 @RestController
 @RequestMapping("/admin/videoResource")
 public class AdminVideoResourceController extends BaseController {
 
     @Autowired
-    private JdbcTemplate jdbcTemplate;
+    private IAdminVideoResourceService adminVideoResourceService;
 
     /**
      * 查询指定租户的视频资源列表(由 AdminTenantDataSourceInterceptor 切库)
@@ -27,16 +28,7 @@ public class AdminVideoResourceController extends BaseController {
     @GetMapping("/list")
     public TableDataInfo list(@RequestParam(required = false) Long tenantId,
                               @RequestParam(required = false) String videoName) {
-        String sql = "SELECT id, title as videoName, video_type as videoType, " +
-                "play_url as playUrl, duration, status, create_time as createTime " +
-                "FROM fs_user_course_video WHERE 1=1";
-        StringBuilder sb = new StringBuilder(sql);
-        if (videoName != null && !videoName.isEmpty()) {
-            sb.append(" AND title LIKE '%").append(videoName.replace("'", "''")).append("%'");
-        }
-        sb.append(" ORDER BY create_time DESC");
-
-        List<Map<String, Object>> list = jdbcTemplate.queryForList(sb.toString());
+        List<AdminVideoResourceVO> list = adminVideoResourceService.selectVideoResourceList(videoName);
         return getDataTable(list);
     }
 }

+ 56 - 0
fs-admin/src/main/java/com/fs/admin/controller/audit/AdminVoiceRoboticController.java

@@ -0,0 +1,56 @@
+package com.fs.admin.controller.audit;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyVoiceRobotic;
+import com.fs.company.service.ICompanyVoiceRoboticService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @description: 外呼
+ * @author: Xgb
+ * @createDate: 2026/5/27
+ * @version: 1.0
+ */
+@RestController
+@RequestMapping("/admin/voice-robotic")
+public class AdminVoiceRoboticController extends BaseController {
+
+    @Autowired
+    private ICompanyVoiceRoboticService companyVoiceRoboticService;
+
+    // ========== [Admin] 外呼任务列表 /admin/voice-robotic ==========
+    @GetMapping("/list")
+    public TableDataInfo adminVoiceRoboticList(com.fs.company.domain.CompanyVoiceRobotic param) {
+        startPage();
+        List<CompanyVoiceRobotic> list = companyVoiceRoboticService != null ?
+                companyVoiceRoboticService.selectCompanyVoiceRoboticList(param) : new ArrayList<>();
+        return getDataTable(list);
+    }
+
+    @GetMapping("/{id}")
+    public AjaxResult adminVoiceRoboticGet(@PathVariable Long id) {
+        if (companyVoiceRoboticService == null) return AjaxResult.error("服务不可用");
+        return AjaxResult.success(companyVoiceRoboticService.selectCompanyVoiceRoboticById(id));
+    }
+
+    @Log(title = "导出外呼任务", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CompanyVoiceRobotic param) {
+        if (companyVoiceRoboticService == null) return AjaxResult.error("服务不可用");
+        List<CompanyVoiceRobotic> list = companyVoiceRoboticService.selectCompanyVoiceRoboticList(param);
+        ExcelUtil<CompanyVoiceRobotic> util = new ExcelUtil<>(CompanyVoiceRobotic.class);
+        return util.exportExcel(list, "外呼任务数据");
+    }
+}

+ 106 - 0
fs-admin/src/main/java/com/fs/admin/controller/audit/LiveAdminController.java

@@ -0,0 +1,106 @@
+package com.fs.admin.controller.audit;
+
+import java.util.*;
+
+import com.fs.admin.service.IAdminLiveService;
+import com.fs.common.annotation.Excel;
+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 lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/admin/live")
+public class LiveAdminController extends BaseController {
+
+    @Autowired
+    private IAdminLiveService adminLiveService;
+
+    private String str(Object o) { return o == null ? "" : o.toString(); }
+
+    @Data
+    public static class LiveExportVO {
+        @Excel(name = "租户名称") private String companyName;
+        @Excel(name = "直播ID") private String liveId;
+        @Excel(name = "直播标题") private String liveName;
+        @Excel(name = "封面地址") private String coverUrl;
+        @Excel(name = "直播类型") private String liveType;
+        @Excel(name = "直播状态") private String liveStatus;
+        @Excel(name = "开始时间") private String startTime;
+        @Excel(name = "结束时间") private String finishTime;
+        @Excel(name = "创建时间") private String createTime;
+    }
+
+    private String statusText(Integer status) {
+        if (status == null) return "";
+        switch (status) {
+            case 1: return "待支付";
+            case 2: return "直播中";
+            case 3: return "已结束";
+            default: return String.valueOf(status);
+        }
+    }
+
+    @Log(title = "导出直播", businessType = BusinessType.EXPORT)
+    @PreAuthorize("@ss.hasPermi('admin:live:list')")
+    @GetMapping("/export")
+    public AjaxResult export(@RequestParam(required = false) String liveTitle,
+                             @RequestParam(required = false) Long companyId,
+                             @RequestParam(required = false) String companyName,
+                             @RequestParam(required = false) Integer status) {
+        List<Map<String, Object>> allList = adminLiveService.selectLiveListForExport(companyId, companyName, liveTitle, status);
+        List<LiveExportVO> voList = new ArrayList<>();
+        for (Map<String, Object> m : allList) {
+            LiveExportVO vo = new LiveExportVO();
+            vo.setCompanyName(str(m.get("companyName")));
+            vo.setLiveId(str(m.get("liveId")));
+            vo.setLiveName(str(m.get("liveName")));
+            vo.setCoverUrl(str(m.get("coverUrl")));
+            vo.setLiveType("1".equals(str(m.get("liveType"))) ? "直播" : "2".equals(str(m.get("liveType"))) ? "录播" : "");
+            vo.setLiveStatus(statusText((Integer) m.get("status")));
+            vo.setStartTime(str(m.get("startTime")));
+            vo.setFinishTime(str(m.get("finishTime")));
+            vo.setCreateTime(str(m.get("createTime")));
+            voList.add(vo);
+        }
+        ExcelUtil<LiveExportVO> util = new ExcelUtil<>(LiveExportVO.class);
+        return util.exportExcel(voList, "直播数据");
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:live:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(@RequestParam(required = false) String liveTitle,
+                              @RequestParam(required = false) Long companyId,
+                              @RequestParam(required = false) String companyName,
+                              @RequestParam(required = false) Integer status) {
+        List<Map<String, Object>> allList = adminLiveService.selectLiveList(companyId, companyName, liveTitle, status);
+        return getDataTable(allList);
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:live:query')")
+    @GetMapping("/{liveId}")
+    public AjaxResult getInfo(@PathVariable Long liveId) {
+        Map<String, Object> data = adminLiveService.selectLiveById(liveId);
+        if (data == null) return AjaxResult.error("直播不存在");
+        return AjaxResult.success(data);
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:live:query')")
+    @GetMapping("/statistics")
+    public AjaxResult statistics(@RequestParam(required = false) Long companyId,
+                                 @RequestParam(required = false) String companyName,
+                                 @RequestParam(required = false) Integer status) {
+        List<Map<String, Object>> allList = adminLiveService.selectLiveListForExport(companyId, companyName, null, status);
+        Map<String, Object> result = new HashMap<>();
+        result.put("totalCount", allList.size());
+        result.put("livingCount", allList.stream().filter(m -> Integer.valueOf(2).equals(m.get("status"))).count());
+        result.put("endedCount", allList.stream().filter(m -> Integer.valueOf(3).equals(m.get("status"))).count());
+        return AjaxResult.success(result);
+    }
+}

+ 113 - 0
fs-admin/src/main/java/com/fs/admin/controller/audit/ProductAdminController.java

@@ -0,0 +1,113 @@
+package com.fs.admin.controller.audit;
+
+import java.util.*;
+
+import com.fs.admin.service.IAdminProductService;
+import com.fs.common.annotation.Excel;
+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 lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/admin/product")
+public class ProductAdminController extends BaseController {
+
+    @Autowired
+    private IAdminProductService adminProductService;
+
+    private String str(Object o) { return o == null ? "" : o.toString(); }
+
+    @Data
+    public static class ProductExportVO {
+        @Excel(name = "租户名称") private String companyName;
+        @Excel(name = "商品名称") private String productName;
+        @Excel(name = "分类") private String categoryName;
+        @Excel(name = "价格") private String price;
+        @Excel(name = "库存") private String stock;
+        @Excel(name = "状态") private String status;
+        @Excel(name = "创建时间") private String createTime;
+    }
+
+    @Log(title = "导出商品", businessType = BusinessType.EXPORT)
+    @PreAuthorize("@ss.hasPermi('admin:product:list')")
+    @GetMapping("/export")
+    public AjaxResult export(@RequestParam(required = false) String productName,
+                             @RequestParam(required = false) String status) {
+        List<Map<String, Object>> allList = adminProductService.selectProductListForExport(productName, status);
+        List<ProductExportVO> voList = new ArrayList<>();
+        for (Map<String, Object> m : allList) {
+            ProductExportVO vo = new ProductExportVO();
+            vo.setCompanyName(str(m.get("companyName")));
+            vo.setProductName(str(m.get("productName")));
+            vo.setCategoryName(str(m.get("categoryName")));
+            vo.setPrice(str(m.get("price")));
+            vo.setStock(str(m.get("stock")));
+            vo.setStatus(statusText(str(m.get("status"))));
+            vo.setCreateTime(str(m.get("createTime")));
+            voList.add(vo);
+        }
+        ExcelUtil<ProductExportVO> util = new ExcelUtil<>(ProductExportVO.class);
+        return util.exportExcel(voList, "商品数据");
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:product:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(@RequestParam(required = false) String productName,
+                              @RequestParam(required = false) String status) {
+        List<Map<String, Object>> allList = adminProductService.selectProductList(productName, status);
+        return getDataTable(allList);
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:product:list')")
+    @GetMapping("/pending")
+    public TableDataInfo pendingList() {
+        List<Map<String, Object>> allList = adminProductService.selectProductPendingList();
+        return getDataTable(allList);
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:product:query')")
+    @GetMapping("/{productId}")
+    public AjaxResult getInfo(@PathVariable Long productId) {
+        Map<String, Object> data = adminProductService.selectProductById(productId);
+        if (data == null) return AjaxResult.error("商品不存在");
+        return AjaxResult.success(data);
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:product:audit')")
+    @PutMapping("/audit/{productId}")
+    public AjaxResult audit(@PathVariable Long productId,
+                            @RequestParam String status,
+                            @RequestParam(required = false) String auditRemark) {
+        int rows = adminProductService.auditProduct(productId, status);
+        return rows > 0 ? AjaxResult.success("操作成功") : AjaxResult.error("操作失败");
+    }
+
+    @PreAuthorize("@ss.hasPermi('admin:product:query')")
+    @GetMapping("/statistics")
+    public AjaxResult statistics() {
+        List<Map<String, Object>> allList = adminProductService.selectProductListForStatistics();
+        Map<String, Object> result = new HashMap<>();
+        result.put("totalCount", allList.size());
+        result.put("pendingCount", allList.stream().filter(r -> "0".equals(str(r.get("status")))).count());
+        result.put("onlineCount", allList.stream().filter(r -> "1".equals(str(r.get("status")))).count());
+        result.put("rejectedCount", allList.stream().filter(r -> "2".equals(str(r.get("status")))).count());
+        return AjaxResult.success(result);
+    }
+
+    private String statusText(String status) {
+        if (status == null || status.isEmpty()) return "";
+        switch (status) {
+            case "0": return "待审核";
+            case "1": return "审核通过";
+            case "2": return "审核退回";
+            default: return status;
+        }
+    }
+}

+ 17 - 20
fs-framework/src/main/java/com/fs/framework/web/service/SysLoginService.java

@@ -43,7 +43,7 @@ import java.util.concurrent.TimeUnit;
 
 /**
  * 登录校验方法
- * 
+ *
 
  */
 @Component
@@ -57,7 +57,7 @@ public class SysLoginService
 
     @Autowired
     private RedisCache redisCache;
-    
+
     @Autowired
     private ISysUserService userService;
 
@@ -77,7 +77,7 @@ public class SysLoginService
 
     /**
      * 登录验证
-     * 
+     *
      * @param username 用户名
      * @param password 密码
      * @param code 验证码
@@ -154,7 +154,7 @@ public class SysLoginService
 
     /**
      * 校验验证码
-     * 
+     *
      * @param username 用户名
      * @param code 验证码
      * @param uuid 唯一标识
@@ -227,24 +227,21 @@ public class SysLoginService
 
         // 默认使用主库
         DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
-
-        // ===== 只有传了 tenantCode 才走租户逻辑 =====
-        if (StringUtils.isNotBlank(tenantCode))
+        
+        // 查询租户(主库)
+        tenantInfo = userService.getTenantInfo(tenantCode);
+        if (BeanUtil.isEmpty(tenantInfo))
         {
-            // 查询租户(主库)
-            tenantInfo = userService.getTenantInfo(tenantCode);
-            if (BeanUtil.isEmpty(tenantInfo))
-            {
-                throw new ServiceException("企业不存在");
-            }
-            if (!tenantInfo.getStatus().equals(1))
-            {
-                throw new ServiceException("企业已禁用");
-            }
-
-            // 切到租户库
-            tenantDataSourceManager.switchTenant(tenantInfo);
+            throw new ServiceException("企业不存在");
         }
+        if (!tenantInfo.getStatus().equals(1))
+        {
+            throw new ServiceException("企业已禁用");
+        }
+
+        // 切到租户库
+        tenantDataSourceManager.switchTenant(tenantInfo);
+
 
         try
         {

+ 14 - 0
fs-service/src/main/java/com/fs/admin/mapper/AdminLiveMapper.java

@@ -0,0 +1,14 @@
+package com.fs.admin.mapper;
+
+import com.fs.admin.vo.AdminLiveVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface AdminLiveMapper {
+
+    List<AdminLiveVO> selectLiveList(@Param("liveTitle") String liveTitle,
+                                     @Param("status") Integer status);
+
+    AdminLiveVO selectLiveById(@Param("liveId") Long liveId);
+}

+ 11 - 0
fs-service/src/main/java/com/fs/admin/mapper/AdminLiveVideoMapper.java

@@ -0,0 +1,11 @@
+package com.fs.admin.mapper;
+
+import com.fs.admin.vo.AdminLiveVideoVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface AdminLiveVideoMapper {
+
+    List<AdminLiveVideoVO> selectLiveVideoList(@Param("videoTitle") String videoTitle);
+}

+ 19 - 0
fs-service/src/main/java/com/fs/admin/mapper/AdminProductMapper.java

@@ -0,0 +1,19 @@
+package com.fs.admin.mapper;
+
+import com.fs.admin.vo.AdminProductVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface AdminProductMapper {
+
+    List<AdminProductVO> selectProductList(@Param("productName") String productName);
+
+    List<AdminProductVO> selectProductListByStatus(@Param("productName") String productName,
+                                                    @Param("status") String status);
+
+    AdminProductVO selectProductById(@Param("productId") Long productId);
+
+    int updateAuditStatus(@Param("productId") Long productId,
+                          @Param("status") String status);
+}

+ 13 - 0
fs-service/src/main/java/com/fs/admin/mapper/AdminVideoResourceMapper.java

@@ -0,0 +1,13 @@
+package com.fs.admin.mapper;
+
+import com.fs.admin.vo.AdminVideoResourceVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface AdminVideoResourceMapper {
+
+    List<AdminVideoResourceVO> selectVideoResourceList(@Param("videoName") String videoName);
+
+    Long selectVideoResourceCount(@Param("videoName") String videoName);
+}

+ 13 - 0
fs-service/src/main/java/com/fs/admin/service/IAdminLiveService.java

@@ -0,0 +1,13 @@
+package com.fs.admin.service;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IAdminLiveService {
+
+    List<Map<String, Object>> selectLiveList(Long companyId, String companyName, String liveTitle, Integer status);
+
+    List<Map<String, Object>> selectLiveListForExport(Long companyId, String companyName, String liveTitle, Integer status);
+
+    Map<String, Object> selectLiveById(Long liveId);
+}

+ 9 - 0
fs-service/src/main/java/com/fs/admin/service/IAdminLiveVideoService.java

@@ -0,0 +1,9 @@
+package com.fs.admin.service;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IAdminLiveVideoService {
+
+    List<Map<String, Object>> selectLiveVideoList(Long companyId, String companyName, String videoTitle);
+}

+ 19 - 0
fs-service/src/main/java/com/fs/admin/service/IAdminProductService.java

@@ -0,0 +1,19 @@
+package com.fs.admin.service;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IAdminProductService {
+
+    List<Map<String, Object>> selectProductList(String productName, String status);
+
+    List<Map<String, Object>> selectProductListForExport(String productName, String status);
+
+    List<Map<String, Object>> selectProductPendingList();
+
+    List<Map<String, Object>> selectProductListForStatistics();
+
+    Map<String, Object> selectProductById(Long productId);
+
+    int auditProduct(Long productId, String status);
+}

+ 10 - 0
fs-service/src/main/java/com/fs/admin/service/IAdminVideoResourceService.java

@@ -0,0 +1,10 @@
+package com.fs.admin.service;
+
+import com.fs.admin.vo.AdminVideoResourceVO;
+
+import java.util.List;
+
+public interface IAdminVideoResourceService {
+
+    List<AdminVideoResourceVO> selectVideoResourceList(String videoName);
+}

+ 64 - 0
fs-service/src/main/java/com/fs/admin/service/impl/AdminLiveServiceImpl.java

@@ -0,0 +1,64 @@
+package com.fs.admin.service.impl;
+
+import com.fs.admin.mapper.AdminLiveMapper;
+import com.fs.admin.service.IAdminLiveService;
+import com.fs.admin.vo.AdminLiveVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class AdminLiveServiceImpl implements IAdminLiveService {
+
+    @Autowired
+    private AdminLiveMapper adminLiveMapper;
+
+    @Override
+    public List<Map<String, Object>> selectLiveList(Long companyId, String companyName, String liveTitle, Integer status) {
+        return toMapList(adminLiveMapper.selectLiveList(liveTitle, status));
+    }
+
+    @Override
+    public List<Map<String, Object>> selectLiveListForExport(Long companyId, String companyName, String liveTitle, Integer status) {
+        return toMapList(adminLiveMapper.selectLiveList(liveTitle, status));
+    }
+
+    @Override
+    public Map<String, Object> selectLiveById(Long liveId) {
+        AdminLiveVO vo = adminLiveMapper.selectLiveById(liveId);
+        if (vo == null) return null;
+        return toMap(vo);
+    }
+
+    private Map<String, Object> toMap(AdminLiveVO vo) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("liveId", vo.getLiveId());
+        map.put("companyId", vo.getCompanyId());
+        map.put("liveTitle", vo.getLiveName());
+        map.put("liveName", vo.getLiveName());
+        map.put("coverUrl", vo.getLiveImgUrl());
+        map.put("startTime", vo.getStartTime());
+        map.put("finishTime", vo.getFinishTime());
+        map.put("status", vo.getStatus());
+        map.put("liveType", vo.getLiveType());
+        map.put("showType", vo.getShowType());
+        map.put("anchorId", vo.getAnchorId());
+        map.put("isShow", vo.getIsShow());
+        map.put("isDel", vo.getIsDel());
+        map.put("createTime", vo.getCreateTime());
+        map.put("liveDesc", vo.getLiveDesc());
+        map.put("liveConfig", vo.getLiveConfig());
+        map.put("rtmpUrl", vo.getRtmpUrl());
+        map.put("flvHlsUrl", vo.getFlvHlsUrl());
+        map.put("companyName", vo.getCompanyName());
+        map.put("tenantCode", vo.getTenantCode());
+        return map;
+    }
+
+    private List<Map<String, Object>> toMapList(List<AdminLiveVO> voList) {
+        return voList.stream().map(this::toMap).collect(java.util.stream.Collectors.toList());
+    }
+}

+ 39 - 0
fs-service/src/main/java/com/fs/admin/service/impl/AdminLiveVideoServiceImpl.java

@@ -0,0 +1,39 @@
+package com.fs.admin.service.impl;
+
+import com.fs.admin.mapper.AdminLiveVideoMapper;
+import com.fs.admin.service.IAdminLiveVideoService;
+import com.fs.admin.vo.AdminLiveVideoVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class AdminLiveVideoServiceImpl implements IAdminLiveVideoService {
+
+    @Autowired
+    private AdminLiveVideoMapper adminLiveVideoMapper;
+
+    @Override
+    public List<Map<String, Object>> selectLiveVideoList(Long companyId, String companyName, String videoTitle) {
+        List<AdminLiveVideoVO> voList = adminLiveVideoMapper.selectLiveVideoList(videoTitle);
+        return voList.stream().map(vo -> {
+            Map<String, Object> map = new HashMap<>();
+            map.put("videoId", vo.getVideoId());
+            map.put("liveId", vo.getLiveId());
+            map.put("videoUrl", vo.getVideoUrl());
+            map.put("videoType", vo.getVideoType());
+            map.put("duration", vo.getDuration());
+            map.put("createTime", vo.getCreateTime());
+            map.put("sort", vo.getSort());
+            map.put("fileSize", vo.getFileSize());
+            map.put("finishStatus", vo.getFinishStatus());
+            map.put("remark", vo.getRemark());
+            map.put("companyName", vo.getCompanyName());
+            map.put("tenantCode", vo.getTenantCode());
+            return map;
+        }).collect(java.util.stream.Collectors.toList());
+    }
+}

+ 76 - 0
fs-service/src/main/java/com/fs/admin/service/impl/AdminProductServiceImpl.java

@@ -0,0 +1,76 @@
+package com.fs.admin.service.impl;
+
+import com.fs.admin.mapper.AdminProductMapper;
+import com.fs.admin.service.IAdminProductService;
+import com.fs.admin.vo.AdminProductVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class AdminProductServiceImpl implements IAdminProductService {
+
+    @Autowired
+    private AdminProductMapper adminProductMapper;
+
+    @Override
+    public List<Map<String, Object>> selectProductList(String productName, String status) {
+        return toMapList(adminProductMapper.selectProductListByStatus(productName, status));
+    }
+
+    @Override
+    public List<Map<String, Object>> selectProductListForExport(String productName, String status) {
+        return toMapList(adminProductMapper.selectProductListByStatus(productName, status));
+    }
+
+    @Override
+    public List<Map<String, Object>> selectProductPendingList() {
+        return toMapList(adminProductMapper.selectProductListByStatus(null, "0"));
+    }
+
+    @Override
+    public List<Map<String, Object>> selectProductListForStatistics() {
+        return toMapList(adminProductMapper.selectProductList(null));
+    }
+
+    @Override
+    public Map<String, Object> selectProductById(Long productId) {
+        AdminProductVO vo = adminProductMapper.selectProductById(productId);
+        if (vo == null) return null;
+        return toMap(vo);
+    }
+
+    @Override
+    public int auditProduct(Long productId, String status) {
+        return adminProductMapper.updateAuditStatus(productId, status);
+    }
+
+    private Map<String, Object> toMap(AdminProductVO vo) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("productId", vo.getProductId());
+        map.put("productName", vo.getProductName());
+        map.put("productImage", vo.getImage());
+        map.put("image", vo.getImage());
+        map.put("price", vo.getPrice());
+        map.put("stock", vo.getStock());
+        map.put("isShow", vo.getIsShow());
+        map.put("isAudit", vo.getIsAudit());
+        map.put("status", vo.getIsAudit());
+        map.put("description", vo.getDescription());
+        map.put("createTime", vo.getCreateTime());
+        map.put("sales", vo.getSales());
+        map.put("cateId", vo.getCateId());
+        map.put("isDel", vo.getIsDel());
+        map.put("brand", vo.getBrand());
+        map.put("companyName", vo.getCompanyName());
+        map.put("tenantCode", vo.getTenantCode());
+        return map;
+    }
+
+    private List<Map<String, Object>> toMapList(List<AdminProductVO> voList) {
+        return voList.stream().map(this::toMap).collect(java.util.stream.Collectors.toList());
+    }
+}

+ 21 - 0
fs-service/src/main/java/com/fs/admin/service/impl/AdminVideoResourceServiceImpl.java

@@ -0,0 +1,21 @@
+package com.fs.admin.service.impl;
+
+import com.fs.admin.mapper.AdminVideoResourceMapper;
+import com.fs.admin.service.IAdminVideoResourceService;
+import com.fs.admin.vo.AdminVideoResourceVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class AdminVideoResourceServiceImpl implements IAdminVideoResourceService {
+
+    @Autowired
+    private AdminVideoResourceMapper adminVideoResourceMapper;
+
+    @Override
+    public List<AdminVideoResourceVO> selectVideoResourceList(String videoName) {
+        return adminVideoResourceMapper.selectVideoResourceList(videoName);
+    }
+}

+ 35 - 0
fs-service/src/main/java/com/fs/admin/vo/AdminLiveVO.java

@@ -0,0 +1,35 @@
+package com.fs.admin.vo;
+
+import lombok.Data;
+
+@Data
+public class AdminLiveVO {
+
+    private Long liveId;
+    private Long companyId;
+    private Long companyUserId;
+    private Long talentId;
+    private String liveName;
+    private String liveDesc;
+    private Integer showType;
+    private Integer status;
+    private String createTime;
+    private Long anchorId;
+    private Integer liveType;
+    private String startTime;
+    private String finishTime;
+    private String liveImgUrl;
+    private String liveConfig;
+    private Integer isShow;
+    private Integer isDel;
+    private String qwQrCode;
+    private String rtmpUrl;
+    private String configJson;
+    private Integer isAudit;
+    private String flvHlsUrl;
+    private String idCardUrl;
+    private Integer globalVisible;
+
+    private String companyName;
+    private String tenantCode;
+}

+ 21 - 0
fs-service/src/main/java/com/fs/admin/vo/AdminLiveVideoVO.java

@@ -0,0 +1,21 @@
+package com.fs.admin.vo;
+
+import lombok.Data;
+
+@Data
+public class AdminLiveVideoVO {
+
+    private Long videoId;
+    private Long liveId;
+    private String videoUrl;
+    private Integer videoType;
+    private Integer duration;
+    private String createTime;
+    private Integer sort;
+    private Integer fileSize;
+    private Integer finishStatus;
+    private String remark;
+
+    private String companyName;
+    private String tenantCode;
+}

+ 84 - 0
fs-service/src/main/java/com/fs/admin/vo/AdminProductVO.java

@@ -0,0 +1,84 @@
+package com.fs.admin.vo;
+
+import lombok.Data;
+import java.math.BigDecimal;
+
+@Data
+public class AdminProductVO {
+
+    private Long productId;
+    private String video;
+    private String image;
+    private String sliderImage;
+    private String productName;
+    private String productInfo;
+    private String keyword;
+    private String barCode;
+    private Long cateId;
+    private BigDecimal price;
+    private BigDecimal vipPrice;
+    private BigDecimal otPrice;
+    private BigDecimal agentPrice;
+    private BigDecimal postage;
+    private String unitName;
+    private Integer sort;
+    private Integer sales;
+    private Integer stock;
+    private Integer isShow;
+    private Integer isHot;
+    private Integer isBenefit;
+    private Integer isBest;
+    private Integer isNew;
+    private String description;
+    private String createTime;
+    private String updateTime;
+    private Integer isPostage;
+    private Integer isDel;
+    private BigDecimal giveIntegral;
+    private BigDecimal cost;
+    private Integer isGood;
+    private Integer browse;
+    private String codePath;
+    private Integer tempId;
+    private Integer specType;
+    private Integer isIntegral;
+    private Integer integral;
+    private Integer productType;
+    private String prescribeCode;
+    private String prescribeSpec;
+    private String prescribeFactory;
+    private String prescribeName;
+    private Integer isDisplay;
+    private Integer tuiCateId;
+    private String companyIds;
+    private Long storeId;
+    private String isDrug;
+    private String drugImage;
+    private String drugRegCertNo;
+    private String commonName;
+    private String dosageForm;
+    private String unitPrice;
+    private String batchNumber;
+    private String mah;
+    private String mahAddress;
+    private String manufacturer;
+    private String manufacturerAddress;
+    private String indications;
+    private String dosage;
+    private String adverseReactions;
+    private String contraindications;
+    private String precautions;
+    private String isAudit;
+    private String returnAddress;
+    private String brand;
+    private String foodProductionLicenseCode;
+    private String originPlace;
+    private String netContent;
+    private String shelfLife;
+    private Integer domesticImported;
+    private String appIds;
+    private Long purchaseLimit;
+
+    private String companyName;
+    private String tenantCode;
+}

+ 29 - 0
fs-service/src/main/java/com/fs/admin/vo/AdminVideoResourceVO.java

@@ -0,0 +1,29 @@
+package com.fs.admin.vo;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class AdminVideoResourceVO {
+
+    private Long id;
+
+    private String videoName;
+
+    private String videoType;
+
+    private String playUrl;
+
+    private Long duration;
+
+    private Long status;
+
+    private LocalDateTime createTime;
+
+    private Long companyId;
+
+    private String companyName;
+
+    private String tenantCode;
+}

+ 63 - 0
fs-service/src/main/resources/mapper/admin/AdminLiveMapper.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.admin.mapper.AdminLiveMapper">
+
+    <resultMap type="com.fs.admin.vo.AdminLiveVO" id="AdminLiveVOResult">
+        <id     property="liveId"        column="live_id"        />
+        <result property="companyId"     column="company_id"     />
+        <result property="companyUserId" column="company_user_id" />
+        <result property="talentId"      column="talent_id"      />
+        <result property="liveName"      column="live_name"      />
+        <result property="liveDesc"      column="live_desc"      />
+        <result property="showType"      column="show_type"      />
+        <result property="status"        column="status"         />
+        <result property="createTime"    column="create_time"    />
+        <result property="anchorId"      column="anchor_id"      />
+        <result property="liveType"      column="live_type"      />
+        <result property="startTime"     column="start_time"     />
+        <result property="finishTime"    column="finish_time"    />
+        <result property="liveImgUrl"    column="live_img_url"   />
+        <result property="liveConfig"    column="live_config"    />
+        <result property="isShow"        column="is_show"        />
+        <result property="isDel"         column="is_del"         />
+        <result property="qwQrCode"      column="qw_qr_code"     />
+        <result property="rtmpUrl"       column="rtmp_url"       />
+        <result property="configJson"    column="config_json"    />
+        <result property="isAudit"       column="is_audit"       />
+        <result property="flvHlsUrl"     column="flv_hls_url"    />
+        <result property="idCardUrl"     column="id_card_url"    />
+        <result property="globalVisible" column="global_visible" />
+    </resultMap>
+
+    <sql id="selectAdminLiveVo">
+        SELECT l.live_id, l.company_id, l.company_user_id, l.talent_id,
+               l.live_name, l.live_desc, l.show_type, l.status,
+               l.create_time, l.anchor_id, l.live_type, l.start_time,
+               l.finish_time, l.live_img_url, l.live_config,
+               l.is_show, l.is_del, l.qw_qr_code, l.rtmp_url,
+               l.config_json, l.is_audit, l.flv_hls_url, l.id_card_url,
+               l.global_visible
+        FROM live l
+    </sql>
+
+    <select id="selectLiveList" resultMap="AdminLiveVOResult">
+        <include refid="selectAdminLiveVo"/>
+        <where>
+            <if test="liveTitle != null and liveTitle != ''">
+                AND l.live_name LIKE CONCAT('%', #{liveTitle}, '%')
+            </if>
+            <if test="status != null">
+                AND l.status = #{status}
+            </if>
+        </where>
+        ORDER BY l.create_time DESC
+    </select>
+
+    <select id="selectLiveById" resultMap="AdminLiveVOResult">
+        <include refid="selectAdminLiveVo"/>
+        WHERE l.live_id = #{liveId}
+    </select>
+
+</mapper>

+ 37 - 0
fs-service/src/main/resources/mapper/admin/AdminLiveVideoMapper.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.admin.mapper.AdminLiveVideoMapper">
+
+    <resultMap type="com.fs.admin.vo.AdminLiveVideoVO" id="AdminLiveVideoVOResult">
+        <id     property="videoId"       column="video_id"       />
+        <result property="liveId"        column="live_id"        />
+        <result property="videoUrl"      column="video_url"      />
+        <result property="videoType"     column="video_type"     />
+        <result property="duration"      column="duration"       />
+        <result property="createTime"    column="create_time"    />
+        <result property="sort"          column="sort"           />
+        <result property="fileSize"      column="file_size"      />
+        <result property="finishStatus"  column="finish_status"  />
+        <result property="remark"        column="remark"         />
+    </resultMap>
+
+    <sql id="selectAdminLiveVideoVo">
+        SELECT v.video_id, v.live_id, v.video_url, v.video_type,
+               v.duration, v.create_time, v.sort, v.file_size,
+               v.finish_status, v.remark
+        FROM live_video v
+    </sql>
+
+    <select id="selectLiveVideoList" resultMap="AdminLiveVideoVOResult">
+        <include refid="selectAdminLiveVideoVo"/>
+        <where>
+            <if test="videoTitle != null and videoTitle != ''">
+                AND v.remark LIKE CONCAT('%', #{videoTitle}, '%')
+            </if>
+        </where>
+        ORDER BY v.create_time DESC
+    </select>
+
+</mapper>

+ 141 - 0
fs-service/src/main/resources/mapper/admin/AdminProductMapper.xml

@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.admin.mapper.AdminProductMapper">
+
+    <resultMap type="com.fs.admin.vo.AdminProductVO" id="AdminProductVOResult">
+        <id     property="productId"              column="product_id"              />
+        <result property="video"                  column="video"                   />
+        <result property="image"                  column="image"                   />
+        <result property="sliderImage"            column="slider_image"            />
+        <result property="productName"            column="product_name"            />
+        <result property="productInfo"            column="product_info"            />
+        <result property="keyword"                column="keyword"                 />
+        <result property="barCode"                column="bar_code"                />
+        <result property="cateId"                 column="cate_id"                 />
+        <result property="price"                  column="price"                   />
+        <result property="vipPrice"               column="vip_price"               />
+        <result property="otPrice"                column="ot_price"                />
+        <result property="agentPrice"             column="agent_price"             />
+        <result property="postage"                column="postage"                 />
+        <result property="unitName"               column="unit_name"               />
+        <result property="sort"                   column="sort"                    />
+        <result property="sales"                  column="sales"                   />
+        <result property="stock"                  column="stock"                   />
+        <result property="isShow"                 column="is_show"                 />
+        <result property="isHot"                  column="is_hot"                  />
+        <result property="isBenefit"              column="is_benefit"              />
+        <result property="isBest"                 column="is_best"                 />
+        <result property="isNew"                  column="is_new"                  />
+        <result property="description"            column="description"             />
+        <result property="createTime"             column="create_time"             />
+        <result property="updateTime"             column="update_time"             />
+        <result property="isPostage"              column="is_postage"              />
+        <result property="isDel"                  column="is_del"                  />
+        <result property="giveIntegral"           column="give_integral"           />
+        <result property="cost"                   column="cost"                    />
+        <result property="isGood"                 column="is_good"                 />
+        <result property="browse"                 column="browse"                  />
+        <result property="codePath"               column="code_path"               />
+        <result property="tempId"                 column="temp_id"                 />
+        <result property="specType"               column="spec_type"               />
+        <result property="isIntegral"             column="is_integral"             />
+        <result property="integral"               column="integral"                />
+        <result property="productType"            column="product_type"            />
+        <result property="prescribeCode"          column="prescribe_code"          />
+        <result property="prescribeSpec"          column="prescribe_spec"          />
+        <result property="prescribeFactory"       column="prescribe_factory"       />
+        <result property="prescribeName"          column="prescribe_name"          />
+        <result property="isDisplay"              column="is_display"              />
+        <result property="tuiCateId"              column="tui_cate_id"             />
+        <result property="companyIds"             column="company_ids"             />
+        <result property="storeId"                column="store_id"                />
+        <result property="isDrug"                 column="is_drug"                 />
+        <result property="drugImage"              column="drug_image"              />
+        <result property="drugRegCertNo"          column="drug_reg_cert_no"        />
+        <result property="commonName"             column="common_name"             />
+        <result property="dosageForm"             column="dosage_form"             />
+        <result property="unitPrice"              column="unit_price"              />
+        <result property="batchNumber"            column="batch_number"            />
+        <result property="mah"                    column="mah"                     />
+        <result property="mahAddress"             column="mah_address"             />
+        <result property="manufacturer"           column="manufacturer"            />
+        <result property="manufacturerAddress"    column="manufacturer_address"    />
+        <result property="indications"            column="indications"             />
+        <result property="dosage"                 column="dosage"                  />
+        <result property="adverseReactions"       column="adverse_reactions"       />
+        <result property="contraindications"      column="contraindications"       />
+        <result property="precautions"            column="precautions"             />
+        <result property="isAudit"                column="is_audit"                />
+        <result property="returnAddress"          column="return_address"          />
+        <result property="brand"                  column="brand"                   />
+        <result property="foodProductionLicenseCode" column="food_production_license_code"/>
+        <result property="originPlace"            column="origin_place"            />
+        <result property="netContent"             column="net_content"             />
+        <result property="shelfLife"              column="shelf_life"              />
+        <result property="domesticImported"       column="domestic_imported"       />
+        <result property="appIds"                 column="app_ids"                 />
+        <result property="purchaseLimit"          column="purchase_limit"          />
+    </resultMap>
+
+    <sql id="selectAdminProductVo">
+        SELECT p.product_id, p.video, p.image, p.slider_image,
+               p.product_name, p.product_info, p.keyword, p.bar_code,
+               p.cate_id, p.price, p.vip_price, p.ot_price,
+               p.agent_price, p.postage, p.unit_name, p.sort,
+               p.sales, p.stock, p.is_show, p.is_hot, p.is_benefit,
+               p.is_best, p.is_new, p.description, p.create_time,
+               p.update_time, p.is_postage, p.is_del, p.give_integral,
+               p.cost, p.is_good, p.browse, p.code_path,
+               p.temp_id, p.spec_type, p.is_integral, p.integral,
+               p.product_type, p.prescribe_code, p.prescribe_spec,
+               p.prescribe_factory, p.prescribe_name, p.is_display,
+               p.tui_cate_id, p.company_ids, p.store_id, p.is_drug,
+               p.drug_image, p.drug_reg_cert_no, p.common_name,
+               p.dosage_form, p.unit_price, p.batch_number,
+               p.mah, p.mah_address, p.manufacturer,
+               p.manufacturer_address, p.indications, p.dosage,
+               p.adverse_reactions, p.contraindications, p.precautions,
+               p.is_audit, p.return_address, p.brand,
+               p.food_production_license_code, p.origin_place,
+               p.net_content, p.shelf_life, p.domestic_imported,
+               p.app_ids, p.purchase_limit
+        FROM fs_store_product_scrm p
+    </sql>
+
+    <select id="selectProductList" resultMap="AdminProductVOResult">
+        <include refid="selectAdminProductVo"/>
+        <where>
+            <if test="productName != null and productName != ''">
+                AND p.product_name LIKE CONCAT('%', #{productName}, '%')
+            </if>
+        </where>
+        ORDER BY p.create_time DESC
+    </select>
+
+    <select id="selectProductListByStatus" resultMap="AdminProductVOResult">
+        <include refid="selectAdminProductVo"/>
+        <where>
+            <if test="productName != null and productName != ''">
+                AND p.product_name LIKE CONCAT('%', #{productName}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND p.is_audit = #{status}
+            </if>
+        </where>
+        ORDER BY p.create_time DESC
+    </select>
+
+    <select id="selectProductById" resultMap="AdminProductVOResult">
+        <include refid="selectAdminProductVo"/>
+        WHERE p.product_id = #{productId}
+    </select>
+
+    <update id="updateAuditStatus">
+        UPDATE fs_store_product_scrm
+        SET is_audit = #{status}, update_time = NOW()
+        WHERE product_id = #{productId}
+    </update>
+
+</mapper>

+ 43 - 0
fs-service/src/main/resources/mapper/admin/AdminVideoResourceMapper.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.admin.mapper.AdminVideoResourceMapper">
+
+    <resultMap type="com.fs.admin.vo.AdminVideoResourceVO" id="AdminVideoResourceVOResult">
+        <id     property="id"          column="video_id"      />
+        <result property="videoName"   column="video_name"    />
+        <result property="videoType"   column="video_type"    />
+        <result property="playUrl"     column="play_url"      />
+        <result property="duration"    column="duration"      />
+        <result property="status"      column="status"        />
+        <result property="createTime"  column="create_time"   />
+    </resultMap>
+
+    <sql id="selectAdminVideoResourceVo">
+        SELECT v.video_id, v.title AS video_name, v.upload_type AS video_type,
+               v.video_url AS play_url, v.duration, v.status, v.create_time
+        FROM fs_user_course_video v
+    </sql>
+
+    <select id="selectVideoResourceList" resultMap="AdminVideoResourceVOResult">
+        <include refid="selectAdminVideoResourceVo"/>
+        <where>
+            <if test="videoName != null and videoName != ''">
+                AND v.title LIKE CONCAT('%', #{videoName}, '%')
+            </if>
+        </where>
+        ORDER BY v.create_time DESC
+    </select>
+
+    <select id="selectVideoResourceCount" resultType="java.lang.Long">
+        SELECT COUNT(1)
+        FROM fs_user_course_video v
+        <where>
+            <if test="videoName != null and videoName != ''">
+                AND v.title LIKE CONCAT('%', #{videoName}, '%')
+            </if>
+        </where>
+    </select>
+
+</mapper>