Ver código fonte

Merge remote-tracking branch 'origin/saas-api' into saas-api

xgb 1 semana atrás
pai
commit
4cbbf3ffd8

+ 152 - 0
fs-admin-saas/src/main/java/com/fs/company/controller/CompanyVoiceRoboticController.java

@@ -0,0 +1,152 @@
+package com.fs.company.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyVoiceRobotic;
+import com.fs.company.domain.CompanyVoiceRoboticCallees;
+import com.fs.company.domain.CompanyVoiceRoboticWx;
+import com.fs.company.service.ICompanyVoiceRoboticCalleesService;
+import com.fs.company.service.ICompanyVoiceRoboticService;
+import com.fs.company.service.ICompanyVoiceRoboticWxService;
+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(SaaS管理端)
+ *
+ * @author fs
+ * @date 2025-05-30
+ */
+@RestController
+@RequestMapping("/company/companyVoiceRobotic")
+public class CompanyVoiceRoboticController extends BaseController {
+
+    @Autowired
+    private ICompanyVoiceRoboticService companyVoiceRoboticService;
+
+    @Autowired
+    private ICompanyVoiceRoboticCalleesService companyVoiceRoboticCalleesService;
+
+    @Autowired
+    private ICompanyVoiceRoboticWxService companyVoiceRoboticWxService;
+
+    /**
+     * 查询机器人外呼任务列表(分页)
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CompanyVoiceRobotic companyVoiceRobotic) {
+        startPage();
+        List<CompanyVoiceRobotic> list = companyVoiceRoboticService.selectCompanyVoiceRoboticList(companyVoiceRobotic);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询机器人外呼任务列表(全部,用于下拉选择)
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:list')")
+    @GetMapping("/listAll")
+    public R listAll(CompanyVoiceRobotic companyVoiceRobotic) {
+        return R.ok().put("data", companyVoiceRoboticService.selectCompanyVoiceRoboticList(companyVoiceRobotic));
+    }
+
+    /**
+     * 查询被叫号码列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:list')")
+    @GetMapping("/calleesList")
+    public TableDataInfo calleesList(Long id) {
+        startPage();
+        List<CompanyVoiceRoboticCallees> list = companyVoiceRoboticCalleesService.selectCompanyVoiceRoboticCalleesListByRoboticId(id);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询加微方式列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:list')")
+    @GetMapping("/wxList")
+    public TableDataInfo wxList(Long id) {
+        startPage();
+        List<CompanyVoiceRoboticWx> list = companyVoiceRoboticWxService.selectWxList(id);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询企微加微方式列表
+     */
+    @GetMapping("/wxListQw")
+    public TableDataInfo wxListQw(Long id) {
+        startPage();
+        List<CompanyVoiceRoboticWx> list = companyVoiceRoboticWxService.selectWxListQw(id);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出机器人外呼任务列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:export')")
+    @Log(title = "机器人外呼任务", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CompanyVoiceRobotic companyVoiceRobotic) {
+        List<CompanyVoiceRobotic> list = companyVoiceRoboticService.selectCompanyVoiceRoboticList(companyVoiceRobotic);
+        ExcelUtil<CompanyVoiceRobotic> util = new ExcelUtil<CompanyVoiceRobotic>(CompanyVoiceRobotic.class);
+        return util.exportExcel(list, "robotic");
+    }
+
+    /**
+     * 获取机器人外呼任务详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return AjaxResult.success(companyVoiceRoboticService.selectCompanyVoiceRoboticById(id));
+    }
+
+    /**
+     * 新增机器人外呼任务
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:add')")
+    @Log(title = "机器人外呼任务", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CompanyVoiceRobotic companyVoiceRobotic) {
+        return toAjax(companyVoiceRoboticService.insertCompanyVoiceRobotic(companyVoiceRobotic));
+    }
+
+    /**
+     * 修改机器人外呼任务
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:edit')")
+    @Log(title = "机器人外呼任务", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CompanyVoiceRobotic companyVoiceRobotic) {
+        return toAjax(companyVoiceRoboticService.updateCompanyVoiceRobotic(companyVoiceRobotic));
+    }
+
+    /**
+     * 删除机器人外呼任务
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:remove')")
+    @Log(title = "机器人外呼任务", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(companyVoiceRoboticService.deleteCompanyVoiceRoboticByIds(ids));
+    }
+
+    /**
+     * 员工列表(全部,用于下拉选择)
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyVoiceRobotic:list')")
+    @GetMapping("/companyUserList")
+    public R companyUserList() {
+        return R.ok().put("data", companyVoiceRoboticService.qwUserList());
+    }
+}

+ 77 - 69
fs-admin-saas/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java

@@ -1,14 +1,19 @@
 package com.fs.course.controller;
 
-import java.util.ArrayList;
-import java.util.List;
+import cn.hutool.core.collection.CollectionUtil;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
 import com.fs.common.exception.CustomException;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.param.FsCourseOverParam;
 import com.fs.course.param.FsCourseWatchLogListParam;
 import com.fs.course.param.FsCourseWatchLogStatisticsListParam;
-import com.fs.course.service.IFsUserCoursePeriodDaysService;
-import com.fs.course.service.IFsUserCoursePeriodService;
+import com.fs.course.service.IFsCourseWatchLogService;
 import com.fs.course.vo.FsCourseOverVO;
 import com.fs.course.vo.FsCourseWatchLogListVO;
 import com.fs.course.vo.FsCourseWatchLogStatisticsListVO;
@@ -16,24 +21,13 @@ import com.fs.qw.param.QwWatchLogStatisticsListParam;
 import com.fs.qw.service.IQwWatchLogService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.course.domain.FsCourseWatchLog;
-import com.fs.course.service.IFsCourseWatchLogService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 短链课程看课记录Controller
@@ -50,34 +44,28 @@ public class FsCourseWatchLogController extends BaseController
 
     @Autowired
     private IQwWatchLogService qwWatchLogService;
-    @Autowired
-    private IFsUserCoursePeriodDaysService userCoursePeriodDaysService;
-    @Autowired
-    private IFsUserCoursePeriodService userCoursePeriodService;
-
+    /**
+     * 查询短链课程看课记录列表
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:list')")
-    @PostMapping("/list")
-    public R list(@RequestBody FsCourseWatchLogListParam param)
+    @GetMapping("/list")
+    public TableDataInfo list(FsCourseWatchLogListParam param)
     {
-        if (param.getSendType()==1&& param.getPeriodETime()!=null && param.getPeriodSTime()!=null) {
-            List<Long> periodIds = userCoursePeriodDaysService.selectFsUserCoursePeriodDaysByTime(param.getPeriodSTime(), param.getPeriodETime());
-
-            if (!periodIds.isEmpty()){
-                List<Long> longs = userCoursePeriodService.selectFsUserCoursePeriodListByPeriodId(periodIds, param.getCompanyId());
-                if (!longs.isEmpty()){
-                    param.setPeriodIds(longs);
-                }else {
-                    return R.ok().put("data", new PageInfo<>(new ArrayList<>()));
-                }
-            }else {
-                return R.ok().put("data", new PageInfo<>(new ArrayList<>()));
-            }
+        startPage();
+        if(CollectionUtil.isNotEmpty(param.getUserIds())){
+            param.setUserIds(param.getUserIds().stream()
+                    .filter(userId -> userId != null && userId.startsWith("user_"))
+                    .map(userId -> userId.substring(5))
+                    .collect(Collectors.toList())
+            );
         }
-
-        PageHelper.startPage(param.getPageNum(), param.getPageSize());
-        return R.ok().put("data", new PageInfo<>(fsCourseWatchLogService.selectFsCourseWatchLogListVO(param)));
+        List<FsCourseWatchLogListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogListVO(param);
+        return getDataTable(list);
     }
 
+    /**
+     * 查询短链课程看课记录列表
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:pageList')")
     @PostMapping("/pageList")
     public R pageList(@RequestBody FsCourseWatchLogListParam param)
@@ -90,45 +78,44 @@ public class FsCourseWatchLogController extends BaseController
     @GetMapping("/qwWatchLogAllStatisticsList")
     public TableDataInfo qwWatchLogAllStatisticsList(QwWatchLogStatisticsListParam param)
     {
-        logger.info("会员课程数据汇总 参数: {}", param);
+        logger.info("会员课程数据汇总 参数: {}",param);
 
-        if (param.getCompanyId() == null && (param.getUserIds() == null || param.getUserIds().isEmpty())) {
+        if(param.getCompanyId() == null){
             throw new CustomException("必须选择公司!");
         }
-        if (param.getSTime() == null || param.getETime() == null) {
+        if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
         return qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
     }
-
     @GetMapping("/qwWatchLogStatisticsList")
     public TableDataInfo qwWatchLogStatisticsList(QwWatchLogStatisticsListParam param)
     {
-        if (param.getPageNum() == null) {
+        if(param.getPageNum() == null){
             param.setPageNum(1L);
         }
-        if (param.getPageSize() == null) {
+        if(param.getPageSize() == null){
             param.setPageSize(10L);
         }
-        if (param.getSTime() == null || param.getETime() == null) {
+        if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
-//        if (param.getCompanyId() == null) {
-//            throw new CustomException("必须选择公司!");
-//        }
+        if(param.getCompanyId() == null){
+            throw new CustomException("必须选择公司!");
+        }
         return qwWatchLogService.selectQwWatchLogStatisticsListVONew(param);
     }
-
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:statisticsList')")
     @GetMapping("/statisticsList")
     public TableDataInfo statisticsList(FsCourseWatchLogStatisticsListParam param)
     {
-//        if (param.getCompanyId() == null) {
-//            if (param.getUserId() == null) {
-//                throw new CustomException("查看公司或者用户必填!");
-//            }
-//        }
-        if (param.getSTime() == null || param.getETime() == null) {
+        // 如果看指定用户就不用设置公司
+        if(param.getCompanyId() == null){
+            if(param.getUserId() == null) {
+                throw new CustomException("查看公司或者用户必填!");
+            }
+        }
+        if (param.getSTime()==null||param.getETime()==null){
             throw new CustomException("必须选择开始时间和结束时间!");
         }
         startPage();
@@ -137,17 +124,22 @@ public class FsCourseWatchLogController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 会员看课统计导出
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:statisticsExport')")
     @Log(title = "会员看课统计导出", businessType = BusinessType.EXPORT)
     @PostMapping("/statisticsExport")
     public AjaxResult statisticsExport(@RequestBody FsCourseWatchLogStatisticsListParam param)
     {
-//        if (param.getCompanyId() == null) {
-//            if (param.getUserId() == null) {
-//                throw new CustomException("查看公司或者用户必填!");
-//            }
-//        }
-        if (param.getSTime() == null || param.getETime() == null) {
+
+        // 如果看指定用户就不用设置公司
+        if(param.getCompanyId() == null){
+            if(param.getUserId() == null) {
+                throw new CustomException("查看公司或者用户必填!");
+            }
+        }
+        if (param.getSTime()==null||param.getETime()==null){
             throw new CustomException("必须选择开始时间和结束时间!");
         }
 
@@ -157,6 +149,10 @@ public class FsCourseWatchLogController extends BaseController
         return util.exportExcel(list, "会员看课统计");
     }
 
+
+    /**
+     * 导出短链课程看课记录列表
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:export')")
     @Log(title = "短链课程看课记录", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
@@ -167,6 +163,9 @@ public class FsCourseWatchLogController extends BaseController
         return util.exportExcel(list, "短链课程看课记录数据");
     }
 
+    /**
+     * 获取短链课程看课记录详细信息
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:query')")
     @GetMapping(value = "/{logId}")
     public AjaxResult getInfo(@PathVariable("logId") Long logId)
@@ -174,6 +173,9 @@ public class FsCourseWatchLogController extends BaseController
         return AjaxResult.success(fsCourseWatchLogService.selectFsCourseWatchLogByLogId(logId));
     }
 
+    /**
+     * 新增短链课程看课记录
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:add')")
     @Log(title = "短链课程看课记录", businessType = BusinessType.INSERT)
     @PostMapping
@@ -182,6 +184,9 @@ public class FsCourseWatchLogController extends BaseController
         return toAjax(fsCourseWatchLogService.insertFsCourseWatchLog(fsCourseWatchLog));
     }
 
+    /**
+     * 修改短链课程看课记录
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:edit')")
     @Log(title = "短链课程看课记录", businessType = BusinessType.UPDATE)
     @PutMapping
@@ -190,9 +195,12 @@ public class FsCourseWatchLogController extends BaseController
         return toAjax(fsCourseWatchLogService.updateFsCourseWatchLog(fsCourseWatchLog));
     }
 
+    /**
+     * 删除短链课程看课记录
+     */
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:remove')")
     @Log(title = "短链课程看课记录", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{logIds}")
+	@DeleteMapping("/{logIds}")
     public AjaxResult remove(@PathVariable Long[] logIds)
     {
         return toAjax(fsCourseWatchLogService.deleteFsCourseWatchLogByLogIds(logIds));
@@ -202,7 +210,7 @@ public class FsCourseWatchLogController extends BaseController
     public TableDataInfo watchLogStatistics(FsCourseOverParam param)
     {
         startPage();
-        if (param.getSTime() == null || param.getETime() == null) {
+        if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
         List<FsCourseOverVO> list = fsCourseWatchLogService.selectFsCourseWatchLogOverStatisticsListVO(param);

+ 28 - 4
fs-admin-saas/src/main/java/com/fs/stats/SalesWatchStatisController.java

@@ -59,7 +59,11 @@ public class SalesWatchStatisController {
         fsStatisSalerWatchService.writeData(date);
         return R.ok();
     }
-
+    /**
+     * 销售完播统计查询
+     * @param param param
+     * @return R
+     */
     @PostMapping("/seller/pageList")
     public R sellerQueryList(@RequestBody StatsWatchLogPageListDTO param){
         if(param.getPageNum() == null) {
@@ -74,6 +78,11 @@ public class SalesWatchStatisController {
         return R.ok().put("data",new PageInfo<>(list));
     }
 
+    /**
+     * 进线转化统计
+     * @param param 参数
+     * @return R
+     */
     @PostMapping("/inline/pageList")
     public R inlineTransferStats(@RequestBody StatsWatchLogPageListDTO param){
         if(param.getPageNum() == null) {
@@ -87,7 +96,6 @@ public class SalesWatchStatisController {
         List<FsStatisQwWatch> list = fsStatisQwWatchService.queryList(param);
         return R.ok().put("data",new PageInfo<>(list));
     }
-
     @PostMapping("/inline/export")
     @RateLimiter(time=5,count = 1)
     public AjaxResult exportInlineQueryList(@RequestBody StatsWatchLogPageListDTO param){
@@ -108,6 +116,11 @@ public class SalesWatchStatisController {
         return util.exportExcel(list, "销售完播统计");
     }
 
+    /**
+     * 训练营完播统计查询
+     * @param param param
+     * @return R
+     */
     @PostMapping("/period/pageList")
     public R periodQueryList(@RequestBody StatsWatchLogPageListDTO param){
         if(param.getPageNum() == null) {
@@ -132,6 +145,11 @@ public class SalesWatchStatisController {
         return util.exportExcel(list, "SOP任务完播统计");
     }
 
+    /**
+     * 每日完播统计查询
+     * @param param param
+     * @return R
+     */
     @PostMapping("/everyDay/pageList")
     public R everyDayQueryList(@RequestBody StatsWatchLogPageListDTO param){
         if(param.getPageNum() == null) {
@@ -144,7 +162,6 @@ public class SalesWatchStatisController {
         List<FsStatisSalerWatch> list = fsStatisSalerWatchService.queryTodayList(param);
         return R.ok().put("data", new PageInfo<>(list));
     }
-
     @PostMapping("/everyDay/export")
     @RateLimiter(time=5,count = 1)
     public AjaxResult exportEveryDayQueryList(@RequestBody StatsWatchLogPageListDTO param){
@@ -154,7 +171,10 @@ public class SalesWatchStatisController {
         ExcelUtil<FsStatisEveryDayWatch> util = new ExcelUtil<>(FsStatisEveryDayWatch.class);
         return util.exportExcel(list, "每日完播统计");
     }
-
+    /**
+     * 获取SOP任务数据
+     * @return
+     */
     @PostMapping("/sopTaskData")
     public R getSOPTaskData(@RequestBody GetSOPTaskDataParam param){
         if(StringUtils.isBlank(param.getStartDate()) && StringUtils.isBlank(param.getEndDate())) {
@@ -165,6 +185,10 @@ public class SalesWatchStatisController {
         return R.ok().put("data",qwSopTaskList);
     }
 
+    /**
+     * 获取部门数据
+     * @return
+     */
     @GetMapping("/getDeptData")
     public R getDeptData(Long companyId){
         List<DeptDataVO> data = companyUserCacheService.getDeptData(companyId);

+ 35 - 0
fs-company/src/main/java/com/fs/company/controller/companyWorkflow/CompanyWorkflowLobsterSimulateController.java

@@ -0,0 +1,35 @@
+package com.fs.company.controller.companyWorkflow;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.utils.ServletUtils;
+import com.fs.company.param.CompanyWorkflowLobsterSimulateParam;
+import com.fs.company.service.ICompanyWorkflowLobsterService;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * AI工作流模拟对话Controller
+ */
+@RestController
+@RequestMapping("/workflow")
+public class CompanyWorkflowLobsterSimulateController extends BaseController {
+
+    @Autowired
+    private ICompanyWorkflowLobsterService lobsterService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 模拟对话
+     */
+    @PostMapping("/simulate")
+    public AjaxResult simulate(@RequestBody CompanyWorkflowLobsterSimulateParam params) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        String reply = lobsterService.simulate(loginUser.getCompany().getCompanyId(), params.getTemplateId(), params.getContent(), params.getSimulateDate());
+        return AjaxResult.success(reply);
+    }
+}

+ 2 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyWorkflowLobsterNodeMapper.java

@@ -19,4 +19,6 @@ public interface CompanyWorkflowLobsterNodeMapper extends BaseMapper<CompanyWork
     void updateBatch(@Param("list") ArrayList<CompanyWorkflowLobsterNode> nodesNew);
 
     int checkNodeGreeting(@Param("templateId") Long templateId);
+
+    List<String> selectCallWordsByTemplateId(@Param("templateId") Long templateId);
 }

+ 16 - 0
fs-service/src/main/java/com/fs/company/param/CompanyWorkflowLobsterSimulateParam.java

@@ -0,0 +1,16 @@
+package com.fs.company.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class CompanyWorkflowLobsterSimulateParam implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long templateId;
+
+    private String content;
+
+    private String simulateDate;
+}

+ 2 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyWorkflowLobsterService.java

@@ -63,4 +63,6 @@ public interface ICompanyWorkflowLobsterService {
     AjaxResult updateTemplateStatus(Long companyId, String username, Long templateId, Integer status);
 
     List<CompanyWorkflowLobster> listTemplateByStatus(Long companyId, Integer status);
+
+    String simulate(Long companyId, Long templateId, String content, String simulateDate);
 }

+ 48 - 22
fs-service/src/main/java/com/fs/company/service/impl/CompanyWorkflowLobsterServiceImpl.java

@@ -2,42 +2,28 @@ package com.fs.company.service.impl;
 
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.spring.SpringUtils;
-import com.fs.company.domain.CompanyWorkflowLobster;
-import com.fs.company.domain.CompanyTagTemplateBinding;
-import com.fs.company.domain.CompanyWorkflowLobsterEdge;
-import com.fs.company.domain.CompanyWorkflowLobsterNode;
-import com.fs.company.domain.CompanyWorkflowLobsterRecord;
-import com.fs.company.domain.CompanyWorkflowLobsterVariable;
-import com.fs.company.mapper.CompanyWorkflowLobsterEdgeMapper;
-import com.fs.company.mapper.CompanyWorkflowLobsterMapper;
-import com.fs.company.mapper.CompanyWorkflowLobsterNodeMapper;
-import com.fs.company.mapper.CompanyWorkflowLobsterRecordMapper;
-import com.fs.company.mapper.CompanyWorkflowLobsterVariableMapper;
-import com.fs.company.mapper.CompanyTagTemplateBindingMapper;
-import com.fs.company.param.CompanyWorkflowLobsterCanvasParam;
-import com.fs.company.param.CompanyWorkflowLobsterConfirmParam;
-import com.fs.company.param.CompanyWorkflowLobsterEdgeParam;
-import com.fs.company.param.CompanyWorkflowLobsterGenerateParam;
-import com.fs.company.param.CompanyWorkflowLobsterNodeParam;
-import com.fs.company.param.CompanyWorkflowLobsterVariableParam;
+import com.fs.company.domain.*;
+import com.fs.company.mapper.*;
+import com.fs.company.param.*;
 import com.fs.company.service.ICompanyWorkflowLobsterService;
+import com.fs.company.utils.JsonUtils;
 import com.fs.fastgptApi.param.ChatParam;
 import com.fs.fastgptApi.service.ChatService;
-import com.fs.wxwork.dto.WxWorkSendTextMsgDTO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 
-import java.sql.Time;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -70,7 +56,10 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
         return all.subList(start, end);
     }
 
-    private static final String LOBSTER_KEY = "fastgpt-lDP6kVelHf2p8j80vfz2Kl7g9PjacwJoTmCplEBGWBaGMCRtv7SueW5mZ4iXe";
+    @Value("${company.lobsterKey:fastgpt-lDP6kVelHf2p8j80vfz2Kl7g9PjacwJoTmCplEBGWBaGMCRtv7SueW5mZ4iXe}")
+    private String LOBSTER_KEY;
+    @Value("${company.lobsterShowKey:fastgpt-hgf4m8QRTAm2pv3SievqRLPHKSJHeX3t8tc4Li15eq0lkNQXXxSDXLKf}")
+    private String LOBSTER_SHOW_KEY;
     private static final ObjectMapper mapper = new ObjectMapper();
     private static final String AI_API = "http://129.28.170.206:3000/api";
 
@@ -707,4 +696,41 @@ public class CompanyWorkflowLobsterServiceImpl implements ICompanyWorkflowLobste
         return all;
     }
 
+    @Override
+    public String simulate(Long companyId, Long templateId, String content, String simulateDate) {
+        JSONObject requestJson = new JSONObject();
+        requestJson.set("userContent", content);
+        requestJson.set("createTime", simulateDate);
+        List<String> callWords = nodeMapper.selectCallWordsByTemplateId(templateId);
+        requestJson.set("callWord", callWords);
+        String requestStr = requestJson.toString();
+        try {
+            R r = callAiService(requestStr, templateId, LOBSTER_SHOW_KEY);
+            
+            if (r.get("data") != null) {
+                Object data = r.get("data");
+                String jsonStr = JSONUtil.toJsonStr(data);
+                ObjectMapper mapper = new ObjectMapper();
+                JsonNode root = mapper.readTree(jsonStr);
+
+                // 提取 choices[0].message.content
+                String choiceContent = root.path("choices")
+                        .path(0)
+                        .path("message")
+                        .path("content")
+                        .asText();
+
+                // 解析 content 中的 JSON 字符串,提取 aiContent
+                JsonNode contentJson = mapper.readTree(choiceContent);
+                String aiContent = contentJson.path("aiContent").asText();
+
+                return aiContent;
+            }
+            return r.toString();
+        } catch (Exception e) {
+            log.error("模拟对话失败: {}", e.getMessage(), e);
+            throw new RuntimeException("模拟对话失败: " + e.getMessage());
+        }
+    }
+
 }

+ 7 - 0
fs-service/src/main/resources/mapper/company/CompanyWorkflowLobsterNodeMapper.xml

@@ -56,5 +56,12 @@
         and del_flag = 0
         and node_type = 2
     </select>
+    <select id="selectCallWordsByTemplateId" resultType="java.lang.String">
+        select message_template from company_workflow_lobster_node
+        where workflow_id = #{templateId}
+          and del_flag = 0
+          and node_type = 2
+          and message_template is not null
+    </select>
 
 </mapper>