Sfoglia il codice sorgente

update 销售端添加语音录制

ct 1 mese fa
parent
commit
79248aec57

+ 78 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java

@@ -21,14 +21,17 @@ import com.fs.company.domain.*;
 import com.fs.company.param.CompanyUserAreaParam;
 import com.fs.company.param.CompanyUserCodeParam;
 import com.fs.company.param.CompanyUserQwParam;
+import com.fs.company.param.companyUserAddPrintParam;
 import com.fs.company.service.*;
 import com.fs.company.service.impl.CompanyDeptServiceImpl;
 import com.fs.company.utils.DomainUtil;
 import com.fs.company.utils.QwStatusEnum;
 import com.fs.company.vo.*;
+import com.fs.config.ai.AiHostProper;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.config.saas.ProjectConfig;
 import com.fs.course.config.CourseConfig;
+import com.fs.fastgptApi.util.AudioUtils;
 import com.fs.framework.datasource.DynamicDataSourceContextHolder;
 import com.fs.framework.datasource.TenantDataSourceManager;
 import com.fs.framework.security.LoginUser;
@@ -46,8 +49,11 @@ import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
+import com.fs.sop.service.IQwSopTempVoiceService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
 import com.fs.system.service.ISysConfigService;
 import com.fs.tenant.domain.TenantInfo;
 import com.fs.tenant.mapper.TenantInfoMapper;
@@ -65,6 +71,8 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.FileInputStream;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
@@ -963,4 +971,74 @@ public class CompanyUserController extends BaseController {
         List<com.fs.hisStore.domain.FsUserScrm> userList = companyUserService.selectBoundFsUsersByCompanyUserId(companyUserId);
         return R.ok().put("data", userList);
     }
+
+    @ApiOperation("上传声纹")
+    @PostMapping("/addVoicePrintUrl")
+    public R addVoicePrintUrl(@RequestBody companyUserAddPrintParam param) throws Exception {
+        Long userId = param.getCompanyUserId();
+        if (userId == null) {
+            try {
+                userId = getUserId();
+            } catch (Exception e) {
+                return R.error("用户失效");
+            }
+        }
+        if (userId == null) {
+            return R.error("用户失效");
+        }
+        if (StringUtils.isEmpty(param.getVoicePrintUrl())) {
+            return R.error("声纹地址不能为空");
+        }
+        CompanyUser companyUser = new CompanyUser();
+        companyUser.setUserId(userId);
+        companyUser.setVoicePrintUrl(param.getVoicePrintUrl());
+
+        //转换音频格式 mp3-wav
+        String s = AudioUtils.audioWAVFromUrl(param.getVoicePrintUrl());
+        if (StringUtils.isEmpty(s)) {
+            return R.error("音频转换失败,请检查 ffmpeg 是否可用及 c:\\hook 目录是否存在");
+        }
+        File file = new File(s);
+        if (!file.isFile()) {
+            return R.error("音频转换失败,未生成 wav 文件: " + s);
+        }
+
+        //保存文件并且上传存储桶
+        FileInputStream fileInputStream = new FileInputStream(file);
+        CloudStorageService storage = OSSFactory.build();
+        String wavUrl = storage.uploadSuffix(fileInputStream, ".wav");
+
+        //更新销售员工声纹
+        companyUser.setVoicePrintUrl(wavUrl);
+        companyUserService.updateCompanyUser(companyUser);
+
+//        try {
+//            CloseableHttpClient httpClient = HttpClients.createDefault();
+//            HttpPost httpPost = new HttpPost(aiHostProper.getCommonApi()+"/app/common/addCompanyAudio");
+//            String json = "{\"url\":\""+wavUrl+"\",\"id\":\""+userId+"\"}";
+//            StringEntity entity = new StringEntity(json);
+//            httpPost.setEntity(entity);
+//            httpPost.setHeader("Content-type", "application/json");
+//            HttpResponse response = httpClient.execute(httpPost);
+//
+//            if (response.getStatusLine().getStatusCode() == 200) {
+//                String responseBody = EntityUtils.toString(response.getEntity());
+//                com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(responseBody);
+//                Integer code = (Integer)jsonObject.get("code");
+//                if (code==200){
+//                    voiceService.insertQwSopTempVoiceModel(userId);
+//                    return R.ok();
+//                }
+//            } else {
+//                return R.error();
+//            }
+//
+//            httpClient.close();
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+
+        return R.ok();
+
+    }
 }

+ 20 - 5
fs-service/src/main/java/com/fs/fastgptApi/util/AudioUtils.java

@@ -44,10 +44,25 @@ public class AudioUtils {
     }
 
     /**
-     * 工具地址
+     * 工具地址(历史部署默认 c:\ffmpeg.exe)
      **/
     static String path = "c:\\";
     static String destinationDir = "c:\\hook\\";
+
+    /**
+     * 解析 ffmpeg 可执行文件:优先环境变量 FFMPEG_PATH,其次 c:\ffmpeg.exe,最后使用 PATH 中的 ffmpeg。
+     */
+    private static String resolveFfmpegExecutable() {
+        String envPath = System.getenv("FFMPEG_PATH");
+        if (envPath != null && !envPath.trim().isEmpty()) {
+            return envPath.trim();
+        }
+        File legacy = new File(path + "ffmpeg.exe");
+        if (legacy.isFile()) {
+            return legacy.getAbsolutePath();
+        }
+        return "ffmpeg";
+    }
     public static AudioVO createVoiceUrl(Long id,String userVoiceUrl){
         String fileUrl = staticAiHostProper.getVoiceApi() + "/app/common/createVoiceUrl?id=" + id + "&userVoiceUrl=" + userVoiceUrl;
 
@@ -232,7 +247,7 @@ public class AudioUtils {
             String WAVPath = destinationDir + "WAV_" + time + ".wav";
             // 构建FFmpeg命令
             String[] command = {
-                    path + "ffmpeg.exe",
+                    resolveFfmpegExecutable(),
                     "-i", audioFilePath,WAVPath
             };
             log.info(command[2]);
@@ -254,7 +269,7 @@ public class AudioUtils {
             // 构建FFmpeg命令
             String[] command = {
                     "cmd", "/c", "start", "/b",
-                    path + "ffmpeg.exe",
+                    resolveFfmpegExecutable(),
                     "-i", audioFilePath
             };
             // 启动进程执行命令
@@ -518,7 +533,7 @@ public class AudioUtils {
         commend.add("/c");
         commend.add("start");
         commend.add("/b");
-        commend.add(path + "ffmpeg.exe");
+        commend.add(resolveFfmpegExecutable());
         commend.add("-y");
         commend.add("-i");
         commend.add(fpath);
@@ -550,7 +565,7 @@ public class AudioUtils {
         Process process = null;
         try {
             List<String> command = new ArrayList<String>();
-            command.add(path + "ffmpeg.exe");
+            command.add(resolveFfmpegExecutable());
             command.add("-y");
             command.add("-i");
             command.add(fpath);

+ 9 - 2
fs-service/src/main/java/com/fs/system/oss/OSSFactory.java

@@ -1,6 +1,8 @@
 package com.fs.system.oss;
 
 import com.alibaba.fastjson.JSON;
+import com.fs.common.exception.ServiceException;
+import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.system.service.ISysConfigService;
 
@@ -19,8 +21,13 @@ public final class OSSFactory
     public static CloudStorageService build()
     {
         String jsonconfig = sysConfigService.selectConfigByKey(CloudConstant.CLOUD_STORAGE_CONFIG_KEY);
-        // 获取云存储配置信息
+        if (StringUtils.isEmpty(jsonconfig)) {
+            throw new ServiceException("云存储未配置,请在系统参数中配置 key=" + CloudConstant.CLOUD_STORAGE_CONFIG_KEY);
+        }
         CloudStorageConfig config = JSON.parseObject(jsonconfig, CloudStorageConfig.class);
+        if (config == null || config.getType() == null) {
+            throw new ServiceException("云存储配置解析失败,请检查 " + CloudConstant.CLOUD_STORAGE_CONFIG_KEY + " 的 JSON 格式");
+        }
         if (config.getType() == CloudConstant.CloudService.QINIU.getValue())
         {
             return new QiniuCloudStorageService(config);
@@ -37,6 +44,6 @@ public final class OSSFactory
         {
             return new HuaweiCloudStorageService(config);
         }
-        return null;
+        throw new ServiceException("不支持的云存储类型: " + config.getType());
     }
 }