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

Merge remote-tracking branch 'origin/master'

ct 1 месяц назад
Родитель
Сommit
1f91f5caaf

+ 91 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyVoiceCloneRefController.java

@@ -0,0 +1,91 @@
+package com.fs.company.controller.company;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.domain.CompanyVoiceCloneRef;
+import com.fs.company.service.ICompanyVoiceCloneService;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 音色关联 Controller
+ * <p>
+ * 数据权限:销售管理员可查看全公司数据,子账号仅可查看自己的数据(companyUserId)
+ * </p>
+ *
+ * @author fs
+ */
+@RestController
+@RequestMapping("/company/voiceCloneRef")
+public class CompanyVoiceCloneRefController extends BaseController {
+
+    @Autowired
+    private ICompanyVoiceCloneService companyVoiceCloneService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 分页查询音色关联列表
+     * <p>
+     * 数据权限隔离:
+     * - 销售管理员(userType=00/02):查看本公司所有数据
+     * - 子账号:仅查看 companyUserId = 自己 userId 的数据
+     * </p>
+     */
+    @PreAuthorize("@ss.hasPermi('company:voiceCloneRef:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CompanyVoiceCloneRef ref) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
+        ref.setCompanyId(loginUser.getCompany().getCompanyId());
+        // 非管理员仅看自己的数据
+        if (!CompanyUser.isAdmin(loginUser.getUser().getUserType())) {
+            ref.setCompanyUserId(loginUser.getUser().getUserId());
+        }
+
+        startPage();
+        return getDataTable(companyVoiceCloneService.selectRefList(ref));
+    }
+
+    /**
+     * 删除音色关联(仅管理员可操作)
+     */
+    @PreAuthorize("@ss.hasPermi('company:voiceCloneRef:remove')")
+    @DeleteMapping("/{id}")
+    public AjaxResult remove(@PathVariable Long id) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        if (!CompanyUser.isAdmin(loginUser.getUser().getUserType())) {
+            return AjaxResult.error("无删除权限,仅管理员可操作");
+        }
+        return toAjax(companyVoiceCloneService.deleteRefById(id));
+    }
+
+    /**
+     * 启用/禁用音色关联(仅管理员可操作)
+     */
+    @Log(title = "修改音色关联启用/禁用状态", businessType = BusinessType.UPDATE)
+    @PreAuthorize("@ss.hasPermi('company:voiceCloneRef:update')")
+    @PutMapping("/changeStatus")
+    public AjaxResult changeStatus(@RequestBody CompanyVoiceCloneRef ref) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        if (!CompanyUser.isAdmin(loginUser.getUser().getUserType())) {
+            return AjaxResult.error("无操作权限,仅管理员可操作");
+        }
+        return toAjax(companyVoiceCloneService.changeStatus(ref));
+    }
+}

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

@@ -89,6 +89,21 @@ public class CompanyVoiceRoboticController extends BaseController
         fillUserInfo(list);
         return getDataTable(list);
     }
+
+    /**
+     * 查询我的机器人外呼任务列表(所有人只看自己的)
+     */
+    @PreAuthorize("@ss.hasPermi('system:companyVoiceRobotic:list')")
+    @GetMapping("/myList")
+    public TableDataInfo myList(CompanyVoiceRobotic companyVoiceRobotic) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        companyVoiceRobotic.setCompanyId(loginUser.getCompany().getCompanyId());
+        companyVoiceRobotic.setCompanyUserId(loginUser.getUser().getUserId());
+        startPage();
+        List<CompanyVoiceRobotic> list = companyVoiceRoboticService.selectCompanyVoiceRoboticListCompany(companyVoiceRobotic);
+        fillUserInfo(list);
+        return getDataTable(list);
+    }
     /**
      * 查询机器人外呼任务列表
      */
@@ -138,6 +153,21 @@ public class CompanyVoiceRoboticController extends BaseController
         return util.exportExcel(list, "robotic");
     }
 
+    /**
+     * 导出我的机器人外呼任务列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:companyVoiceRobotic:export')")
+    @Log(title = "我的机器人外呼任务", businessType = BusinessType.EXPORT)
+    @GetMapping("/myExport")
+    public AjaxResult myExport(CompanyVoiceRobotic companyVoiceRobotic) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        companyVoiceRobotic.setCompanyId(loginUser.getCompany().getCompanyId());
+        companyVoiceRobotic.setCompanyUserId(loginUser.getUser().getUserId());
+        List<CompanyVoiceRobotic> list = companyVoiceRoboticService.selectCompanyVoiceRoboticListCompany(companyVoiceRobotic);
+        ExcelUtil<CompanyVoiceRobotic> util = new ExcelUtil<CompanyVoiceRobotic>(CompanyVoiceRobotic.class);
+        return util.exportExcel(list, "myRobotic");
+    }
+
     /**
      * 获取机器人外呼任务详细信息
      */

+ 5 - 3
fs-company/src/main/java/com/fs/company/controller/company/EasyCallController.java

@@ -7,6 +7,7 @@ import com.fs.aicall.service.ICompanyBindAiModelService;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.ServletUtils;
+import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyVoiceCloneRefMapper;
 import com.fs.company.service.easycall.IEasyCallService;
 import com.fs.company.vo.easycall.*;
@@ -99,13 +100,14 @@ public class EasyCallController extends BaseController {
     public R getVoiceCodeList() {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long companyId = loginUser.getUser().getCompanyId();
-
-        List<Long> ttsIds = companyVoiceCloneRefMapper.selectByCompanyIdAndCompanyUserId(companyId, loginUser.getCompany().getUserId());
+        // 管理员查全公司启用的音色关联,子账号仅查自己的
+        Long userId = CompanyUser.isAdmin(loginUser.getUser().getUserType()) ? null : loginUser.getUser().getUserId();
+        List<Long> ttsIds = companyVoiceCloneRefMapper.selectActiveTtsIds(companyId, userId);
         List<CcTtsAliyun> ccTtsAliyuns = companyVoiceCloneRefMapper.selectCcTtsAliyunList();
 
         List<EasyCallVoiceCodeVO> result = ccTtsAliyuns.stream()
                 .filter(item ->
-                        item.getPriority() == 1 || (item.getPriority() == 0 && ttsIds.contains(item.getId()))
+                        ttsIds.stream().anyMatch(id -> id.intValue() == item.getId())
                 )
                 .map(item -> {
                     EasyCallVoiceCodeVO vo = new EasyCallVoiceCodeVO();

+ 3 - 0
fs-service/src/main/java/com/fs/company/domain/CompanyVoiceCloneRef.java

@@ -25,6 +25,9 @@ public class CompanyVoiceCloneRef {
     /** 状态 */
     private Integer status;
 
+    /** 删除标志(0=正常,1=删除) */
+    private Integer delFlag;
+
     /** 创建人 */
     private String createBy;
 

+ 18 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyVoiceCloneRefMapper.java

@@ -21,11 +21,29 @@ public interface CompanyVoiceCloneRefMapper {
     List<Long> selectByCompanyIdAndCompanyUserId(@Param("companyId") Long companyId,
                                    @Param("companyUserId") Long companyUserId);
 
+    /**
+     * 查询公司下启用且未删除的音色关联 tts_id 列表
+     * @param companyId 公司ID(必填)
+     * @param companyUserId 用户ID(可选,为 null 时查全公司)
+     * @return tts_id 列表
+     */
+    List<Long> selectActiveTtsIds(@Param("companyId") Long companyId,
+                                  @Param("companyUserId") Long companyUserId);
+
 
     @DataSource(DataSourceType.EASYCALL)
     List<CcTtsAliyun> selectCcTtsAliyunList();
 
+    /**
+     * 分页查询公司音色关联列表
+     * @param ref 查询条件(companyId必填,companyUserId可选用于子账号过滤)
+     * @return 音色关联列表
+     */
+    List<CompanyVoiceCloneRef> selectCompanyVoiceCloneRefList(CompanyVoiceCloneRef ref);
+
+    int deleteById(@Param("id") Long id);
 
+    int updateStatusById(CompanyVoiceCloneRef ref);
 
 
 

+ 27 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyVoiceCloneService.java

@@ -1,8 +1,11 @@
 package com.fs.company.service;
 
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.company.domain.CompanyVoiceCloneRef;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 /**
  * 豆包声音克隆 Service 接口
  *
@@ -33,4 +36,28 @@ public interface ICompanyVoiceCloneService {
      * @return 操作结果(含 base64 音频数据)
      */
     AjaxResult doubaoTtsTest(String speakerId, Integer language, String text);
+
+    /**
+     * 分页查询音色关联列表
+     *
+     * @param ref 查询条件(companyId、companyUserId、voiceName、status)
+     * @return 音色关联列表
+     */
+    List<CompanyVoiceCloneRef> selectRefList(CompanyVoiceCloneRef ref);
+
+    /**
+     * 根据ID删除音色关联
+     *
+     * @param id 主键ID
+     * @return 删除行数
+     */
+    int deleteRefById(Long id);
+
+    /**
+     * 修改音色关联启用/禁用状态
+     *
+     * @param ref 包含 id 和 status
+     * @return 更新行数
+     */
+    int changeStatus(CompanyVoiceCloneRef ref);
 }

+ 17 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyVoiceCloneServiceImpl.java

@@ -20,6 +20,7 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.IOException;
 import java.util.Base64;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
@@ -400,6 +401,21 @@ public class CompanyVoiceCloneServiceImpl implements ICompanyVoiceCloneService {
                 .build();
     }
 
+    @Override
+    public List<CompanyVoiceCloneRef> selectRefList(CompanyVoiceCloneRef ref) {
+        return companyVoiceCloneRefMapper.selectCompanyVoiceCloneRefList(ref);
+    }
+
+    @Override
+    public int deleteRefById(Long id) {
+        return companyVoiceCloneRefMapper.deleteById(id);
+    }
+
+    @Override
+    public int changeStatus(CompanyVoiceCloneRef ref) {
+        return companyVoiceCloneRefMapper.updateStatusById(ref);
+    }
+
     private synchronized void addCompanyVoiceRelation(String code,String name,Long companyId, Integer ttsId,Long companyUserId) {
         if (companyId == null) {
             throw new RuntimeException("companyId为空,无法保存公司音色关联");
@@ -418,6 +434,7 @@ public class CompanyVoiceCloneServiceImpl implements ICompanyVoiceCloneService {
                 ref.setCompanyUserId(companyUserId);
                 ref.setTtsId(ttsId);
                 ref.setStatus(1);
+                ref.setDelFlag(0);
                 ref.setCreateBy("system");
                 ref.setUpdateBy("system");
                 companyVoiceCloneRefMapper.insertCompanyVoiceCloneRef(ref);

+ 4 - 0
fs-service/src/main/java/com/fs/crm/mapper/CrmCustomerMapper.java

@@ -1084,6 +1084,10 @@ public interface CrmCustomerMapper extends BaseMapper<CrmCustomer> {
             "<if test = 'maps.endTime != null and maps.endTime != \"\" '> " +
             "and date_format(c.create_time,'%y%m%d') &lt;= date_format(#{maps.endTime},'%y%m%d') " +
             "</if>" +
+            "<if test = 'maps.visitStatus != null and maps.visitStatus !=\"\"'> " +
+            "and c.visit_status IN " +
+            "<foreach collection=\"maps.visitStatus.split(',')\" item='item' index='index' open='(' separator=',' close=')'> #{item} </foreach>" +
+            "</if>" +
             " order by c.customer_id desc "+
             "</script>"})
     List<CrmCustomerAllListQueryVO> selectCrmCustomerAllListQuery(@Param("maps") CrmCustomerAllListQueryParam param);

+ 4 - 0
fs-service/src/main/java/com/fs/crm/param/CrmCustomerAllListQueryParam.java

@@ -60,4 +60,8 @@ public class CrmCustomerAllListQueryParam extends BaseQueryParam {
     private String intentionDegree;
 
     private String companyUserNickName;
+
+    /** 跟进阶段 */
+    private String visitStatus;
+
 }

+ 1 - 0
fs-service/src/main/resources/db/tenant-initTable.sql

@@ -18498,6 +18498,7 @@ CREATE TABLE `company_voice_clone_ref`
     `company_user_id` bigint NULL DEFAULT NULL COMMENT '销售id',
     `tts_id`          int     NOT NULL COMMENT '音色表id,对应cc_tts_aliyun.id',
     `status`          tinyint NOT NULL DEFAULT 1 COMMENT '状态:1启用,0禁用',
+    `del_flag`        tinyint NOT NULL DEFAULT 0 COMMENT '删除标志(0=正常,1=删除)',
     `create_by`       varchar(64)  NULL DEFAULT '' COMMENT '创建人',
     `create_time`     datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `update_by`       varchar(64) NULL DEFAULT '' COMMENT '更新人',

+ 41 - 1
fs-service/src/main/resources/mapper/company/CompanyVoiceCloneRefMapper.xml

@@ -12,6 +12,7 @@
         <result property="voiceCode" column="voice_code"/>
         <result property="ttsId" column="tts_id"/>
         <result property="status" column="status"/>
+        <result property="delFlag" column="del_flag"/>
         <result property="createBy" column="create_by"/>
         <result property="createTime" column="create_time"/>
         <result property="updateBy" column="update_by"/>
@@ -20,11 +21,13 @@
     </resultMap>
 
     <select id="selectByCompanyIdAndTtsId" resultMap="CompanyVoiceCloneRefResult">
-        select id,voice_name,voice_code, company_id,company_user_id, tts_id, status, create_by, create_time, update_by, update_time, remark
+        select id,voice_name,voice_code, company_id,company_user_id, tts_id, status, del_flag, create_by, create_time, update_by, update_time, remark
         from company_voice_clone_ref
         where company_id = #{companyId}
           and company_user_id = #{companyUserId}
           and tts_id = #{ttsId}
+          and del_flag = 0
+          and status = 1
             limit 1
     </select>
     <select id="selectByCompanyIdAndCompanyUserId" resultType="java.lang.Long">
@@ -32,9 +35,22 @@
         from company_voice_clone_ref
         where company_id = #{companyId}
           and company_user_id = #{companyUserId}
+          and del_flag = 0
+          and status = 1
             limit 1
     </select>
 
+    <select id="selectActiveTtsIds" resultType="java.lang.Long">
+        select tts_id
+        from company_voice_clone_ref
+        where company_id = #{companyId}
+        and del_flag = 0
+        and status = 1
+        <if test="companyUserId != null">
+            and company_user_id = #{companyUserId}
+        </if>
+    </select>
+
     <sql id="selectCcTtsAliyunVo">
         select id, voice_name, voice_code, voice_enabled, voice_source, priority, provider,tts_models from cc_tts_aliyun
     </sql>
@@ -64,6 +80,7 @@
             company_user_id,
             tts_id,
             status,
+            del_flag,
             create_by,
             create_time,
             update_by,
@@ -78,6 +95,7 @@
                 #{companyUserId},
                 #{ttsId},
                 #{status},
+                #{delFlag},
                 #{createBy},
                 now(),
                 #{updateBy},
@@ -97,4 +115,26 @@
         where id = #{id}
     </update>
 
+    <delete id="deleteById">
+        update company_voice_clone_ref set del_flag = 1, update_time = now() where id = #{id}
+    </delete>
+
+    <update id="updateStatusById" parameterType="com.fs.company.domain.CompanyVoiceCloneRef">
+        update company_voice_clone_ref set status = #{status}, update_time = now() where id = #{id}
+    </update>
+
+    <select id="selectCompanyVoiceCloneRefList" resultMap="CompanyVoiceCloneRefResult">
+        select id, voice_name, voice_code, company_id, company_user_id, tts_id,
+               status, del_flag, create_by, create_time, update_by, update_time, remark
+        from company_voice_clone_ref
+        <where>
+            del_flag = 0
+            <if test="companyId != null"> and company_id = #{companyId}</if>
+            <if test="companyUserId != null"> and company_user_id = #{companyUserId}</if>
+            <if test="voiceName != null and voiceName != ''"> and voice_name like concat('%', #{voiceName}, '%')</if>
+            <if test="status != null"> and status = #{status}</if>
+        </where>
+        order by id desc
+    </select>
+
 </mapper>

+ 1 - 0
fs-service/src/main/resources/mapper/company/CompanyVoiceRoboticMapper.xml

@@ -68,6 +68,7 @@
             a.del_flag = 0
             <if test="taskType != null "> and a.task_type = #{taskType} </if>
             <if test="companyId != null"> and a.company_id = #{companyId} </if>
+            <if test="companyUserId != null"> and a.company_user_id = #{companyUserId} </if>
             <if test="name != null  and name != ''"> and a.name like concat('%', #{name}, '%')</if>
             <if test="taskName != null  and taskName != ''"> and a.task_name like concat('%', #{taskName}, '%')</if>
             <if test="taskId != null "> and a.task_id = #{taskId}</if>