FsConfController.java 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585
  1. package com.ruoyi.cc.controller;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.ruoyi.aicall.domain.CcCallPhone;
  5. import com.ruoyi.aicall.service.ICcCallPhoneService;
  6. import com.ruoyi.cc.domain.CcInboundCdr;
  7. import com.ruoyi.cc.domain.CcOutboundCdr;
  8. import com.ruoyi.cc.model.FsConfProfile;
  9. import com.ruoyi.cc.model.FsMod;
  10. import com.ruoyi.cc.model.ProfileRegExtnumModel;
  11. import com.ruoyi.cc.model.ProfileStatusModel;
  12. import com.ruoyi.cc.service.*;
  13. import com.ruoyi.cc.utils.FsEslNameUtils;
  14. import com.ruoyi.common.core.controller.BaseController;
  15. import com.ruoyi.common.core.domain.AjaxResult;
  16. import com.ruoyi.common.core.page.TableDataInfo;
  17. import com.ruoyi.common.utils.CommonUtils;
  18. import com.ruoyi.common.utils.DateUtils;
  19. import com.ruoyi.common.utils.StringUtils;
  20. import link.thingscloud.freeswitch.esl.EslConnectionUtil;
  21. import link.thingscloud.freeswitch.esl.transport.message.EslMessage;
  22. import org.apache.shiro.authz.annotation.RequiresPermissions;
  23. import org.apache.shiro.authz.annotation.Logical;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.stereotype.Controller;
  26. import org.springframework.ui.ModelMap;
  27. import org.springframework.util.CollectionUtils;
  28. import org.springframework.web.bind.annotation.*;
  29. import org.w3c.dom.Document;
  30. import org.w3c.dom.Element;
  31. import org.w3c.dom.Node;
  32. import org.w3c.dom.NodeList;
  33. import org.xml.sax.InputSource;
  34. import javax.servlet.http.HttpServletResponse;
  35. import javax.xml.parsers.DocumentBuilder;
  36. import javax.xml.parsers.DocumentBuilderFactory;
  37. import java.io.IOException;
  38. import java.io.OutputStream;
  39. import java.io.StringReader;
  40. import java.net.URLEncoder;
  41. import java.nio.charset.StandardCharsets;
  42. import java.text.SimpleDateFormat;
  43. import java.util.ArrayList;
  44. import java.util.Date;
  45. import java.util.List;
  46. /**
  47. * freeswitch配置文件控制层
  48. */
  49. @Controller
  50. @RequestMapping("/cc/fsconf")
  51. public class FsConfController extends BaseController {
  52. @Autowired
  53. private IFsConfService fsConfService;
  54. @Autowired
  55. private IFsVariablesService fsVariablesService;
  56. @Autowired
  57. private ICcParamsService ccParamsService;
  58. @Autowired
  59. private ICcGatewaysService ccGatewaysService;
  60. @Autowired
  61. private ICcCallPhoneService callPhoneService;
  62. @Autowired
  63. private ICcInboundCdrService inboundCdrService;
  64. @Autowired
  65. private ICcOutboundCdrService outboundCdrService;
  66. /**
  67. * 系统全局配置
  68. * @return
  69. */
  70. @RequiresPermissions("cc:switchconf:view")
  71. @GetMapping(value = "/switchconf")
  72. public String switchConf() {
  73. return "cc/switchconf/switchconf";
  74. }
  75. /**
  76. * 保存系统全局配置
  77. * @param params
  78. * @return
  79. */
  80. @RequiresPermissions("cc:switchconf:view")
  81. @PostMapping(value = "/setSwitchConf")
  82. @ResponseBody
  83. public AjaxResult setSwitchConf(@RequestBody JSONArray params) {
  84. fsConfService.setSwitchConf(params);
  85. return AjaxResult.success("设置成功!");
  86. }
  87. /**
  88. * 重启fs服务
  89. * @return
  90. */
  91. @RequiresPermissions("cc:switchconf:view")
  92. @GetMapping(value = "/restartFs")
  93. @ResponseBody
  94. public AjaxResult restartFs() {
  95. String err = fsConfService.restartFs();
  96. if (StringUtils.isNotEmpty(err)) {
  97. return AjaxResult.error(err);
  98. }
  99. return AjaxResult.success("重启成功!");
  100. }
  101. /**
  102. * 获取系统全局配置
  103. * @return
  104. */
  105. @RequiresPermissions("cc:switchconf:view")
  106. @GetMapping(value = "/getSwitchConf")
  107. @ResponseBody
  108. public AjaxResult getSwitchConf() {
  109. // 配置文件所有配置
  110. JSONObject confAllVars = fsConfService.getSwitchConf();
  111. // 可配置的基本配置,其他的为隐藏的高级配置
  112. JSONObject fsVars = fsVariablesService.getFsVariablesByCat(2); // key: 参数名, value:别名
  113. JSONArray baseConfigs = new JSONArray();
  114. JSONArray advancedConfigs = new JSONArray();
  115. for (String name: confAllVars.keySet()) {
  116. JSONObject var = new JSONObject();
  117. var.put("name", name);
  118. var.put("value", confAllVars.getString(name));
  119. if (fsVars.keySet().contains(name)) {
  120. // 基本配置
  121. var.put("aliasName", fsVars.getString(name)); // 别名
  122. baseConfigs.add(var);
  123. } else {
  124. // 高级配置
  125. var.put("aliasName", name); // 高级配置没有别名
  126. advancedConfigs.add(var);
  127. }
  128. }
  129. JSONObject result = new JSONObject();
  130. result.put("baseConfigs", baseConfigs);
  131. result.put("advancedConfigs", advancedConfigs);
  132. return AjaxResult.success("success", result);
  133. }
  134. /**
  135. * 全局编码配置
  136. * @return
  137. */
  138. @RequiresPermissions("cc:varsconf:view")
  139. @GetMapping(value = "/varsconf")
  140. public String varsConf() {
  141. return "cc/varsconf/varsconf";
  142. }
  143. /**
  144. * 保存全局编码配置
  145. * @param params
  146. * @return
  147. */
  148. @RequiresPermissions("cc:varsconf:view")
  149. @PostMapping(value = "/setVarsConf")
  150. @ResponseBody
  151. public AjaxResult setVarsConf(@RequestBody JSONArray params) {
  152. fsConfService.setVarsConf(params);
  153. return AjaxResult.success("设置成功!");
  154. }
  155. /**
  156. * 获取全局编码配置
  157. * @return
  158. */
  159. @RequiresPermissions("cc:varsconf:view")
  160. @GetMapping(value = "/getVarsConf")
  161. @ResponseBody
  162. public AjaxResult getVarsConf() {
  163. // 配置文件所有配置
  164. JSONObject confAllVars = fsConfService.getVarsConf();
  165. // 可配置的基本配置,其他的为隐藏的高级配置(1. vars.xml 2. switch.conf.xml 3. profile 4. xunfei_asr 5. aliyun asr)
  166. JSONObject fsVars = fsVariablesService.getFsVariablesByCat(1); // key: 参数名, value:别名
  167. JSONArray baseConfigs = new JSONArray();
  168. JSONArray advancedConfigs = new JSONArray();
  169. for (String name: confAllVars.keySet()) {
  170. JSONObject var = new JSONObject();
  171. var.put("name", name);
  172. var.put("value", confAllVars.getString(name));
  173. if (fsVars.keySet().contains(name)) {
  174. // 基本配置
  175. var.put("aliasName", fsVars.getString(name)); // 别名
  176. baseConfigs.add(var);
  177. } else {
  178. // 高级配置
  179. var.put("aliasName", name); // 高级配置没有别名
  180. advancedConfigs.add(var);
  181. }
  182. }
  183. JSONObject result = new JSONObject();
  184. result.put("baseConfigs", baseConfigs);
  185. result.put("advancedConfigs", advancedConfigs);
  186. return AjaxResult.success("success", result);
  187. }
  188. /**
  189. * ASR(讯飞)参数配置
  190. * @return
  191. */
  192. @RequiresPermissions("cc:xunfeiasrconf:view")
  193. @GetMapping(value = "/xunfeiasrconf")
  194. public String xunfeiAsrConf() {
  195. return "cc/xunfeiasrconf/xunfeiasrconf";
  196. }
  197. /**
  198. * FunAsr参数配置
  199. * @return
  200. */
  201. @RequiresPermissions("cc:funasrconf:view")
  202. @GetMapping(value = "/funasrconf")
  203. public String funAsrConf() {
  204. return "cc/funasrconf/funasrconf";
  205. }
  206. /**
  207. * TTS(阿里)参数配置
  208. * @return
  209. */
  210. @RequiresPermissions("cc:alittsconf:view")
  211. @GetMapping(value = "/alittsconf")
  212. public String aliTtsConf() {
  213. return "cc/alittsconf/alittsconf";
  214. }
  215. /**
  216. * TTS(科大讯飞)参数配置
  217. * @return
  218. */
  219. @RequiresPermissions("cc:xfttsconf:view")
  220. @GetMapping(value = "/xfttsconf")
  221. public String xfTtsConf() {
  222. return "cc/xfttsconf/xfttsconf";
  223. }
  224. /**
  225. * TTS(腾讯云)参数配置
  226. * @return
  227. */
  228. @RequiresPermissions("cc:txtts1conf:view")
  229. @GetMapping(value = "/txtts1conf")
  230. public String txTts1Conf() {
  231. return "cc/txtts1conf/txtts1conf";
  232. }
  233. /**
  234. * TTS(ViiTorTTS)参数配置
  235. * @return
  236. */
  237. @RequiresPermissions("cc:vtttsconf:view")
  238. @GetMapping(value = "/vtttsconf")
  239. public String vtTtsConf() {
  240. return "cc/vtttsconf/vtttsconf";
  241. }
  242. /**
  243. * 获取阿里云tts配置
  244. * @return
  245. */
  246. @RequiresPermissions("cc:alittsconf:view")
  247. @GetMapping(value = "/getAliTtsConf")
  248. @ResponseBody
  249. public AjaxResult getAliTtsConf() {
  250. String asrFileName = "/autoload_configs/aliyun_tts.conf.xml";
  251. return getConfigFileJsonData(asrFileName, 5);
  252. }
  253. /**
  254. * 获取讯飞tts配置
  255. * @return
  256. */
  257. @RequiresPermissions("cc:xfttsconf:view")
  258. @GetMapping(value = "/getXfTtsConf")
  259. @ResponseBody
  260. public AjaxResult getXfTtsConf() {
  261. String asrFileName = "/autoload_configs/xf_tts.conf.xml";
  262. return getConfigFileJsonData(asrFileName, 5);
  263. }
  264. /**
  265. * 获取腾讯云tts配置
  266. * @return
  267. */
  268. @RequiresPermissions("cc:txtts1conf:view")
  269. @GetMapping(value = "/getTxTts1Conf")
  270. @ResponseBody
  271. public AjaxResult getTxTts1Conf() {
  272. String asrFileName = "/autoload_configs/tx_tts1.conf.xml";
  273. return getConfigFileJsonData(asrFileName, 5);
  274. }
  275. /**
  276. * 获取ViiTorTTS配置
  277. * @return
  278. */
  279. @RequiresPermissions("cc:vtttsconf:view")
  280. @GetMapping(value = "/getVtTtsConf")
  281. @ResponseBody
  282. public AjaxResult getVtTtsConf() {
  283. String asrFileName = "/autoload_configs/vt_tts.conf.xml";
  284. return getConfigFileJsonData(asrFileName, 5);
  285. }
  286. /**
  287. * 豆包tts 参数配置
  288. * @return
  289. */
  290. @RequiresPermissions("cc:doubaottsconf:view")
  291. @GetMapping(value = "/doubaottsconf")
  292. public String doubaoTtsConf() {
  293. return "cc/doubaottsconf/doubaottsconf";
  294. }
  295. /**
  296. * 获取豆包tts配置
  297. * @return
  298. */
  299. @RequiresPermissions("cc:doubaottsconf:view")
  300. @GetMapping(value = "/getDoubaoTtsConf")
  301. @ResponseBody
  302. public AjaxResult getDoubaoTtsConf() {
  303. String fileName = "/autoload_configs/doubao_vcl_tts.conf.xml";
  304. return getConfigFileJsonData(fileName, 5);
  305. }
  306. /**
  307. * 保存Doubao TTS配置
  308. * @param params
  309. * @return
  310. */
  311. @RequiresPermissions("cc:doubaottsconf:view")
  312. @PostMapping(value = "/setDoubaoTtsConf")
  313. @ResponseBody
  314. public AjaxResult setDoubaoTtsConf(@RequestBody JSONArray params) {
  315. String asrFileName = "/autoload_configs/doubao_vcl_tts.conf.xml";
  316. String moduleName = "mod_doubao_vcl_tts";
  317. AjaxResult result = saveAndReloadTtsModule("doubao-tts-account-json",
  318. asrFileName, moduleName, params);
  319. return result;
  320. }
  321. /**
  322. * ASR(阿里)参数配置
  323. * @return
  324. */
  325. @RequiresPermissions("cc:aliasrconf:view")
  326. @GetMapping(value = "/aliasrconf")
  327. public String aliAsrConf() {
  328. return "cc/aliasrconf/aliasrconf";
  329. }
  330. /**
  331. * ASR(阿里新模块)参数配置
  332. * @return
  333. */
  334. @RequiresPermissions("cc:aliasrbridgeconf:view")
  335. @GetMapping(value = "/aliasrbridgeconf")
  336. public String aliAsrBridgeConf() {
  337. return "cc/aliasrbridgeconf/aliasrbridgeconf";
  338. }
  339. /**
  340. * ASR(腾讯新模块)参数配置
  341. * @return
  342. */
  343. @RequiresPermissions("cc:txasrbridgeconf:view")
  344. @GetMapping(value = "/txasrbridgeconf")
  345. public String txAsrBridgeConf() {
  346. return "cc/txasrbridgeconf/txasrbridgeconf";
  347. }
  348. /**
  349. * ASR(腾讯MPS字幕模块)参数配置
  350. * @return
  351. */
  352. @RequiresPermissions("cc:txasr1bridgeconf:view")
  353. @GetMapping(value = "/txasr1bridgeconf")
  354. public String txAsr1BridgeConf() {
  355. return "cc/txasr1bridgeconf/txasr1bridgeconf";
  356. }
  357. /**
  358. * 获取ASR配置
  359. * @return
  360. */
  361. @RequiresPermissions("cc:aliasrconf:view")
  362. @GetMapping(value = "/getAliAsrConf")
  363. @ResponseBody
  364. public AjaxResult getAliAsrConf() {
  365. String asrFileName = "/autoload_configs/aliyun_asr.conf.xml";
  366. return getConfigFileJsonData(asrFileName, 5);
  367. }
  368. /**
  369. * 获取新 ASR 模块配置
  370. * @return
  371. */
  372. @RequiresPermissions("cc:aliasrbridgeconf:view")
  373. @GetMapping(value = "/getAliBridgeAsrConf")
  374. @ResponseBody
  375. public AjaxResult getAliBridgeAsrConf() {
  376. String asrFileName = "/autoload_configs/ali_asr.conf.xml";
  377. return getConfigFileJsonData(asrFileName, 5);
  378. }
  379. /**
  380. * 获取腾讯 ASR 模块配置
  381. * @return
  382. */
  383. @RequiresPermissions("cc:txasrbridgeconf:view")
  384. @GetMapping(value = "/getTxBridgeAsrConf")
  385. @ResponseBody
  386. public AjaxResult getTxBridgeAsrConf() {
  387. String asrFileName = "/autoload_configs/tx_asr.conf.xml";
  388. return getConfigFileJsonData(asrFileName, 5);
  389. }
  390. /**
  391. * 获取腾讯 ASR1 模块配置
  392. * @return
  393. */
  394. @RequiresPermissions("cc:txasr1bridgeconf:view")
  395. @GetMapping(value = "/getTxBridgeAsr1Conf")
  396. @ResponseBody
  397. public AjaxResult getTxBridgeAsr1Conf() {
  398. String asrFileName = "/autoload_configs/tx_asr1.conf.xml";
  399. return getConfigFileJsonData(asrFileName, 5);
  400. }
  401. /**
  402. * 获取FunASR配置
  403. * @return
  404. */
  405. @RequiresPermissions("cc:funasrconf:view")
  406. @GetMapping(value = "/getFunAsrConf")
  407. @ResponseBody
  408. public AjaxResult getFunAsrConf() {
  409. return getConfigFileJsonData("/autoload_configs/funasr.conf.xml", 4);
  410. }
  411. @RequiresPermissions("cc:aliasrconf:view")
  412. @GetMapping(value = "/chinatelecomasrconf")
  413. public String chinatelecomAsrConf() {
  414. return "cc/chinatelecomasrconf/chinatelecomasrconf";
  415. }
  416. @RequiresPermissions("cc:alittsconf:view")
  417. @GetMapping(value = "/chinatelecomttsconf")
  418. public String chinatelecomTtsConf() {
  419. return "cc/chinatelecomttsconf/chinatelecomttsconf";
  420. }
  421. @RequiresPermissions("cc:aliasrconf:view")
  422. @GetMapping(value = "/getChinatelecomAsrConf")
  423. @ResponseBody
  424. public AjaxResult getChinatelecomAsrConf() {
  425. String asrFileName = "/autoload_configs/chinatelecom_asr.conf.xml";
  426. return getConfigFileJsonData(asrFileName, 5);
  427. }
  428. @RequiresPermissions("cc:alittsconf:view")
  429. @GetMapping(value = "/getChinatelecomTtsConf")
  430. @ResponseBody
  431. public AjaxResult getChinatelecomTtsConf() {
  432. String fileName = "/autoload_configs/chinatelecom_tts.conf.xml";
  433. return getConfigFileJsonData(fileName, 5);
  434. }
  435. /**
  436. * 获取ASR配置
  437. * @return
  438. */
  439. @RequiresPermissions("cc:xunfeiasrconf:view")
  440. @GetMapping(value = "/getXunfeiAsrConf")
  441. @ResponseBody
  442. public AjaxResult getXunfeiAsrConf() {
  443. return getConfigFileJsonData("/autoload_configs/xunfei_asr.conf.xml", 4);
  444. }
  445. private AjaxResult getConfigFileJsonData(String configFile, int cat){
  446. JSONObject confAllVars = fsConfService.getAsrConf(configFile);
  447. if(confAllVars.size() != 0) {
  448. JSONObject fsVars = fsVariablesService.getFsVariablesByCat(cat); // key: 参数名, value:别名
  449. JSONArray baseConfigs = new JSONArray();
  450. for (String name : confAllVars.keySet()) {
  451. JSONObject var = new JSONObject();
  452. var.put("name", name);
  453. boolean hidden = fsConfService.checkNeedHidden(name);
  454. // server_url_webapi不需要加密
  455. if ("server_url_webapi".equals(name)) {
  456. hidden = false;
  457. }
  458. if(hidden){
  459. var.put("value", CommonUtils.maskStringUtil(confAllVars.getString(name)));
  460. }else {
  461. var.put("value", confAllVars.getString(name));
  462. }
  463. if (fsVars.keySet().contains(name)) {
  464. // 基本配置
  465. var.put("aliasName", fsVars.getString(name)); // 别名
  466. baseConfigs.add(var);
  467. } else {
  468. // 高级配置
  469. var.put("aliasName", name); // 高级配置没有别名
  470. baseConfigs.add(var);
  471. }
  472. }
  473. return AjaxResult.success("success", baseConfigs);
  474. }else{
  475. return AjaxResult.error(String.format("config file not found: %s", configFile));
  476. }
  477. }
  478. private AjaxResult saveAndReloadAsrModule(String asrFileName, String moduleName, JSONArray params, String asrProvider){
  479. String result = fsConfService.setAsrConf(params, asrFileName);
  480. if(StringUtils.isEmpty(result)) {
  481. result = fsConfService.ensureAsrengineLoaded(moduleName);
  482. if (!StringUtils.isEmpty(result)) {
  483. return AjaxResult.error(result);
  484. }
  485. // 更新cc_params参数表
  486. ccParamsService.updateParamsValue("sys-asr-provider", asrProvider);
  487. String reloadRsp = ccParamsService.reloadParams();
  488. if(!reloadRsp.equalsIgnoreCase("success")){
  489. return error("参数修改成功, 但是刷新失败, 请手动重启 call-center!");
  490. }
  491. AjaxResult loadResult = loadOrReloadAsrModule(moduleName);
  492. if (loadResult.isSuccess()) {
  493. return AjaxResult.success("配置写入成功!\n 模块已成功加载!");
  494. }
  495. return AjaxResult.error("配置写入成功!\n 但是模块加载失败! \n" + loadResult.get("msg"));
  496. }else{
  497. return AjaxResult.error("配置文件写入失败!\n " + result);
  498. }
  499. }
  500. private String asrProviderByModule(String asrengine) {
  501. if (StringUtils.isEmpty(asrengine)) {
  502. return "";
  503. }
  504. switch (asrengine.trim()) {
  505. case "mod_xunfei_asr":
  506. return "xunfeiasr";
  507. case "mod_aliyun_asr":
  508. return "aliyun";
  509. case "mod_ali_asr":
  510. return "ali";
  511. case "mod_tx_asr":
  512. return "tx";
  513. case "mod_tx_asr1":
  514. return "tx1";
  515. case "mod_chinatelecom_asr":
  516. return "chinatelecom";
  517. case "mod_funasr":
  518. return "funasr";
  519. default:
  520. return "";
  521. }
  522. }
  523. private AjaxResult loadOrReloadAsrModule(String moduleName) {
  524. EslMessage resp = EslConnectionUtil.sendSyncApiCommand("reload", moduleName.trim());
  525. String text = CommonUtils.ListToString(resp.getBodyLines(), '\n');
  526. if(text.contains("+OK")) {
  527. return AjaxResult.success("设置成功!");
  528. }
  529. resp = EslConnectionUtil.sendSyncApiCommand("load", moduleName.trim());
  530. text = CommonUtils.ListToString(resp.getBodyLines(), '\n');
  531. if(text.contains("+OK")) {
  532. return AjaxResult.success("设置成功!");
  533. }
  534. return AjaxResult.error("设置失败!\n " + text);
  535. }
  536. private AjaxResult saveAndReloadTtsModule(String paramCode, String asrFileName, String moduleName, JSONArray params){
  537. String result = fsConfService.setAsrConf(params, asrFileName);
  538. if(StringUtils.isEmpty(result)) {
  539. if (StringUtils.isNotEmpty(paramCode)) {
  540. String ttsAccountJson = ccParamsService.getParamValueByCode(paramCode, "{}");
  541. logger.info("修改前的tts账号信息");
  542. JSONObject paramValues = JSONObject.parseObject(ttsAccountJson);
  543. for (int j = 0; j < params.size(); j++) {
  544. JSONObject param = params.getJSONObject(j);
  545. String attrName = param.getString("name");
  546. String attValue = param.getString("value");
  547. // 包含星号的参数值不更新
  548. if (!attValue.contains("****")) {
  549. paramValues.put(attrName, attValue);
  550. }
  551. }
  552. ccParamsService.updateParamsValue(paramCode, JSONObject.toJSONString(paramValues));
  553. String reloadRsp = ccParamsService.reloadParams();
  554. if(!reloadRsp.equalsIgnoreCase("success")){
  555. return error("参数修改成功, 但是刷新失败, 请手动重启 call-center!");
  556. }
  557. }
  558. EslMessage resp = EslConnectionUtil.sendSyncApiCommand("reload", moduleName);
  559. String respText = CommonUtils.ListToString(resp.getBodyLines());
  560. if(respText.contains("OK module loaded")) {
  561. return AjaxResult.success("配置写入成功!\n 模块已成功加载!");
  562. }else{
  563. return AjaxResult.error("配置写入成功!\n 但是模块加载失败! \n" + respText);
  564. }
  565. }else{
  566. return AjaxResult.error("配置文件写入失败!\n " + result);
  567. }
  568. }
  569. /**
  570. * 保存ASR配置
  571. * @param params
  572. * @return
  573. */
  574. @RequiresPermissions("cc:aliasrconf:view")
  575. @PostMapping(value = "/setAliAsrConf")
  576. @ResponseBody
  577. public AjaxResult setAliAsrConf(@RequestBody JSONArray params) {
  578. String asrFileName = "/autoload_configs/aliyun_asr.conf.xml";
  579. String moduleName = "mod_aliyun_asr";
  580. return saveAndReloadAsrModule(asrFileName, moduleName, params, "aliyun");
  581. }
  582. /**
  583. * 保存新 ASR 模块配置
  584. * @param params
  585. * @return
  586. */
  587. @RequiresPermissions("cc:aliasrbridgeconf:view")
  588. @PostMapping(value = "/setAliBridgeAsrConf")
  589. @ResponseBody
  590. public AjaxResult setAliBridgeAsrConf(@RequestBody JSONArray params) {
  591. String asrFileName = "/autoload_configs/ali_asr.conf.xml";
  592. String moduleName = "mod_ali_asr";
  593. return saveAndReloadAsrModule(asrFileName, moduleName, params, "ali");
  594. }
  595. /**
  596. * 保存腾讯 ASR 模块配置
  597. * @param params
  598. * @return
  599. */
  600. @RequiresPermissions("cc:txasrbridgeconf:view")
  601. @PostMapping(value = "/setTxBridgeAsrConf")
  602. @ResponseBody
  603. public AjaxResult setTxBridgeAsrConf(@RequestBody JSONArray params) {
  604. String asrFileName = "/autoload_configs/tx_asr.conf.xml";
  605. String moduleName = "mod_tx_asr";
  606. return saveAndReloadAsrModule(asrFileName, moduleName, params, "tx");
  607. }
  608. /**
  609. * 保存腾讯 ASR1 模块配置
  610. * @param params
  611. * @return
  612. */
  613. @RequiresPermissions("cc:txasr1bridgeconf:view")
  614. @PostMapping(value = "/setTxBridgeAsr1Conf")
  615. @ResponseBody
  616. public AjaxResult setTxBridgeAsr1Conf(@RequestBody JSONArray params) {
  617. String asrFileName = "/autoload_configs/tx_asr1.conf.xml";
  618. String moduleName = "mod_tx_asr1";
  619. return saveAndReloadAsrModule(asrFileName, moduleName, params, "tx1");
  620. }
  621. /**
  622. * 保存ASR配置
  623. * @param params
  624. * @return
  625. */
  626. @RequiresPermissions("cc:aliasrconf:view")
  627. @PostMapping(value = "/setChinatelecomAsrConf")
  628. @ResponseBody
  629. public AjaxResult setChinatelecomAsrConf(@RequestBody JSONArray params) {
  630. String asrFileName = "/autoload_configs/chinatelecom_asr.conf.xml";
  631. String moduleName = "mod_chinatelecom_asr";
  632. return saveAndReloadAsrModule(asrFileName, moduleName, params, "chinatelecom");
  633. }
  634. /**
  635. * 保存TTS配置
  636. * @param params
  637. * @return
  638. */
  639. @RequiresPermissions("cc:alittsconf:view")
  640. @PostMapping(value = "/setAliTtsConf")
  641. @ResponseBody
  642. public AjaxResult setAliTtsConf(@RequestBody JSONArray params) {
  643. String asrFileName = "/autoload_configs/aliyun_tts.conf.xml";
  644. String moduleName = "mod_aliyun_tts";
  645. AjaxResult result = saveAndReloadTtsModule("aliyun-tts-account-json",
  646. asrFileName, moduleName, params);
  647. return result;
  648. }
  649. /**
  650. * 保存讯飞TTS配置
  651. * @param params
  652. * @return
  653. */
  654. @RequiresPermissions("cc:xfttsconf:view")
  655. @PostMapping(value = "/setXfTtsConf")
  656. @ResponseBody
  657. public AjaxResult setXfTtsConf(@RequestBody JSONArray params) {
  658. String asrFileName = "/autoload_configs/xf_tts.conf.xml";
  659. String moduleName = "mod_xf_tts";
  660. AjaxResult result = saveAndReloadTtsModule("", asrFileName, moduleName, params);
  661. return result;
  662. }
  663. /**
  664. * 保存腾讯云TTS配置
  665. * @param params
  666. * @return
  667. */
  668. @RequiresPermissions("cc:txtts1conf:view")
  669. @PostMapping(value = "/setTxTts1Conf")
  670. @ResponseBody
  671. public AjaxResult setTxTts1Conf(@RequestBody JSONArray params) {
  672. String asrFileName = "/autoload_configs/tx_tts1.conf.xml";
  673. String moduleName = "mod_tx_tts1";
  674. AjaxResult result = saveAndReloadTtsModule("tx-tts1-account-json", asrFileName, moduleName, params);
  675. return result;
  676. }
  677. /**
  678. * 保存ViiTorTTS配置
  679. * @param params
  680. * @return
  681. */
  682. @RequiresPermissions("cc:vtttsconf:view")
  683. @PostMapping(value = "/setVtTtsConf")
  684. @ResponseBody
  685. public AjaxResult setVtTtsConf(@RequestBody JSONArray params) {
  686. String asrFileName = "/autoload_configs/vt_tts.conf.xml";
  687. String moduleName = "mod_vt_tts";
  688. AjaxResult result = saveAndReloadTtsModule("vt-tts-account-json", asrFileName, moduleName, params);
  689. return result;
  690. }
  691. /**
  692. * 保存TTS配置
  693. * @param params
  694. * @return
  695. */
  696. @RequiresPermissions("cc:alittsconf:view")
  697. @PostMapping(value = "/setChinatelecomTtsConf")
  698. @ResponseBody
  699. public AjaxResult setChinatelecomTtsConf(@RequestBody JSONArray params) {
  700. String asrFileName = "/autoload_configs/chinatelecom_tts.conf.xml";
  701. String moduleName = "mod_chinatelecom_tts";
  702. AjaxResult result = saveAndReloadTtsModule("", asrFileName, moduleName, params);
  703. return result;
  704. }
  705. /**
  706. * 保存ASR配置
  707. * @param params
  708. * @return
  709. */
  710. @RequiresPermissions("cc:xunfeiasrconf:view")
  711. @PostMapping(value = "/setXunfeiAsrConf")
  712. @ResponseBody
  713. public AjaxResult setXunfeiAsrConf(@RequestBody JSONArray params) {
  714. String asrFileName = "/autoload_configs/xunfei_asr.conf.xml";
  715. String moduleName = "mod_xunfei_asr";
  716. return saveAndReloadAsrModule(asrFileName, moduleName, params, "xunfeiasr");
  717. }
  718. /**
  719. * 保存FunASR配置
  720. * @param params
  721. * @return
  722. */
  723. @RequiresPermissions("cc:funasrconf:view")
  724. @PostMapping(value = "/setFunAsrConf")
  725. @ResponseBody
  726. public AjaxResult setFunAsrConf(@RequestBody JSONArray params) {
  727. String asrFileName = "/autoload_configs/funasr.conf.xml";
  728. String moduleName = "mod_funasr";
  729. return saveAndReloadAsrModule(asrFileName, moduleName, params, "funasr");
  730. }
  731. /**
  732. * ASR引擎设置
  733. * @return
  734. */
  735. @RequiresPermissions("cc:asrengine:view")
  736. @GetMapping(value = "/asrengine")
  737. public String asrengine(ModelMap mmap) {
  738. String asrEngine = fsConfService.getAsrengine();
  739. FsMod mod = new FsMod();
  740. mod.setModName("asrEngine");
  741. mod.setModValue(asrEngine);
  742. mmap.put("mod", mod);
  743. return "cc/asrengine/asrengine";
  744. }
  745. /**
  746. * 设置ASR引擎(mod_xunfei_asr、mod_aliyun_asr、mod_ali_asr、mod_tx_asr、mod_tx_asr1)
  747. * @param asrengine
  748. * @return
  749. */
  750. @RequiresPermissions("cc:asrengine:view")
  751. @GetMapping(value = "/setAsrengine")
  752. @ResponseBody
  753. public AjaxResult setAsrengine(@RequestParam String asrengine) {
  754. String result = fsConfService.setAsrengine(asrengine);
  755. if(StringUtils.isEmpty(result)){
  756. if (StringUtils.isNotEmpty(asrengine)) {
  757. String asrProvider = asrProviderByModule(asrengine);
  758. if (StringUtils.isNotEmpty(asrProvider)) {
  759. ccParamsService.updateParamsValue("fs_call_asr_engine", asrProvider);
  760. ccParamsService.updateParamsValue("sys-asr-provider", asrProvider);
  761. String reloadRsp = ccParamsService.reloadParams();
  762. if(!reloadRsp.equalsIgnoreCase("success")){
  763. return error("参数修改成功, 但是刷新失败, 请手动重启 call-center!");
  764. }
  765. }
  766. return loadOrReloadAsrModule(asrengine);
  767. }else{
  768. return AjaxResult.error("参数错误!");
  769. }
  770. }else {
  771. return AjaxResult.error(result);
  772. }
  773. }
  774. /**
  775. * 证书配置
  776. * @return
  777. */
  778. @RequiresPermissions("cc:certwsspen:view")
  779. @GetMapping(value = "/certwsspen")
  780. public String certWssPen() {
  781. return "cc/certwsspen/certwsspen";
  782. }
  783. /**
  784. * 获取证书配置
  785. * @return
  786. */
  787. @RequiresPermissions("cc:certwsspen:view")
  788. @GetMapping(value = "/getCertWssPen")
  789. @ResponseBody
  790. public AjaxResult getCertWssPen() {
  791. JSONObject result = new JSONObject();
  792. result.put("certValue", fsConfService.getCertWssPen());
  793. return AjaxResult.success("success", result);
  794. }
  795. /**
  796. * 保存证书配置
  797. * @param params
  798. * @return
  799. */
  800. @RequiresPermissions("cc:certwsspen:view")
  801. @PostMapping(value = "/setCertWssPen")
  802. @ResponseBody
  803. public AjaxResult setCertWssPen(@RequestBody JSONObject params) {
  804. fsConfService.setCertWssPen(params.getString("certValue"));
  805. return AjaxResult.success("设置成功!");
  806. }
  807. /**
  808. * 授权配置
  809. * @return
  810. */
  811. @RequiresPermissions("cc:licenseconf:view")
  812. @GetMapping(value = "/licenseconf")
  813. public String licenseconf() {
  814. if (!getSysUser().isAdmin()) {
  815. return "error/unauth";
  816. }
  817. return "cc/licenseconf/licenseconf";
  818. }
  819. /**
  820. * 获取授权配置(仅超级管理员)
  821. * @return
  822. */
  823. @GetMapping(value = "/getLicenseConf")
  824. @ResponseBody
  825. public AjaxResult getLicenseConf() {
  826. if (!getSysUser().isAdmin()) {
  827. return AjaxResult.error("权限不足");
  828. }
  829. JSONObject result = new JSONObject();
  830. result.put("fingerprintValue", fsConfService.getFingerprintValue());
  831. result.put("licenseValue", fsConfService.getLicenseValue());
  832. result.put("licenseInfo", fsConfService.getLicenseInfo());
  833. return AjaxResult.success("success", result);
  834. }
  835. /**
  836. * 保存授权配置(仅超级管理员)
  837. * @param params
  838. * @return
  839. */
  840. @PostMapping(value = "/setLicenseConf")
  841. @ResponseBody
  842. public AjaxResult setLicenseConf(@RequestBody JSONObject params) {
  843. if (!getSysUser().isAdmin()) {
  844. return AjaxResult.error("权限不足");
  845. }
  846. fsConfService.setLicenseConf(params.getString("licenseValue"));
  847. return AjaxResult.success("设置成功!");
  848. }
  849. /**
  850. * 日志监控
  851. * @return
  852. */
  853. @RequiresPermissions("cc:catlogs:view")
  854. @GetMapping(value = "/catlogs")
  855. public String catLogs(ModelMap mmap) {
  856. String ccLogFiles = ccParamsService.getParamValueByCode("cc_log_file_path", "");
  857. String errorLogFiles = ccLogFiles.replace("easycallcenter365.log", "easycallcenter365-ERROR.log");
  858. String errorLogs = fsConfService.getLogs("", errorLogFiles, "error");
  859. mmap.put("errorLogs", errorLogs);
  860. return "cc/catlogs/catlogs";
  861. }
  862. /**
  863. * 获取日志
  864. * @return
  865. */
  866. @RequiresPermissions("cc:catlogs:view")
  867. @GetMapping(value = "/getLogs")
  868. @ResponseBody
  869. public AjaxResult getLogs(@RequestParam String uuid) {
  870. if (StringUtils.isBlank(uuid) || uuid.length() <= 10) {
  871. return AjaxResult.error("请输入正确的uuid");
  872. }
  873. uuid = uuid.trim();
  874. if (!FsEslNameUtils.isSafeLogQueryId(uuid)) {
  875. return AjaxResult.error("请输入正确的uuid");
  876. }
  877. JSONObject result = new JSONObject();
  878. // result.put("fsLogs", "这是freeswitch日志:\r\n19:21:38.255 [schedule-pool-3] INFO c.r.f.s.w.s.OnlineWebSessionManager - [validateSessions,100] - invalidation sessions...\r\n19:21:38.281 [schedule-pool-3] DEBUG c.r.s.m.S.selectOnlineByExpired - [debug,135] - ==> Preparing: select sessionId, login_name, dept_name, ipaddr, login_location, browser, os, status, start_timestamp, last_access_time, expire_time from sys_user_online o WHERE o.last_access_time <= ? ORDER BY o.last_access_time ASC\r\n19:21:38.283 [schedule-pool-3] DEBUG c.r.s.m.S.selectOnlineByExpired - [debug,135] - ==> Parameters: 2024-12-22 18:51:38(String)\r\n19:21:38.312 [schedule-pool-3] DEBUG c.r.s.m.S.selectOnlineByExpired - [debug,135] - <== Total: 0\r\n19:21:38.313 [schedule-pool-3] INFO c.r.f.s.w.s.OnlineWebSessionManager - [validateSessions,165] - Finished invalidation session. No sessions were stopped.\r\n");
  879. // result.put("ccLogs", "这是callcenter日志:\r\n19:21:38.255 [schedule-pool-3] INFO c.r.f.s.w.s.OnlineWebSessionManager - [validateSessions,100] - invalidation sessions...\r\n19:21:38.281 [schedule-pool-3] DEBUG c.r.s.m.S.selectOnlineByExpired - [debug,135] - ==> Preparing: select sessionId, login_name, dept_name, ipaddr, login_location, browser, os, status, start_timestamp, last_access_time, expire_time from sys_user_online o WHERE o.last_access_time <= ? ORDER BY o.last_access_time ASC\r\n19:21:38.283 [schedule-pool-3] DEBUG c.r.s.m.S.selectOnlineByExpired - [debug,135] - ==> Parameters: 2024-12-22 18:51:38(String)\r\n19:21:38.312 [schedule-pool-3] DEBUG c.r.s.m.S.selectOnlineByExpired - [debug,135] - <== Total: 0\r\n19:21:38.313 [schedule-pool-3] INFO c.r.f.s.w.s.OnlineWebSessionManager - [validateSessions,165] - Finished invalidation session. No sessions were stopped.\r\n");
  880. String fsLogFiles = ccParamsService.getParamValueByCode("fs_log_file_path", "");
  881. String fsLogs = fsConfService.getLogs(uuid, fsLogFiles, "cc");
  882. result.put("fsLogs", fsLogs); // freeswitch日志
  883. String ccLogFiles = ccParamsService.getParamValueByCode("cc_log_file_path", "");
  884. String ccLogs = fsConfService.getLogs(uuid, ccLogFiles, "cc");
  885. if (StringUtils.isNotEmpty(fsLogs)
  886. && StringUtils.isBlank(ccLogs)) {
  887. // String ccHisLogFiles = ccLogFiles.replace(".log", ".*.log");
  888. // logger.info(ccHisLogFiles);
  889. // ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  890. List<CcCallPhone> callPhoneList = callPhoneService.selectCcCallPhoneList(new CcCallPhone().setUuid(uuid));
  891. if (!CollectionUtils.isEmpty(callPhoneList)) {
  892. String date = DateUtils.parseDateToStr("yyyy-MM-dd", new Date(callPhoneList.get(0).getCalloutTime()));
  893. String ccHisLogFiles = ccLogFiles.replace(".log", "." + date + ".0.log");
  894. logger.info(ccHisLogFiles);
  895. ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  896. } else {
  897. List<CcInboundCdr> inboundCdrList = inboundCdrService.selectCcInboundCdrList(new CcInboundCdr().setUuid(uuid));
  898. if (!CollectionUtils.isEmpty(inboundCdrList)) {
  899. String date = DateUtils.parseDateToStr("yyyy-MM-dd", new Date(inboundCdrList.get(0).getInboundTime()));
  900. String ccHisLogFiles = ccLogFiles.replace(".log", "." + date + ".0.log");
  901. logger.info(ccHisLogFiles);
  902. ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  903. } else {
  904. List<CcOutboundCdr> outboundCdrList = outboundCdrService.selectCcOutboundCdrList(new CcOutboundCdr().setUuid(uuid));
  905. if (!CollectionUtils.isEmpty(outboundCdrList)) {
  906. String date = DateUtils.parseDateToStr("yyyy-MM-dd", new Date(outboundCdrList.get(0).getStartTime()));
  907. String ccHisLogFiles = ccLogFiles.replace(".log", "." + date + ".0.log");
  908. logger.info(ccHisLogFiles);
  909. ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  910. }
  911. }
  912. }
  913. }
  914. result.put("ccLogs", ccLogs); // callcenter日志
  915. return AjaxResult.success("success", result);
  916. }
  917. /**
  918. * 获取日志
  919. * @return
  920. */
  921. @RequiresPermissions("cc:catlogs:view")
  922. @GetMapping(value = "/downloadLogs")
  923. @ResponseBody
  924. public void downloadLogs(@RequestParam String uuid, HttpServletResponse response) {
  925. if (StringUtils.isBlank(uuid) || uuid.length() <= 10) {
  926. try {
  927. response.setContentType("application/json;charset=UTF-8");
  928. response.getWriter().write("{\"code\":500,\"msg\":\"请输入正确的uuid\"}");
  929. } catch (IOException e) {
  930. logger.error("写入错误响应失败", e);
  931. }
  932. return;
  933. }
  934. uuid = uuid.trim();
  935. if (!FsEslNameUtils.isSafeLogQueryId(uuid)) {
  936. try {
  937. response.setContentType("application/json;charset=UTF-8");
  938. response.getWriter().write("{\"code\":500,\"msg\":\"请输入正确的uuid\"}");
  939. } catch (IOException e) {
  940. logger.error("写入错误响应失败", e);
  941. }
  942. return;
  943. }
  944. // 获取日志内容
  945. String fsLogFiles = ccParamsService.getParamValueByCode("fs_log_file_path", "");
  946. String fsLogs = fsConfService.getLogs(uuid, fsLogFiles, "cc");
  947. String ccLogFiles = ccParamsService.getParamValueByCode("cc_log_file_path", "");
  948. String ccLogs = fsConfService.getLogs(uuid, ccLogFiles, "cc");
  949. if (StringUtils.isNotEmpty(fsLogs)
  950. && StringUtils.isBlank(ccLogs)) {
  951. // String ccHisLogFiles = ccLogFiles.replace(".log", ".*.log");
  952. // logger.info(ccHisLogFiles);
  953. // ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  954. List<CcCallPhone> callPhoneList = callPhoneService.selectCcCallPhoneList(new CcCallPhone().setUuid(uuid));
  955. if (!CollectionUtils.isEmpty(callPhoneList)) {
  956. String date = DateUtils.parseDateToStr("yyyy-MM-dd", new Date(callPhoneList.get(0).getCalloutTime()));
  957. String ccHisLogFiles = ccLogFiles.replace(".log", "." + date + ".0.log");
  958. logger.info(ccHisLogFiles);
  959. ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  960. } else {
  961. List<CcInboundCdr> inboundCdrList = inboundCdrService.selectCcInboundCdrList(new CcInboundCdr().setUuid(uuid));
  962. if (!CollectionUtils.isEmpty(inboundCdrList)) {
  963. String date = DateUtils.parseDateToStr("yyyy-MM-dd", new Date(inboundCdrList.get(0).getInboundTime()));
  964. String ccHisLogFiles = ccLogFiles.replace(".log", "." + date + ".0.log");
  965. logger.info(ccHisLogFiles);
  966. ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  967. } else {
  968. List<CcOutboundCdr> outboundCdrList = outboundCdrService.selectCcOutboundCdrList(new CcOutboundCdr().setUuid(uuid));
  969. if (!CollectionUtils.isEmpty(outboundCdrList)) {
  970. String date = DateUtils.parseDateToStr("yyyy-MM-dd", new Date(outboundCdrList.get(0).getStartTime()));
  971. String ccHisLogFiles = ccLogFiles.replace(".log", "." + date + ".0.log");
  972. logger.info(ccHisLogFiles);
  973. ccLogs = fsConfService.getLogs(uuid, ccHisLogFiles, "cc");
  974. }
  975. }
  976. }
  977. }
  978. String errorLogFiles = ccLogFiles.replace("easycallcenter365.log", "easycallcenter365-ERROR.log");
  979. String errorLogs = fsConfService.getLogs("", errorLogFiles, "error");
  980. // 生成TXT文件内容
  981. StringBuilder fileContent = new StringBuilder();
  982. fileContent.append("========================================\n");
  983. fileContent.append("UUID: ").append(uuid).append("\n");
  984. fileContent.append("下载时间: ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append("\n");
  985. fileContent.append("========================================\n\n");
  986. fileContent.append("【FreeSwitch 日志】\n");
  987. fileContent.append("========================================\n");
  988. fileContent.append(StringUtils.isNotBlank(fsLogs) ? fsLogs : "无日志内容\n");
  989. fileContent.append("\n\n");
  990. fileContent.append("【CallCenter 日志】\n");
  991. fileContent.append("========================================\n");
  992. fileContent.append(StringUtils.isNotBlank(ccLogs) ? ccLogs : "无日志内容\n");
  993. fileContent.append("【Error 日志】\n");
  994. fileContent.append("========================================\n");
  995. fileContent.append(StringUtils.isNotBlank(errorLogs) ? errorLogs : "无日志内容\n");
  996. fileContent.append("\n\n");
  997. // 设置响应头,实现浏览器下载
  998. String fileName = "logs_" + uuid + "_" + System.currentTimeMillis() + ".txt";
  999. try {
  1000. response.setContentType("text/plain;charset=UTF-8");
  1001. response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
  1002. response.setHeader("Cache-Control", "no-cache");
  1003. response.setContentLength(fileContent.toString().getBytes(StandardCharsets.UTF_8).length);
  1004. // 写入文件内容
  1005. try (OutputStream out = response.getOutputStream()) {
  1006. out.write(fileContent.toString().getBytes(StandardCharsets.UTF_8));
  1007. out.flush();
  1008. }
  1009. } catch (IOException e) {
  1010. logger.error("下载日志文件失败", e);
  1011. }
  1012. }
  1013. @RequiresPermissions("cc:profileconf:view")
  1014. @GetMapping("/profileconf")
  1015. public String profile()
  1016. {
  1017. ccGatewaysService.refreshGatewaysFiles();
  1018. return "cc/profileconf/profileconf";
  1019. }
  1020. @RequiresPermissions("cc:profileconf:add")
  1021. @GetMapping("/profileconf/add/{profileType}")
  1022. public String addProfile(@PathVariable("profileType") String profileType, ModelMap mmap)
  1023. {
  1024. mmap.put("profileType", profileType);
  1025. return "cc/profileconf/add";
  1026. }
  1027. @RequiresPermissions("cc:profileconf:edit")
  1028. @GetMapping("/profileconf/edit/{profileName}")
  1029. public String editProfile(@PathVariable("profileName") String profileName, ModelMap mmap)
  1030. {
  1031. mmap.put("profileName", profileName);
  1032. return "cc/profileconf/edit";
  1033. }
  1034. /**
  1035. * 查询分机管理列表
  1036. */
  1037. @RequiresPermissions("cc:profileconf:list")
  1038. @PostMapping("/profileList")
  1039. @ResponseBody
  1040. public TableDataInfo profileList()
  1041. {
  1042. startPage();
  1043. List<FsConfProfile> list = fsConfService.selectProfileList();
  1044. return getDataTable(list);
  1045. }
  1046. /**
  1047. * 保存 profile 配置
  1048. */
  1049. @RequiresPermissions(value = {"cc:profileconf:add", "cc:profileconf:edit"}, logical = Logical.OR)
  1050. @PostMapping(value = "/setProfileConf")
  1051. @ResponseBody
  1052. public AjaxResult setProfileConf(@RequestBody JSONArray params) {
  1053. String profileName = "";
  1054. String profileType = "";
  1055. String operaType = "";
  1056. JSONArray xmlParams = new JSONArray();
  1057. for (int i = 0; i < params.size(); i++) {
  1058. JSONObject param = params.getJSONObject(i);
  1059. // 不需要写入文件的属性
  1060. if ("_profileType".equals(param.getString("name"))) {
  1061. profileType = param.getString("value");
  1062. continue;
  1063. }
  1064. if ("_operaType".equals(param.getString("name"))) {
  1065. operaType = param.getString("value");
  1066. continue;
  1067. }
  1068. // 需要写入文件的属性
  1069. if ("profileName".equals(param.getString("name"))) {
  1070. profileName = param.getString("value");
  1071. }
  1072. xmlParams.add(param);
  1073. }
  1074. logger.info("profileName:" + profileName);
  1075. logger.info("profileType:" + profileType);
  1076. logger.info("operaType:" + operaType);
  1077. if (!FsEslNameUtils.isSafeName(profileName)) {
  1078. return AjaxResult.error("profileName参数不合法");
  1079. }
  1080. if (StringUtils.isNotEmpty(profileType) && !FsEslNameUtils.isSafeName(profileType)) {
  1081. return AjaxResult.error("profileType参数不合法");
  1082. }
  1083. String saveSuccess = fsConfService.setProfileConf(profileName, profileType, xmlParams);
  1084. if(!StringUtils.isEmpty(saveSuccess)){
  1085. return AjaxResult.error(saveSuccess);
  1086. }
  1087. if ("add".equals(operaType)) {
  1088. // 新增后启动
  1089. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "profile " + profileName + " start");
  1090. if (null != eslMessage) {
  1091. logger.info(StringUtils.joinWith("/r/n", eslMessage.getBodyLines().toArray()));
  1092. }
  1093. } else if ("edit".equals(operaType)) {
  1094. // 修改后重启
  1095. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "profile " + profileName + " restart");
  1096. if (null != eslMessage) {
  1097. logger.info(StringUtils.joinWith("/r/n", eslMessage.getBodyLines().toArray()));
  1098. }
  1099. }
  1100. return AjaxResult.success("设置成功!");
  1101. }
  1102. @RequiresPermissions(value = {"cc:profileconf:view", "cc:profileconf:add", "cc:profileconf:edit"}, logical = Logical.OR)
  1103. @GetMapping(value = "/getProfileConf")
  1104. @ResponseBody
  1105. public AjaxResult getProfileConf(@RequestParam(required = false) String profileName, @RequestParam(required = false) String profileType) {
  1106. // 配置文件所有配置
  1107. JSONObject confAllVars = fsConfService.getProfileConf(profileName, profileType);
  1108. // 可配置的基本配置,其他的为隐藏的高级配置
  1109. JSONObject fsVars = fsVariablesService.getFsVariablesByCat(3); // key: 参数名, value:别名
  1110. JSONArray baseConfigs = new JSONArray();
  1111. JSONArray advancedConfigs = new JSONArray();
  1112. for (String name: confAllVars.keySet()) {
  1113. JSONObject var = new JSONObject();
  1114. var.put("name", name);
  1115. var.put("value", confAllVars.getString(name));
  1116. if (fsVars.keySet().contains(name)) {
  1117. // 基本配置
  1118. var.put("aliasName", fsVars.getString(name)); // 别名
  1119. baseConfigs.add(var);
  1120. } else {
  1121. // 高级配置
  1122. var.put("aliasName", name); // 高级配置没有别名
  1123. advancedConfigs.add(var);
  1124. }
  1125. }
  1126. JSONObject result = new JSONObject();
  1127. result.put("baseConfigs", baseConfigs);
  1128. result.put("advancedConfigs", advancedConfigs);
  1129. return AjaxResult.success("success", result);
  1130. }
  1131. @RequiresPermissions("cc:profileconf:status")
  1132. @GetMapping(value = "/getProfileStatus")
  1133. @ResponseBody
  1134. public AjaxResult getProfileStatus(@RequestParam String profileName) {
  1135. if (!FsEslNameUtils.isSafeName(profileName)) {
  1136. return AjaxResult.error("profileName参数不合法");
  1137. }
  1138. JSONObject result = new JSONObject();
  1139. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "xmlstatus");
  1140. if (null != eslMessage) {
  1141. logger.info(StringUtils.joinWith("\r\n", eslMessage.getBodyLines().toArray()));
  1142. List<ProfileStatusModel> list = convertProfileStatusXml(StringUtils.joinWith("", eslMessage.getBodyLines().toArray()));
  1143. logger.info(JSONObject.toJSONString(list));
  1144. result.put("data", list);
  1145. } else {
  1146. result.put("msg", "系统错误");
  1147. }
  1148. return AjaxResult.success("success", result);
  1149. }
  1150. /**
  1151. * profileStatus格式转换
  1152. * @param xml
  1153. * @return
  1154. */
  1155. private List<ProfileStatusModel> convertProfileStatusXml(String xml) {
  1156. List<ProfileStatusModel> list = new ArrayList<>();
  1157. try {
  1158. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  1159. DocumentBuilder builder = factory.newDocumentBuilder();
  1160. InputSource is = new InputSource(new StringReader(xml));
  1161. Document doc = builder.parse(is);
  1162. // 根节点
  1163. Node profiles = doc.getDocumentElement();
  1164. // 下层数据节点(profile、gateway、alias等)
  1165. NodeList children = profiles.getChildNodes();
  1166. for (int i = 0; i < children.getLength(); i++) {
  1167. // 比如profile节点
  1168. Node child = children.item(i);
  1169. if (child.getNodeType() == Node.ELEMENT_NODE) {
  1170. Element element = (Element) children.item(i);
  1171. Node name = element.getElementsByTagName("name").item(0);
  1172. Node type = element.getElementsByTagName("type").item(0);
  1173. Node data = element.getElementsByTagName("data").item(0);
  1174. Node state = element.getElementsByTagName("state").item(0);
  1175. ProfileStatusModel model = new ProfileStatusModel();
  1176. if (null != name && StringUtils.isNotEmpty(name.getTextContent())) {
  1177. model.setName(name.getTextContent().trim());
  1178. }
  1179. if (null != type && StringUtils.isNotEmpty(type.getTextContent())) {
  1180. model.setType(type.getTextContent().trim());
  1181. }
  1182. if (null != data && StringUtils.isNotEmpty(data.getTextContent())) {
  1183. model.setData(data.getTextContent().trim());
  1184. }
  1185. if (null != state && StringUtils.isNotEmpty(state.getTextContent())) {
  1186. model.setState(state.getTextContent().trim());
  1187. }
  1188. list.add(model);
  1189. }
  1190. }
  1191. } catch (Exception e) {
  1192. e.printStackTrace();
  1193. }
  1194. return list;
  1195. }
  1196. @RequiresPermissions("cc:profileconf:start")
  1197. @GetMapping(value = "/startProfile")
  1198. @ResponseBody
  1199. public AjaxResult startProfile(@RequestParam String profileName) {
  1200. if (!FsEslNameUtils.isSafeName(profileName)) {
  1201. return AjaxResult.error("profileName参数不合法");
  1202. }
  1203. JSONObject result = new JSONObject();
  1204. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "profile " + profileName + " start");
  1205. if (null != eslMessage) {
  1206. result.put("msg", eslMessage.getBodyLines());
  1207. } else {
  1208. result.put("msg", "系统错误");
  1209. }
  1210. return AjaxResult.success("success", result);
  1211. }
  1212. @RequiresPermissions("cc:profileconf:stop")
  1213. @GetMapping(value = "/stopProfile")
  1214. @ResponseBody
  1215. public AjaxResult stopProfile(@RequestParam String profileName) {
  1216. if (!FsEslNameUtils.isSafeName(profileName)) {
  1217. return AjaxResult.error("profileName参数不合法");
  1218. }
  1219. JSONObject result = new JSONObject();
  1220. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "profile " + profileName + " stop");
  1221. if (null != eslMessage) {
  1222. result.put("msg", eslMessage.getBodyLines());
  1223. } else {
  1224. result.put("msg", "系统错误");
  1225. }
  1226. return AjaxResult.success("success", result);
  1227. }
  1228. @RequiresPermissions("cc:profileconf:restart")
  1229. @GetMapping(value = "/restartProfile")
  1230. @ResponseBody
  1231. public AjaxResult restartProfile(@RequestParam String profileName) {
  1232. if (!FsEslNameUtils.isSafeName(profileName)) {
  1233. return AjaxResult.error("profileName参数不合法");
  1234. }
  1235. JSONObject result = new JSONObject();
  1236. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "profile " + profileName + " restart");
  1237. if (null != eslMessage) {
  1238. result.put("msg", eslMessage.getBodyLines());
  1239. } else {
  1240. result.put("msg", "系统错误");
  1241. }
  1242. return AjaxResult.success("success", result);
  1243. }
  1244. @RequiresPermissions("cc:profileconf:status")
  1245. @GetMapping(value = "/getExtnumList")
  1246. @ResponseBody
  1247. public AjaxResult getExtnumList(@RequestParam String profileName) {
  1248. if (!FsEslNameUtils.isSafeName(profileName)) {
  1249. return AjaxResult.error("profileName参数不合法");
  1250. }
  1251. JSONObject result = new JSONObject();
  1252. EslMessage eslMessage = EslConnectionUtil.sendSyncApiCommand("sofia", "xmlstatus profile " + profileName + " reg");
  1253. if (null != eslMessage) {
  1254. logger.info(StringUtils.joinWith("\r\n", eslMessage.getBodyLines().toArray()));
  1255. List<ProfileRegExtnumModel> list = convertProfileRegExtnumXml(StringUtils.joinWith("", eslMessage.getBodyLines().toArray()));
  1256. logger.info(JSONObject.toJSONString(list));
  1257. result.put("data", list);
  1258. } else {
  1259. result.put("msg", "系统错误");
  1260. }
  1261. return AjaxResult.success("success", result);
  1262. }
  1263. private List<ProfileRegExtnumModel> convertProfileRegExtnumXml(String xml) {
  1264. List<ProfileRegExtnumModel> list = new ArrayList<>();
  1265. try {
  1266. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  1267. DocumentBuilder builder = factory.newDocumentBuilder();
  1268. InputSource is = new InputSource(new StringReader(xml));
  1269. Document doc = builder.parse(is);
  1270. NodeList children = doc.getElementsByTagName("registration");
  1271. for (int i = 0; i < children.getLength(); i++) {
  1272. // 比如profile节点
  1273. Node child = children.item(i);
  1274. if (child.getNodeType() == Node.ELEMENT_NODE) {
  1275. Element element = (Element) children.item(i);
  1276. Node user = element.getElementsByTagName("user").item(0);
  1277. Node networkIp = element.getElementsByTagName("network-ip").item(0);
  1278. Node networkPort = element.getElementsByTagName("network-port").item(0);
  1279. Node status = element.getElementsByTagName("status").item(0);
  1280. Node agent = element.getElementsByTagName("agent").item(0);
  1281. ProfileRegExtnumModel model = new ProfileRegExtnumModel();
  1282. if (null != user && StringUtils.isNotEmpty(user.getTextContent())) {
  1283. model.setUser(user.getTextContent().trim().split("@")[0]);
  1284. }
  1285. if (null != networkIp && StringUtils.isNotEmpty(networkIp.getTextContent())) {
  1286. model.setNetworkIp(networkIp.getTextContent().trim());
  1287. }
  1288. if (null != networkPort && StringUtils.isNotEmpty(networkPort.getTextContent())) {
  1289. model.setNetworkPort(networkPort.getTextContent().trim());
  1290. }
  1291. if (null != status && StringUtils.isNotEmpty(status.getTextContent())) {
  1292. model.setStatus(status.getTextContent().trim());
  1293. }
  1294. if (null != agent && StringUtils.isNotEmpty(agent.getTextContent())) {
  1295. String agentValue = agent.getTextContent().trim();
  1296. if (agentValue.length() > 16) {
  1297. agentValue = agentValue.substring(0, 14) + "...";
  1298. }
  1299. model.setAgent(agentValue);
  1300. }
  1301. list.add(model);
  1302. }
  1303. }
  1304. } catch (Exception e) {
  1305. e.printStackTrace();
  1306. }
  1307. return list;
  1308. }
  1309. /**
  1310. * ASR(亚马逊)参数配置
  1311. * @return
  1312. */
  1313. @RequiresPermissions("cc:awsasrconf:view")
  1314. @GetMapping(value = "/awsasrconf")
  1315. public String awsAsrConf() {
  1316. return "cc/awsasrconf/awsasrconf";
  1317. }
  1318. /**
  1319. * 获取亚马逊ASR配置
  1320. * @return
  1321. */
  1322. @RequiresPermissions("cc:awsasrconf:view")
  1323. @GetMapping(value = "/getAwsAsrConf")
  1324. @ResponseBody
  1325. public AjaxResult getAwsAsrConf() {
  1326. String asrFileName = "/autoload_configs/aws_asr.conf.xml";
  1327. return getConfigFileJsonData(asrFileName, 5);
  1328. }
  1329. /**
  1330. * 保存ASR配置
  1331. * @param params
  1332. * @return
  1333. */
  1334. @RequiresPermissions("cc:awsasrconf:view")
  1335. @PostMapping(value = "/setAwsAsrConf")
  1336. @ResponseBody
  1337. public AjaxResult setAwsAsrConf(@RequestBody JSONArray params) {
  1338. String asrFileName = "/autoload_configs/aws_asr.conf.xml";
  1339. String moduleName = "mod_aws_asr";
  1340. return saveAndReloadAsrModule(asrFileName, moduleName, params, "aws");
  1341. }
  1342. /**
  1343. * TTS(亚马逊)参数配置
  1344. * @return
  1345. */
  1346. @RequiresPermissions("cc:awsttsconf:view")
  1347. @GetMapping(value = "/awsttsconf")
  1348. public String awsTtsConf() {
  1349. return "cc/awsttsconf/awsttsconf";
  1350. }
  1351. /**
  1352. * 获取亚马逊tts配置
  1353. * @return
  1354. */
  1355. @RequiresPermissions("cc:awsttsconf:view")
  1356. @GetMapping(value = "/getAwsTtsConf")
  1357. @ResponseBody
  1358. public AjaxResult getAwsTtsConf() {
  1359. String ttsFileName = "/autoload_configs/aws_tts.conf.xml";
  1360. return getConfigFileJsonData(ttsFileName, 5);
  1361. }
  1362. /**
  1363. * 保存TTS配置
  1364. * @param params
  1365. * @return
  1366. */
  1367. @RequiresPermissions("cc:awsttsconf:view")
  1368. @PostMapping(value = "/setAwsTtsConf")
  1369. @ResponseBody
  1370. public AjaxResult setAwsTtsConf(@RequestBody JSONArray params) {
  1371. String asrFileName = "/autoload_configs/aws_tts.conf.xml";
  1372. String moduleName = "mod_aws_tts";
  1373. AjaxResult result = saveAndReloadTtsModule("aws-tts-account-json",
  1374. asrFileName, moduleName, params);
  1375. return result;
  1376. }
  1377. /**
  1378. * ASR(deepgram)参数配置
  1379. * @return
  1380. */
  1381. @RequiresPermissions("cc:deepgramasrconf:view")
  1382. @GetMapping(value = "/deepgramasrconf")
  1383. public String deepgramAsrConf() {
  1384. return "cc/deepgramasrconf/deepgramasrconf";
  1385. }
  1386. /**
  1387. * 获取Deepgram ASR配置
  1388. * @return
  1389. */
  1390. @RequiresPermissions("cc:deepgramasrconf:view")
  1391. @GetMapping(value = "/getDeepgramAsrConf")
  1392. @ResponseBody
  1393. public AjaxResult getDeepgramAsrConf() {
  1394. String asrFileName = "/autoload_configs/deepgram_asr.conf.xml";
  1395. return getConfigFileJsonData(asrFileName, 5);
  1396. }
  1397. /**
  1398. * 保存ASR配置
  1399. * @param params
  1400. * @return
  1401. */
  1402. @RequiresPermissions("cc:deepgramasrconf:view")
  1403. @PostMapping(value = "/setDeepgramAsrConf")
  1404. @ResponseBody
  1405. public AjaxResult setDeepgramAsrConf(@RequestBody JSONArray params) {
  1406. String asrFileName = "/autoload_configs/deepgram_asr.conf.xml";
  1407. String moduleName = "mod_deepgram_asr";
  1408. return saveAndReloadAsrModule(asrFileName, moduleName, params, "deepgram");
  1409. }
  1410. /**
  1411. * TTS(deepgram)参数配置
  1412. * @return
  1413. */
  1414. @RequiresPermissions("cc:deepgramttsconf:view")
  1415. @GetMapping(value = "/deepgramttsconf")
  1416. public String deepgramTtsConf() {
  1417. return "cc/deepgramttsconf/deepgramttsconf";
  1418. }
  1419. /**
  1420. * 获取deepgram tts配置
  1421. * @return
  1422. */
  1423. @RequiresPermissions("cc:deepgramttsconf:view")
  1424. @GetMapping(value = "/getDeepgramTtsConf")
  1425. @ResponseBody
  1426. public AjaxResult getDeepgramTtsConf() {
  1427. String ttsFileName = "/autoload_configs/deepgram_tts.conf.xml";
  1428. return getConfigFileJsonData(ttsFileName, 5);
  1429. }
  1430. /**
  1431. * 保存TTS配置
  1432. * @param params
  1433. * @return
  1434. */
  1435. @RequiresPermissions("cc:deepgramttsconf:view")
  1436. @PostMapping(value = "/setDeepgramTtsConf")
  1437. @ResponseBody
  1438. public AjaxResult setDeepgramTtsConf(@RequestBody JSONArray params) {
  1439. String asrFileName = "/autoload_configs/deepgram_tts.conf.xml";
  1440. String moduleName = "mod_deepgram_tts";
  1441. AjaxResult result = saveAndReloadTtsModule("deepgram-tts-account-json",
  1442. asrFileName, moduleName, params);
  1443. return result;
  1444. }
  1445. }