ApiController.java 84 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935
  1. package com.ruoyi.aicall.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.domain.CcCallTask;
  6. import com.ruoyi.aicall.domain.CcLlmAgentAccount;
  7. import com.ruoyi.aicall.domain.CcTtsAliyun;
  8. import com.ruoyi.aicall.model.*;
  9. import com.ruoyi.aicall.service.ICcCallPhoneService;
  10. import com.ruoyi.aicall.service.ICcCallTaskService;
  11. import com.ruoyi.aicall.service.ICcLlmAgentAccountService;
  12. import com.ruoyi.aicall.service.ICcTtsAliyunService;
  13. import com.ruoyi.aicall.utils.ClientIpCheck;
  14. import com.ruoyi.aicall.utils.DESUtil;
  15. import com.ruoyi.cc.domain.*;
  16. import com.ruoyi.cc.service.*;
  17. import com.ruoyi.cc.utils.DateValidatorUtils;
  18. import com.ruoyi.common.core.controller.BaseController;
  19. import com.ruoyi.common.core.domain.AjaxResult;
  20. import com.ruoyi.common.core.domain.entity.SysUser;
  21. import com.ruoyi.common.core.page.TableDataInfo;
  22. import com.ruoyi.common.utils.CommonUtils;
  23. import com.ruoyi.common.utils.DateUtils;
  24. import com.ruoyi.common.utils.ShiroUtils;
  25. import com.ruoyi.common.utils.StringUtils;
  26. import com.ruoyi.common.utils.bean.BeanUtils;
  27. import com.ruoyi.common.utils.uuid.UuidGenerator;
  28. import com.ruoyi.framework.shiro.service.SysPasswordService;
  29. import com.ruoyi.framework.shiro.util.AuthorizationUtils;
  30. import com.ruoyi.system.service.ISysUserService;
  31. import lombok.extern.slf4j.Slf4j;
  32. import org.apache.commons.lang3.RandomUtils;
  33. import org.springframework.beans.factory.annotation.Autowired;
  34. import org.springframework.stereotype.Controller;
  35. import org.springframework.transaction.annotation.Transactional;
  36. import org.springframework.util.CollectionUtils;
  37. import org.springframework.web.bind.annotation.*;
  38. import javax.servlet.http.HttpServletRequest;
  39. import java.io.UnsupportedEncodingException;
  40. import java.net.URLDecoder;
  41. import java.net.URLEncoder;
  42. import java.util.*;
  43. import java.util.stream.Collectors;
  44. @Controller
  45. @Slf4j
  46. @RequestMapping("/aicall/api")
  47. public class ApiController extends BaseController {
  48. @Autowired
  49. private ICcCallTaskService callTaskService;
  50. @Autowired
  51. private ICcCallPhoneService ccCallPhoneService;
  52. @Autowired
  53. private ICcInboundCdrService inboundCdrService;
  54. @Autowired
  55. private ICcOutboundCdrService outboundCdrService;
  56. @Autowired
  57. private ICcParamsService paramsService;
  58. @Autowired
  59. private ICcGatewaysService ccGatewaysService;
  60. @Autowired
  61. private ICcLlmAgentAccountService ccLlmAgentAccountService;
  62. @Autowired
  63. private ICcBizGroupService ccBizGroupService;
  64. @Autowired
  65. private ICcCallTaskService ccCallTaskService;
  66. @Autowired
  67. private ICcTtsAliyunService ccTtsAliyunService;
  68. @Autowired
  69. private ICcExtNumService ccExtNumService;
  70. @Autowired
  71. private ICcParamsService ccParamsService;
  72. @Autowired
  73. private ISysUserService userService;
  74. @Autowired
  75. private SysPasswordService passwordService;
  76. @Autowired
  77. private ICcCustCallRecordService ccCustCallRecordService;
  78. @Autowired
  79. private ICcCustInfoService ccCustInfoService;
  80. @Autowired
  81. private ISysDivisionDataService sysDivisionDataService;
  82. @Autowired
  83. private ICcOutboundCdrService ccOutboundCdrService;
  84. /**
  85. * 获取外呼网关列表接口
  86. * @param req
  87. * @return
  88. */
  89. @GetMapping("/gateway/list")
  90. @ResponseBody
  91. public AjaxResult getGatewayList(HttpServletRequest req, @RequestParam(value = "purposes", required = false) String purposes){
  92. // 校验客户端ip是否在白名单内
  93. if (!ClientIpCheck.checkIp(req)) {
  94. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单!", "");
  95. }
  96. // 获取外呼网关列表
  97. Map<String, Object> params = new HashMap<>();
  98. if (StringUtils.isBlank(purposes)) {
  99. params.put("purposes", Arrays.asList(1,2,3));
  100. } else {
  101. params.put("purposes", Arrays.asList(purposes.split(",")));
  102. }
  103. List<CcGateways> list = ccGatewaysService.selectCcGatewaysList(new CcGateways().setParams(params));
  104. List<ApiGatewaysModel> result = new ArrayList<>();
  105. for (CcGateways data: list) {
  106. ApiGatewaysModel model = new ApiGatewaysModel();
  107. BeanUtils.copyProperties(data, model);
  108. result.add(model);
  109. }
  110. return AjaxResult.success(result);
  111. }
  112. /**
  113. * 获取大模型列表接口
  114. * @param req
  115. * @return
  116. */
  117. @GetMapping("/llmacount/list")
  118. @ResponseBody
  119. public AjaxResult getLlmAcountList(HttpServletRequest req){
  120. // 校验客户端ip是否在白名单内
  121. if (!ClientIpCheck.checkIp(req)) {
  122. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单!", "");
  123. }
  124. // 获取大模型列表
  125. List<CcLlmAgentAccount> list = ccLlmAgentAccountService.selectCcLlmAgentAccountList(new CcLlmAgentAccount());
  126. return AjaxResult.success(list);
  127. }
  128. /**
  129. * 获取音色列表
  130. * @return
  131. */
  132. @GetMapping("/voicecode/list")
  133. @ResponseBody
  134. public AjaxResult getVoiceCodeList(HttpServletRequest req)
  135. {
  136. // 校验客户端ip是否在白名单内
  137. if (!ClientIpCheck.checkIp(req)) {
  138. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单!", "");
  139. }
  140. // 获取音色列表
  141. List<CcTtsAliyun> list = ccTtsAliyunService.selectCcTtsAliyunList(new CcTtsAliyun());
  142. JSONArray result = new JSONArray();
  143. for (CcTtsAliyun ttsAliyun: list) {
  144. JSONObject obj = new JSONObject();
  145. obj.put("voiceName", ttsAliyun.getVoiceName());
  146. obj.put("voiceCode", ttsAliyun.getVoiceCode());
  147. obj.put("voiceSource", ttsAliyun.getVoiceSource());
  148. obj.put("ttsModels", ttsAliyun.getTtsModels());
  149. result.add(obj);
  150. }
  151. return AjaxResult.success(result);
  152. }
  153. /**
  154. * 获取技能组列表
  155. * @param req
  156. * @return
  157. */
  158. @GetMapping("/busigroup/list")
  159. @ResponseBody
  160. public AjaxResult getBusigroupList(HttpServletRequest req){
  161. // // 校验客户端ip是否在白名单内
  162. // if (!ClientIpCheck.checkIp(req)) {
  163. // return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单!", "");
  164. // }
  165. // 获取技能组列表
  166. List<CcBizGroup> list = ccBizGroupService.selectCcBizGroupList(new CcBizGroup());
  167. return AjaxResult.success(list);
  168. }
  169. /**
  170. * 通话记录查询接口(支持按时间、坐席、号码、呼入/呼出类型筛选)
  171. * @param req
  172. * @param queryParams
  173. * @return
  174. */
  175. @PostMapping("/calltask/list")
  176. @ResponseBody
  177. public TableDataInfo getCallTaskList(HttpServletRequest req, @RequestBody ApiCallTaskQueryParams queryParams)
  178. {
  179. TableDataInfo tableDataInfo;
  180. // 校验请求方ip是否合法
  181. if (!ClientIpCheck.checkIp(req)) {
  182. tableDataInfo = new TableDataInfo();
  183. tableDataInfo.setTotal(0);
  184. tableDataInfo.setCode(AjaxResult.Type.NO_AUTH.value());
  185. tableDataInfo.setMsg("未授权,请联系系统管理员添加ip白名单!");
  186. return tableDataInfo;
  187. }
  188. // 处理分页
  189. if (null == queryParams.getPageNum()) {
  190. queryParams.setPageNum(1);
  191. }
  192. if (null == queryParams.getPageSize()) {
  193. queryParams.setPageSize(20);
  194. }
  195. // 校验参数
  196. if (StringUtils.isNotEmpty(queryParams.getCreateTimeStart())
  197. && !DateValidatorUtils.isYmdHms(queryParams.getCreateTimeStart())) {
  198. tableDataInfo = new TableDataInfo();
  199. tableDataInfo.setTotal(0);
  200. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  201. tableDataInfo.setMsg("createTimeStart格式不正确,请使用'yyyy-MM-dd HH:mm:ss'格式!");
  202. return tableDataInfo;
  203. }
  204. if (StringUtils.isNotEmpty(queryParams.getCreateTimeEnd())
  205. && !DateValidatorUtils.isYmdHms(queryParams.getCreateTimeEnd())) {
  206. tableDataInfo = new TableDataInfo();
  207. tableDataInfo.setTotal(0);
  208. tableDataInfo.setCode(AjaxResult.Type.ERROR.value());
  209. tableDataInfo.setMsg("createTimeEnd格式不正确,请使用'yyyy-MM-dd HH:mm:ss'格式!");
  210. return tableDataInfo;
  211. }
  212. Map<String, Object> params = new HashMap<>();
  213. params.put("createTimeStart", queryParams.getCreateTimeStart());
  214. params.put("createTimeEnd", queryParams.getCreateTimeEnd());
  215. // 分页请求数据
  216. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  217. CcCallTask ccCallTask = new CcCallTask();
  218. ccCallTask.setBatchId(queryParams.getBatchId());
  219. ccCallTask.setBatchName(queryParams.getBatchName());
  220. ccCallTask.setParams(params);
  221. List<CcCallTask> list = ccCallTaskService.selectCcCallTaskList(ccCallTask);
  222. tableDataInfo = getDataTable(list);
  223. List<CcCallTask> records = (List<CcCallTask>) tableDataInfo.getRows();
  224. for (CcCallTask data: records){
  225. CallTaskStatModel statModel = ccCallPhoneService.statByBatchId(data.getBatchId());
  226. data.setPhoneCount(statModel.getPhoneCount());
  227. data.setCallCount(statModel.getCallCount());
  228. data.setNoCallCount(statModel.getPhoneCount() - statModel.getCallCount());
  229. data.setConnectCount(statModel.getConnectCount());
  230. data.setNoConnectCount(statModel.getCallCount() - statModel.getConnectCount());
  231. if (data.getCallCount() > 0) {
  232. data.setRealConnectRate(data.getConnectCount()*1.0/data.getCallCount());
  233. } else {
  234. data.setRealConnectRate(0.0);
  235. }
  236. }
  237. tableDataInfo.setRows(records);
  238. return tableDataInfo;
  239. }
  240. /**
  241. * 根据uuid查询
  242. * @param req
  243. * @param uuid
  244. * @param callType
  245. * @return
  246. */
  247. @GetMapping("/record/uuid")
  248. @ResponseBody
  249. public AjaxResult getRecordByUuid(HttpServletRequest req, @RequestParam String uuid, @RequestParam String callType)
  250. {
  251. // 校验客户端ip是否在白名单内
  252. if (!ClientIpCheck.checkIp(req)) {
  253. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单!", "");
  254. }
  255. if (StringUtils.isBlank(callType)) {
  256. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "callType不能为空!", "");
  257. }
  258. // 01:呼入, 02:AI外呼, 03:人工外呼
  259. ApiCallRecordQueryParams queryParams = new ApiCallRecordQueryParams().setUuid(uuid).setCallType(callType);
  260. TableDataInfo tableDataInfo = new TableDataInfo();
  261. if ("01".equals(callType)) {
  262. tableDataInfo = getInboundRecords(queryParams);
  263. } else if ("02".equals(callType)) {
  264. tableDataInfo = getAiCallRecords(queryParams);
  265. } else if ("03".equals(callType)) {
  266. tableDataInfo = getOutboundRecords(queryParams);
  267. }
  268. if (null != tableDataInfo.getRows() && tableDataInfo.getRows().size() > 0) {
  269. return AjaxResult.success(tableDataInfo.getRows().get(0));
  270. } else {
  271. return AjaxResult.success();
  272. }
  273. }
  274. /**
  275. * 通话记录查询接口(支持按时间、坐席、号码、呼入/呼出类型筛选)
  276. * @param req
  277. * @param queryParams
  278. * @return
  279. */
  280. @PostMapping("/records/list")
  281. @ResponseBody
  282. public TableDataInfo getRecordsList(HttpServletRequest req, @RequestBody ApiCallRecordQueryParams queryParams)
  283. {
  284. TableDataInfo tableDataInfo;
  285. // 校验请求方ip是否合法
  286. if (!ClientIpCheck.checkIp(req)) {
  287. tableDataInfo = new TableDataInfo();
  288. tableDataInfo.setTotal(0);
  289. tableDataInfo.setCode(AjaxResult.Type.NO_AUTH.value());
  290. tableDataInfo.setMsg("未授权,请联系系统管理员添加ip白名单!");
  291. return tableDataInfo;
  292. }
  293. // 分页参数处理
  294. if (null == queryParams.getPageNum()
  295. && null == queryParams.getPageSize()) {
  296. queryParams.setPageNum(1);
  297. queryParams.setPageSize(200000);
  298. }
  299. if (null == queryParams.getPageNum()) {
  300. queryParams.setPageNum(1);
  301. }
  302. if (null == queryParams.getPageSize()) {
  303. queryParams.setPageSize(20);
  304. }
  305. // 类型(01:呼入, 02:AI外呼, 03:人工外呼)
  306. String callType = queryParams.getCallType();
  307. if (StringUtils.isBlank(callType)) {
  308. tableDataInfo = new TableDataInfo();
  309. tableDataInfo.setTotal(0);
  310. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  311. tableDataInfo.setMsg("callType不能为空!");
  312. return tableDataInfo;
  313. }
  314. // 校验参数
  315. if (StringUtils.isNotEmpty(queryParams.getCalloutTimeStart())
  316. && !DateValidatorUtils.isYmdHms(queryParams.getCalloutTimeStart())) {
  317. tableDataInfo = new TableDataInfo();
  318. tableDataInfo.setTotal(0);
  319. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  320. tableDataInfo.setMsg("calloutTimeStart格式不正确,请使用'yyyy-MM-dd HH:mm:ss'格式!");
  321. return tableDataInfo;
  322. }
  323. if (StringUtils.isNotEmpty(queryParams.getCalloutTimeEnd())
  324. && !DateValidatorUtils.isYmdHms(queryParams.getCalloutTimeEnd())) {
  325. tableDataInfo = new TableDataInfo();
  326. tableDataInfo.setTotal(0);
  327. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  328. tableDataInfo.setMsg("calloutTimeStart格式不正确,请使用'yyyy-MM-dd HH:mm:ss'格式!");
  329. return tableDataInfo;
  330. }
  331. // 01:呼入, 02:AI外呼, 03:人工外呼
  332. if ("01".equals(callType)) {
  333. return getInboundRecords(queryParams);
  334. } else if ("02".equals(callType)) {
  335. return getAiCallRecords(queryParams);
  336. } else if ("03".equals(callType)) {
  337. return getOutboundRecords(queryParams);
  338. } else {
  339. tableDataInfo = new TableDataInfo();
  340. tableDataInfo.setTotal(0);
  341. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  342. tableDataInfo.setMsg("callType参数不合法,呼入请输入01,AI外呼请输入02,手工外呼请输入03!");
  343. return tableDataInfo;
  344. }
  345. }
  346. /**
  347. * 创建外呼任务接口(含任务名称、优先级、并发数、TTS/音频模板等参数)接口
  348. * @param req
  349. * @param apiCallTaskModel
  350. * @return
  351. */
  352. @PostMapping("/ai/createTask")
  353. @ResponseBody
  354. public AjaxResult createCallTask(HttpServletRequest req, @RequestBody ApiCallTaskModel apiCallTaskModel) {
  355. // 校验ip白名单
  356. if (!ClientIpCheck.checkIp(req)) {
  357. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单!", "");
  358. }
  359. CcCallTask ccCallTask = new CcCallTask();
  360. // 校验参数
  361. // 任务名称不能为空
  362. if (StringUtils.isBlank(apiCallTaskModel.getBatchName())) {
  363. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "batchName不能为空!", "");
  364. }
  365. // threadNum不能为空
  366. if (null == apiCallTaskModel.getThreadNum()) {
  367. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "threadNum不能为空!", "");
  368. }
  369. // 校验groupId是否存在
  370. if (!checkGroupId(apiCallTaskModel.getGroupId())) {
  371. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "groupId参数不合法,请输入正确的groupId!", "");
  372. }
  373. // 校验taskType是否合法
  374. if (null == apiCallTaskModel.getTaskType()) {
  375. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "taskType不能为空!", "");
  376. } else {
  377. if (apiCallTaskModel.getTaskType() != 1
  378. && apiCallTaskModel.getTaskType() != 2) {
  379. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "taskType参数不合法,AI外呼请输入1,通知提醒请输入2!", "");
  380. }
  381. }
  382. // 校验gatewayId是否合法
  383. if (!checkGatewayId(apiCallTaskModel.getGatewayId())) {
  384. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "gatewayId参数不合法,请输入正确的gatewayId!", "");
  385. }
  386. // AI外呼需要校验llmAccountId是否合法
  387. if (apiCallTaskModel.getTaskType() == 2) {
  388. if (!checkLlmAccountId(apiCallTaskModel.getLlmAccountId())) {
  389. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "llmAccountId参数不合法,请输入正确的llmAccountId!", "");
  390. }
  391. }
  392. // playTimes 如果为空,默认值给1
  393. if (apiCallTaskModel.getTaskType() == 3) {
  394. if (null == apiCallTaskModel.getPlayTimes()) {
  395. apiCallTaskModel.setPlayTimes(1);
  396. }
  397. }
  398. // 校验voiceCode、voiceSource是否合法
  399. if (!checkVoiceCode(apiCallTaskModel.getVoiceCode(), apiCallTaskModel.getVoiceSource())) {
  400. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "voiceCode或voiceSource参数不合法,请输入正确的voiceCode和voiceSource!", "");
  401. }
  402. // 创建任务
  403. BeanUtils.copyProperties(apiCallTaskModel, ccCallTask, "batchId");
  404. if ("acd".equals(ccCallTask.getAiTransferType())) {
  405. ccCallTask.setAiTransferData(ccCallTask.getAiTransferGroupId());
  406. } else if ("extension".equals(ccCallTask.getAiTransferType())) {
  407. ccCallTask.setAiTransferData(ccCallTask.getAiTransferExtNumber());
  408. } else if ("gateway".equals(ccCallTask.getAiTransferType())) {
  409. JSONObject aiTransferData = new JSONObject();
  410. aiTransferData.put("gatewayId", ccCallTask.getAiTransferGatewayId());
  411. aiTransferData.put("destNumber", ccCallTask.getAiTransferGatewayDestNumber());
  412. ccCallTask.setAiTransferData(JSONObject.toJSONString(aiTransferData));
  413. }
  414. if (null != ccCallTask.getConntectRate() && ccCallTask.getConntectRate() > 0) {
  415. ccCallTask.setRate(ccCallTask.getConntectRate()/100.0);
  416. }
  417. ccCallTask.setCreatetime(System.currentTimeMillis());
  418. if (StringUtils.isBlank(ccCallTask.getAsrLanguageCode())) {
  419. ccCallTask.setAsrLanguageCode("zh-CN");
  420. }
  421. if (StringUtils.isBlank(ccCallTask.getTtsLanguageCode())) {
  422. ccCallTask.setTtsLanguageCode("zh-CN");
  423. }
  424. if (StringUtils.isBlank(ccCallTask.getAsrModels())) {
  425. ccCallTask.setAsrProvider("ali");
  426. ccCallTask.setAsrModels("fun-asr-flash-8k-realtime");
  427. }
  428. if (StringUtils.isBlank(ccCallTask.getTtsModels())) {
  429. ccCallTask.setTtsModels("");
  430. }
  431. ccCallTaskService.insertCcCallTask(ccCallTask);
  432. apiCallTaskModel.setBatchId(ccCallTask.getBatchId());
  433. return AjaxResult.success("success", apiCallTaskModel);
  434. }
  435. /**
  436. * 启动任务接口
  437. * @param req
  438. * @param batchId
  439. * @return
  440. */
  441. @GetMapping("/ai/startTask")
  442. @ResponseBody
  443. public AjaxResult startTask(HttpServletRequest req, @RequestParam("batchId") Long batchId) {
  444. // 校验ip白名单
  445. if (!ClientIpCheck.checkIp(req)) {
  446. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单", "");
  447. }
  448. // 启动任务
  449. CcCallTask ccCallTask = ccCallTaskService.selectCcCallTaskByBatchId(batchId);
  450. if (null == ccCallTask) {
  451. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不合法,请输入正确的batchId", "");
  452. }
  453. ccCallTask.setIfcall(1);
  454. ccCallTask.setExecuting(0L);
  455. ccCallTask.setStopTime(0L);
  456. ccCallTaskService.updateCcCallTask(ccCallTask);
  457. return AjaxResult.success();
  458. }
  459. /**
  460. * 停止任务接口
  461. * @param req
  462. * @param batchId
  463. * @return
  464. */
  465. @GetMapping( "/ai/stopTask")
  466. @ResponseBody
  467. public AjaxResult stopTask(HttpServletRequest req, @RequestParam("batchId") Long batchId)
  468. {
  469. // 校验ip白名单
  470. if (!ClientIpCheck.checkIp(req)) {
  471. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单", "");
  472. }
  473. // 停止任务
  474. CcCallTask ccCallTask = ccCallTaskService.selectCcCallTaskByBatchId(batchId);
  475. if (null == ccCallTask) {
  476. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不合法,请输入正确的batchId", "");
  477. }
  478. ccCallTask.setIfcall(0);
  479. ccCallTask.setExecuting(0L);
  480. ccCallTask.setStopTime(System.currentTimeMillis());
  481. ccCallTaskService.updateCcCallTask(ccCallTask);
  482. return AjaxResult.success();
  483. }
  484. /**
  485. * 追加名单(不自动启动任务)
  486. * @param req
  487. * @param aiCallListModel
  488. * @return
  489. */
  490. @PostMapping("/ai/addCallList")
  491. @ResponseBody
  492. public AjaxResult addAiCallList(HttpServletRequest req, @RequestBody AiCallListModel aiCallListModel) {
  493. if (!ClientIpCheck.checkIp(req)) {
  494. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单", "");
  495. }
  496. Long batchId = aiCallListModel.getBatchId();
  497. if (null == batchId) {
  498. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不能为空", "");
  499. }
  500. if (CollectionUtils.isEmpty(aiCallListModel.getPhoneList())) {
  501. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数phoneList不能为空", "");
  502. }
  503. // 获取任务
  504. CcCallTask ccCallTask = callTaskService.selectCcCallTaskByBatchId(batchId);
  505. if (null == ccCallTask) {
  506. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不合法,请输入正确的batchId", "");
  507. }
  508. if (ccCallTask.getTaskType() != 1) {
  509. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不合法,请输入AI外呼任务(taskType为1)的batchId", "");
  510. }
  511. // 追加名单
  512. Integer successCount = 0;
  513. List<CcCallPhone> callPhoneList = new ArrayList<>();
  514. for (String phoneNum: aiCallListModel.getPhoneList()) {
  515. if (StringUtils.isBlank(phoneNum)) {
  516. continue;
  517. }
  518. JSONObject bizJson = new JSONObject();
  519. CcCallPhone callPhone = buildCcCallPhone(ccCallTask, phoneNum, bizJson);
  520. callPhoneList.add(callPhone);
  521. successCount ++;
  522. if (callPhoneList.size() >= 200) {
  523. ccCallPhoneService.batchInsertCcCallPhone(callPhoneList);
  524. callPhoneList = new ArrayList<>();
  525. }
  526. }
  527. if (callPhoneList.size() > 0) {
  528. ccCallPhoneService.batchInsertCcCallPhone(callPhoneList);
  529. }
  530. log.info("成功追加" + successCount + "个名单");
  531. return AjaxResult.success("成功追加" + successCount + "个名单");
  532. }
  533. /**
  534. * 追加外呼名单(不自动启动任务)
  535. * @param req
  536. * @param commonCallListModel
  537. * @return
  538. */
  539. @PostMapping("/common/addCallList")
  540. @ResponseBody
  541. public AjaxResult addCommonCallList(HttpServletRequest req, @RequestBody CommonCallListModel commonCallListModel) {
  542. if (!ClientIpCheck.checkIp(req)) {
  543. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单", "");
  544. }
  545. Long batchId = commonCallListModel.getBatchId();
  546. if (null == batchId) {
  547. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不能为空", "");
  548. }
  549. if (CollectionUtils.isEmpty(commonCallListModel.getPhoneList())) {
  550. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数phoneList不能为空", "");
  551. }
  552. // 获取任务
  553. CcCallTask ccCallTask = callTaskService.selectCcCallTaskByBatchId(batchId);
  554. if (null == ccCallTask) {
  555. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不合法,请输入正确的batchId", "");
  556. }
  557. // 通知类的通知内容必填
  558. if (ccCallTask.getTaskType() == 2) {
  559. for (CommonPhoneModel commonPhoneModel : commonCallListModel.getPhoneList()) {
  560. if (StringUtils.isBlank(commonPhoneModel.getNoticeContent())) {
  561. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "号码" + commonPhoneModel.getPhoneNum() + "的noticeContent不能为空!", "");
  562. }
  563. }
  564. }
  565. // 追加名单
  566. Integer successCount = 0;
  567. List<CcCallPhone> callPhoneList = new ArrayList<>();
  568. for (CommonPhoneModel commonPhoneModel : commonCallListModel.getPhoneList()) {
  569. String phoneNum = commonPhoneModel.getPhoneNum();
  570. if (StringUtils.isBlank(phoneNum)) {
  571. continue;
  572. }
  573. CcCallPhone callPhone = buildCcCallPhone(ccCallTask, phoneNum, commonPhoneModel.getBizJson());
  574. callPhone.setTtsText(commonPhoneModel.getNoticeContent());
  575. callPhoneList.add(callPhone);
  576. successCount ++;
  577. if (callPhoneList.size() >= 200) {
  578. ccCallPhoneService.batchInsertCcCallPhone(callPhoneList);
  579. callPhoneList = new ArrayList<>();
  580. }
  581. }
  582. if (callPhoneList.size() > 0) {
  583. ccCallPhoneService.batchInsertCcCallPhone(callPhoneList);
  584. }
  585. log.info("成功追加" + successCount + "个名单");
  586. return AjaxResult.success("成功追加" + successCount + "个名单",callPhoneList);
  587. }
  588. /**
  589. * yangqiang定制的追加通知的名单
  590. * @param req
  591. * @param noticeCallModel
  592. * @return
  593. */
  594. @PostMapping("/notice/call")
  595. @ResponseBody
  596. public AjaxResult callNotice(HttpServletRequest req, @RequestBody NoticeCallModel noticeCallModel) {
  597. if (!ClientIpCheck.checkIp(req)) {
  598. return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单", "");
  599. }
  600. // 获取任务
  601. String batchName = paramsService.getParamValueByCode("testNoticeCallTaskName", "test");
  602. String phoneNum = paramsService.getParamValueByCode("testNoticeCallPhoneNum", "13908113506");
  603. CcCallTask ccCallTask = callTaskService.selectCcCallTaskByBatchName(batchName, 2);
  604. // 追加名单
  605. JSONObject bizJson = new JSONObject();
  606. CcCallPhone callPhone = buildCcCallPhone(ccCallTask, phoneNum, bizJson);
  607. callPhone.setTtsText(noticeCallModel.getNoticeContent());
  608. ccCallPhoneService.insertCcCallPhone(callPhone);
  609. // 启动任务
  610. ccCallTask.setIfcall(1);
  611. ccCallTask.setExecuting(0L);
  612. ccCallTask.setStopTime(0L);
  613. callTaskService.updateCcCallTask(ccCallTask);
  614. return AjaxResult.success();
  615. }
  616. private CcCallPhone buildCcCallPhone(CcCallTask ccCallTask, String phoneNum, JSONObject bizJson) {
  617. CcCallPhone callPhone = new CcCallPhone();
  618. callPhone.setId(UuidGenerator.GetOneUuid());
  619. callPhone.setGroupId("1");
  620. callPhone.setBatchId(ccCallTask.getBatchId());
  621. callPhone.setCreatetime(new Date().getTime());
  622. callPhone.setCallstatus(0);
  623. callPhone.setCalloutTime(0L);
  624. callPhone.setCallcount(0);
  625. callPhone.setCallEndTime(0L);
  626. callPhone.setTimeLen(0L);
  627. callPhone.setValidTimeLen(0L);
  628. callPhone.setUuid("");
  629. callPhone.setConnectedTime(0L);
  630. callPhone.setHangupCause("");
  631. callPhone.setAnsweredTime(0L);
  632. callPhone.setDialogue("");
  633. callPhone.setWavfile("");
  634. callPhone.setRecordServerUrl("");
  635. callPhone.setDialogueCount(0L);
  636. callPhone.setAcdOpnum("");
  637. callPhone.setAcdQueueTime(0L);
  638. callPhone.setAcdWaitTime(0);
  639. callPhone.setTelephone(phoneNum);
  640. if (phoneNum.length() > 4) {
  641. bizJson.put("tailNum", phoneNum.substring(phoneNum.length()-4));
  642. } else {
  643. bizJson.put("tailNum", phoneNum);
  644. }
  645. bizJson.put("phoneNum", phoneNum);
  646. callPhone.setCustName(bizJson.getString("custName"));
  647. if (null == callPhone.getCustName()) {
  648. callPhone.setCustName("");
  649. }
  650. callPhone.setBizJson(JSONObject.toJSONString(bizJson));
  651. if (ccCallTask.getTaskType() == 1) {
  652. callPhone.setIntent("");
  653. } else {
  654. callPhone.setIntent("-");
  655. }
  656. return callPhone;
  657. }
  658. private TableDataInfo getOutboundRecords(ApiCallRecordQueryParams queryParams) {
  659. Map<String, Object> params = new HashMap<>();
  660. params.put("inboundTimeStart", queryParams.getCalloutTimeStart());
  661. params.put("inboundTimeEnd", queryParams.getCalloutTimeEnd());
  662. if (null != queryParams.getTimeLenStart()) {
  663. params.put("timeLenSecondStart", queryParams.getTimeLenStart().toString());
  664. }
  665. if (null != queryParams.getTimeLenEnd()) {
  666. params.put("timeLenSecondEnd", queryParams.getTimeLenEnd().toString());
  667. }
  668. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  669. CcOutboundCdr outboundCdr = new CcOutboundCdr();
  670. outboundCdr.setUuid(queryParams.getUuid());
  671. outboundCdr.setCaller(queryParams.getTelephone());
  672. outboundCdr.setOpnum(queryParams.getExtnum());
  673. outboundCdr.setParams(params);
  674. List<CcOutboundCdr> list = outboundCdrService.selectCcOutboundCdrList(outboundCdr);
  675. TableDataInfo tableData = getDataTable(list);
  676. List<CcOutboundCdr> records = (List<CcOutboundCdr>) tableData.getRows();
  677. List<ApiCallRecordQueryResult> apiRecords = new ArrayList<>();
  678. for (CcOutboundCdr data: records) {
  679. ApiCallRecordQueryResult apiData = new ApiCallRecordQueryResult();
  680. if (data.getRecordFilename().startsWith("/")) {
  681. data.setRecordFilename(data.getRecordFilename().substring(1));
  682. }
  683. data.setWavFileUrl("/recordings/files?filename=" + data.getRecordFilename());
  684. apiData.setUuid(data.getUuid());
  685. apiData.setTelephone(CommonUtils.maskPhoneNumber(data.getCallee()));
  686. apiData.setCalloutTime(DateUtils.format(new Date(data.getStartTime()), "yyyy-MM-dd HH:mm:ss"));
  687. if (data.getAnsweredTime() > 0) {
  688. apiData.setAnsweredTime(DateUtils.format(new Date(data.getAnsweredTime()), "yyyy-MM-dd HH:mm:ss"));
  689. } else {
  690. apiData.setAnsweredTime("");
  691. }
  692. if (data.getEndTime() > 0) {
  693. apiData.setCallEndTime(DateUtils.format(new Date(data.getEndTime()), "yyyy-MM-dd HH:mm:ss"));
  694. } else {
  695. apiData.setCallEndTime("");
  696. }
  697. apiData.setHangupCause(data.getHangupCause());
  698. if (data.getTimeLen() > 0) {
  699. apiData.setWavFileUrl(data.getWavFileUrl());
  700. } else {
  701. apiData.setWavFileUrl("");
  702. }
  703. apiData.setDialogue(new JSONArray());
  704. apiData.setTimeLen(Long.valueOf(data.getTimeLen()/1000).intValue());
  705. apiRecords.add(apiData);
  706. }
  707. tableData.setRows(records);
  708. TableDataInfo tableDataInfo = new TableDataInfo();
  709. tableDataInfo.setCode(tableData.getCode());
  710. tableDataInfo.setRows(apiRecords);
  711. tableDataInfo.setTotal(tableData.getTotal());
  712. tableDataInfo.setMsg(tableData.getMsg());
  713. return tableDataInfo;
  714. }
  715. private TableDataInfo getInboundRecords(ApiCallRecordQueryParams queryParams) {
  716. Map<String, Object> params = new HashMap<>();
  717. params.put("inboundTimeStart", queryParams.getCalloutTimeStart());
  718. params.put("inboundTimeEnd", queryParams.getCalloutTimeEnd());
  719. if (null != queryParams.getTimeLenStart()) {
  720. params.put("timeLenSecondStart", queryParams.getTimeLenStart().toString());
  721. }
  722. if (null != queryParams.getTimeLenEnd()) {
  723. params.put("timeLenSecondEnd", queryParams.getTimeLenEnd().toString());
  724. }
  725. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  726. CcInboundCdr inboundCdr = new CcInboundCdr();
  727. inboundCdr.setUuid(queryParams.getUuid());
  728. inboundCdr.setCaller(queryParams.getTelephone());
  729. inboundCdr.setOpnum(queryParams.getExtnum());
  730. inboundCdr.setParams(params);
  731. List<CcInboundCdr> list = inboundCdrService.selectCcInboundCdrList(inboundCdr);
  732. TableDataInfo tableData = getDataTable(list);
  733. List<CcInboundCdr> records = (List<CcInboundCdr>) tableData.getRows();
  734. List<ApiCallRecordQueryResult> apiRecords = new ArrayList<>();
  735. for (CcInboundCdr data: records) {
  736. ApiCallRecordQueryResult apiData = new ApiCallRecordQueryResult();
  737. if (data.getWavFile().startsWith("/")) {
  738. data.setWavFile(data.getWavFile().substring(1));
  739. }
  740. data.setWavFileUrl("/recordings/files?filename=" + data.getWavFile());
  741. apiData.setUuid(data.getUuid());
  742. apiData.setTelephone(CommonUtils.maskPhoneNumber(data.getCaller()));
  743. apiData.setCalloutTime(DateUtils.format(new Date(data.getInboundTime()), "yyyy-MM-dd HH:mm:ss"));
  744. if (data.getAnsweredTime() > 0) {
  745. apiData.setAnsweredTime(DateUtils.format(new Date(data.getAnsweredTime()), "yyyy-MM-dd HH:mm:ss"));
  746. } else {
  747. apiData.setAnsweredTime("");
  748. }
  749. if (data.getHangupTime() > 0) {
  750. apiData.setCallEndTime(DateUtils.format(new Date(data.getHangupTime()), "yyyy-MM-dd HH:mm:ss"));
  751. } else {
  752. apiData.setCallEndTime("");
  753. }
  754. apiData.setHangupCause("");
  755. if (data.getTimeLen() > 0) {
  756. apiData.setWavFileUrl(data.getWavFileUrl());
  757. } else {
  758. apiData.setWavFileUrl("");
  759. }
  760. if (StringUtils.isNotEmpty(data.getChatContent())) {
  761. JSONArray dialogue = new JSONArray();
  762. JSONArray.parseArray(data.getChatContent()).forEach(obj -> {
  763. JSONObject json = (JSONObject) obj;
  764. if ("assistant".equals(json.getString("role"))
  765. || "user".equals(json.getString("role"))) {
  766. JSONObject content = new JSONObject();
  767. content.put("role", json.getString("role"));
  768. content.put("content", json.getString("content"));
  769. dialogue.add(content);
  770. }
  771. });
  772. apiData.setDialogue(dialogue);
  773. } else {
  774. apiData.setDialogue(new JSONArray());
  775. }
  776. apiData.setTimeLen(Long.valueOf(data.getTimeLen()/1000).intValue());
  777. apiData.setManualAnsweredTime(data.getManualAnsweredTime());
  778. apiData.setManualAnsweredTimeLen(data.getManualAnsweredTimeLen());
  779. apiRecords.add(apiData);
  780. }
  781. tableData.setRows(records);
  782. TableDataInfo tableDataInfo = new TableDataInfo();
  783. tableDataInfo.setCode(tableData.getCode());
  784. tableDataInfo.setRows(apiRecords);
  785. tableDataInfo.setTotal(tableData.getTotal());
  786. tableDataInfo.setMsg(tableData.getMsg());
  787. return tableDataInfo;
  788. }
  789. private TableDataInfo getAiCallRecords(ApiCallRecordQueryParams queryParams) {
  790. Map<String, Object> params = new HashMap<>();
  791. params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
  792. params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
  793. if (null != queryParams.getTimeLenStart()) {
  794. params.put("timeLenSecondStart", queryParams.getTimeLenStart().toString());
  795. }
  796. if (null != queryParams.getTimeLenEnd()) {
  797. params.put("timeLenSecondEnd", queryParams.getTimeLenEnd().toString());
  798. }
  799. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  800. CcCallPhone ccCallPhone = new CcCallPhone();
  801. if (null != queryParams.getBatchId() && queryParams.getBatchId() > 0) {
  802. ccCallPhone.setBatchId(queryParams.getBatchId());
  803. }
  804. ccCallPhone.setUuid(queryParams.getUuid());
  805. ccCallPhone.setTelephone(queryParams.getTelephone());
  806. ccCallPhone.setAcdOpnum(queryParams.getExtnum());
  807. ccCallPhone.setCallstatus(queryParams.getCallstatus());
  808. ccCallPhone.setCallerNumber(queryParams.getCallerNumber());
  809. ccCallPhone.setParams(params);
  810. List<CcCallPhone> list = ccCallPhoneService.selectCcCallPhoneList(ccCallPhone);
  811. TableDataInfo tableData = getDataTable(list);
  812. List<CcCallPhone> records = (List<CcCallPhone>) tableData.getRows();
  813. List<ApiCallRecordQueryResult> apiRecords = new ArrayList<>();
  814. for (CcCallPhone data: records) {
  815. ApiCallRecordQueryResult apiData = new ApiCallRecordQueryResult();
  816. if (data.getWavfile().startsWith("/")) {
  817. data.setWavfile(data.getWavfile().substring(1));
  818. }
  819. data.setWavfile("/recordings/files?filename=" + data.getWavfile());
  820. apiData.setUuid(data.getUuid());
  821. apiData.setTelephone(CommonUtils.maskPhoneNumber(data.getTelephone()));
  822. apiData.setCalloutTime(DateUtils.format(new Date(data.getCalloutTime()), "yyyy-MM-dd HH:mm:ss"));
  823. if (data.getAnsweredTime() > 0) {
  824. apiData.setAnsweredTime(DateUtils.format(new Date(data.getAnsweredTime()), "yyyy-MM-dd HH:mm:ss"));
  825. } else {
  826. apiData.setAnsweredTime("");
  827. }
  828. if (data.getCallEndTime() > 0) {
  829. apiData.setCallEndTime(DateUtils.format(new Date(data.getCallEndTime()), "yyyy-MM-dd HH:mm:ss"));
  830. } else {
  831. apiData.setCallEndTime("");
  832. }
  833. apiData.setHangupCause(data.getHangupCause());
  834. if (data.getTimeLen() > 0) {
  835. apiData.setWavFileUrl(data.getWavfile());
  836. } else {
  837. apiData.setWavFileUrl("");
  838. }
  839. if (StringUtils.isNotEmpty(data.getDialogue())) {
  840. JSONArray dialogue = new JSONArray();
  841. JSONArray.parseArray(data.getDialogue()).forEach(obj -> {
  842. JSONObject json = (JSONObject) obj;
  843. if ("assistant".equals(json.getString("role"))
  844. || "user".equals(json.getString("role"))) {
  845. JSONObject content = new JSONObject();
  846. content.put("role", json.getString("role"));
  847. content.put("content", json.getString("content"));
  848. dialogue.add(content);
  849. }
  850. });
  851. apiData.setDialogue(dialogue);
  852. } else {
  853. apiData.setDialogue(new JSONArray());
  854. }
  855. apiData.setTimeLen(Long.valueOf(data.getTimeLen()/1000).intValue());
  856. apiData.setSessionId(data.getId());
  857. apiData.setCallstatus(data.getCallstatus());
  858. apiData.setCallerNumber(CommonUtils.maskPhoneNumber(data.getCallerNumber()));
  859. apiData.setManualAnsweredTime(data.getManualAnsweredTime());
  860. apiData.setManualAnsweredTimeLen(data.getManualAnsweredTimeLen());
  861. apiRecords.add(apiData);
  862. }
  863. tableData.setRows(records);
  864. TableDataInfo tableDataInfo = new TableDataInfo();
  865. tableDataInfo.setCode(tableData.getCode());
  866. tableDataInfo.setRows(apiRecords);
  867. tableDataInfo.setTotal(tableData.getTotal());
  868. tableDataInfo.setMsg(tableData.getMsg());
  869. return tableDataInfo;
  870. }
  871. private boolean checkGroupId(String groupId) {
  872. // 可以为空
  873. if (StringUtils.isBlank(groupId)) {
  874. return true;
  875. }
  876. // 如果传值了,必须是存在的值
  877. CcBizGroup ccBizGroup = ccBizGroupService.selectCcBizGroupByGroupId(groupId);
  878. if (null == ccBizGroup) {
  879. return false;
  880. }
  881. return true;
  882. }
  883. private boolean checkGatewayId(Long gatewayId) {
  884. // 不可以为空
  885. if (null == gatewayId) {
  886. return false;
  887. }
  888. // 必须是存在的网关,且用途是外呼或者不限制
  889. CcGateways ccGateways = ccGatewaysService.selectCcGatewaysById(gatewayId);
  890. if (null == ccGateways) {
  891. return false;
  892. }
  893. // 网关用途 0 dropped; 1 phonebar; 2 outbound tasks; 3. Unlimited
  894. if (ccGateways.getPurpose() != 2
  895. && ccGateways.getPurpose() != 3) {
  896. return false;
  897. }
  898. return true;
  899. }
  900. private boolean checkLlmAccountId(Integer llmAccountId) {
  901. // 不能为空
  902. if (null == llmAccountId) {
  903. return false;
  904. }
  905. // 必须存在
  906. CcLlmAgentAccount ccLlmAgentAccount = ccLlmAgentAccountService.selectCcLlmAgentAccountById(llmAccountId);
  907. if (null == ccLlmAgentAccount) {
  908. return false;
  909. }
  910. return true;
  911. }
  912. private boolean checkVoiceCode(String voiceCode, String voiceSource) {
  913. // 不能为空
  914. if (StringUtils.isBlank(voiceCode) || StringUtils.isBlank(voiceSource)) {
  915. return false;
  916. }
  917. // voiceSource仅支持aliyun_tts 、 aliyun_tts_flow 和 doubao_vcl_tts
  918. if (!"aliyun_tts".equals(voiceSource)
  919. && !"aliyun_tts_flow".equals(voiceSource)
  920. && !"doubao_vcl_tts".equals(voiceSource)) {
  921. return false;
  922. }
  923. // voiceCode必须是存在的
  924. CcTtsAliyun ccTtsAliyun = ccTtsAliyunService.selectCcTtsAliyunByVoiceCode(voiceCode);
  925. if (null == ccTtsAliyun) {
  926. return false;
  927. }
  928. return true;
  929. }
  930. /**
  931. * 行稳数智追加名单【不自动启动任务,需要在任务管理页面手动启动任务】
  932. * @param req
  933. * @param localCallModel
  934. * @return
  935. */
  936. @PostMapping("/local/addCall")
  937. @ResponseBody
  938. public AjaxResult addLocalCall(HttpServletRequest req, @RequestBody LocalCallModel localCallModel) {
  939. // if (!ClientIpCheck.checkIp(req)) {
  940. // return AjaxResult.error(AjaxResult.Type.NO_AUTH, "未授权,请联系系统管理员添加ip白名单", "");
  941. // }
  942. // 获取任务
  943. String batchName = localCallModel.getBatchName();
  944. if (StringUtils.isEmpty(batchName)) {
  945. batchName = paramsService.getParamValueByCode("testNoticeCallTaskName", "test");
  946. }
  947. CcCallTask ccCallTask = callTaskService.selectCcCallTaskByBatchName(batchName, 1);
  948. log.info("接收到名单localCallModel:{}", JSONObject.toJSONString(localCallModel));
  949. log.info("batchName:{}", batchName);
  950. log.info("ccCallTask:{}", JSONObject.toJSONString(ccCallTask));
  951. // 追加名单
  952. String phoneNum = localCallModel.getPhone();
  953. JSONObject bizJson = new JSONObject();
  954. bizJson.put("caller", localCallModel.getCaller());
  955. bizJson.put("welcomeMessage", localCallModel.getWelcomeMessage());
  956. bizJson.put("questionChainId", localCallModel.getQuestionChainId());
  957. CcCallPhone callPhone = buildCcCallPhone(ccCallTask, phoneNum, bizJson);
  958. ccCallPhoneService.insertCcCallPhone(callPhone);
  959. // 暂时关闭自动启动逻辑(后续改成自动启停逻辑)
  960. // // 如果停止超过5分钟,则自动启动
  961. // if (ccCallTask.getIfcall() == 0
  962. // && (System.currentTimeMillis() - ccCallTask.getStopTime()) >= 5*60*1000L) {
  963. // ccCallTask.setIfcall(1);
  964. // ccCallTask.setExecuting(0L);
  965. // ccCallTask.setStopTime(0L);
  966. // callTaskService.updateCcCallTask(ccCallTask);
  967. // }
  968. JSONObject res = new JSONObject();
  969. res.put("sessionId", callPhone.getId().toString());
  970. log.info("名单处理完成:{}", JSONObject.toJSONString(callPhone));
  971. return AjaxResult.success(res);
  972. }
  973. /**
  974. * 自动绑定并获取分机信息
  975. * @param req
  976. * @param loginUser
  977. * @return
  978. */
  979. @GetMapping("/phoneBar/extnum/bind")
  980. @ResponseBody
  981. public AjaxResult getExtNumByUserName(HttpServletRequest req, @RequestParam String loginUser) {
  982. // 获取分机号
  983. CcExtNum ccExtNum = ccExtNumService.selectCcExtNumByUserCode(loginUser);
  984. if (null != ccExtNum) {
  985. return AjaxResult.success("success", ccExtNum);
  986. }
  987. // 如果没有获取到分机,则自动绑定分机
  988. List<CcExtNum> ccExtNumList = ccExtNumService.selectUnBindCcExtNumList();
  989. if (CollectionUtils.isEmpty(ccExtNumList)) {
  990. log.error("没有可用分机,无法分配分机-:{}", loginUser);
  991. return AjaxResult.error("没有可用分机,无法分配分机");
  992. }
  993. ccExtNum = ccExtNumList.get(RandomUtils.nextInt(0, ccExtNumList.size()));
  994. ccExtNum.setUserCode(loginUser);
  995. ccExtNumService.updateCcExtNum(ccExtNum);
  996. return AjaxResult.success("success", ccExtNum);
  997. }
  998. /**
  999. * 获取电话工具条的网关列表
  1000. * @param req
  1001. * @param extNum
  1002. * @return
  1003. */
  1004. @GetMapping("/phoneBar/params")
  1005. @ResponseBody
  1006. public AjaxResult getPhoneBaseParams(HttpServletRequest req, @RequestParam String extNum) {
  1007. // 获取分机号
  1008. CcExtNum ccExtNum = ccExtNumService.selectCcExtNumByExtNum(Long.valueOf(extNum));
  1009. String extnum = ccExtNum.getExtNum().toString();
  1010. String opnum = ccExtNum.getUserCode();
  1011. String groupId = "1";
  1012. String skillLevel = "9";
  1013. String projectId = "1";
  1014. String loginToken = ccExtNumService.createToken(extnum, opnum, groupId, skillLevel, projectId);
  1015. // 网关用途 0 dropped; 1 phonebar; 2 outbound tasks; 3. Unlimited
  1016. Map<String, Object> params = new HashMap<>();
  1017. params.put("purposes", Arrays.asList(1,3));
  1018. List<CcGateways> gatewaysList = ccGatewaysService.selectCcGatewaysList(new CcGateways().setParams(params));
  1019. List<JSONObject> gatewayList = new ArrayList<>();
  1020. for (CcGateways ccGateways: gatewaysList) {
  1021. JSONObject configGateway = new JSONObject();
  1022. configGateway.put("uuid", ccGateways.getId().toString());
  1023. configGateway.put("updateTime", ccGateways.getUpdateTime());
  1024. configGateway.put("gatewayAddr", ccGateways.getGwAddr());
  1025. configGateway.put("callerNumber", ccGateways.getCaller());
  1026. configGateway.put("calleePrefix", ccGateways.getCalleePrefix());
  1027. configGateway.put("callProfile", ccGateways.getProfileName());
  1028. configGateway.put("priority", ccGateways.getPriority());
  1029. configGateway.put("concurrency", ccGateways.getMaxConcurrency());
  1030. configGateway.put("register", ccGateways.getRegister());
  1031. configGateway.put("authUsername", ccGateways.getAuthUsername());
  1032. configGateway.put("audioCodec", ccGateways.getCodec());
  1033. gatewayList.add(configGateway);
  1034. }
  1035. JSONObject callConfig = new JSONObject();
  1036. String scriptServer = ccParamsService.getParamValueByCode("call-center-server-ip-addr", "");
  1037. String scriptPort = ccParamsService.getParamValueByCode("call-center-websocket-port", "");
  1038. callConfig.put("scriptServer", scriptServer);
  1039. callConfig.put("scriptPort", scriptPort);
  1040. callConfig.put("loginToken", loginToken);
  1041. callConfig.put("gatewayList", gatewayList);
  1042. return AjaxResult.success(callConfig);
  1043. }
  1044. @PostMapping("/test/localChat")
  1045. @ResponseBody
  1046. public JSONObject localChat(HttpServletRequest request, @RequestBody JSONObject reqParams) {
  1047. // {"code":200, "data":{"choices":[{"content":"xxxxxxx", "wavFilePath":"/home/Records/251224101457010001/20260113161253001914.wav"}]}}
  1048. log.info("请求参数:{}", reqParams);
  1049. Integer rounds = 0;
  1050. for (int i = 0; i < reqParams.getJSONArray("messages").size(); i++) {
  1051. if ("assistant".equals(reqParams.getJSONArray("messages").getJSONObject(i).getString("role"))) {
  1052. rounds ++;
  1053. }
  1054. }
  1055. String[] rspDatas = new String[]{
  1056. // "您好,请问您是测试1本人是吗?| /home/Records/23/round-1.wav; ",
  1057. "这里是中信银行委托方,这个电话号码是测试1在中信银行办理业务时登记的号码,您是测试1吗? | /home/Records/23/round-2-1.wav;/home/Records/23/round-2-2.wav;/home/Records/23/round-2-3.wav",
  1058. "这里是中信银行委托方,这边主要是通知您一下,您在中信银行卡尾号6388的信用卡已错过到期环款日,当期账单账面欠款总额9097元全国统一核账时间在今天下午5点需要您在此之前处理进来,可以吧?| /home/Records/23/round-3-1.wav;/home/Records/23/round-3-2.wav;",
  1059. "您的账单现在已经过环款日了,能和我们说一下您是为什么还没处理欠款吗? | /home/Records/23/round-4.wav",
  1060. "好的,请您在今天下午5点之前至少处理您的最低还款额0元时间和资金都没问题,对吗?|/home/Records/23/round-5.wav",
  1061. "银行稍后安排工作人员查账,建议您尽快处理欠款,不打扰您了,再见。hangupCall|/home/Records/23/round-6.wav"
  1062. };
  1063. JSONObject result = new JSONObject();
  1064. result.put("code", 200);
  1065. JSONObject data = new JSONObject();
  1066. JSONArray choices = new JSONArray();
  1067. JSONObject delta = new JSONObject();
  1068. String[] rspData = rspDatas[rounds].split("\\|");
  1069. delta.put("content", rspData[0].trim());
  1070. delta.put("wavFilePath", rspData[1].trim());
  1071. JSONObject choices0 = new JSONObject();
  1072. choices0.put("delta", delta);
  1073. choices.add(choices0);
  1074. data.put("choices", choices);
  1075. result.put("data", data);
  1076. return result;
  1077. }
  1078. //=======================================================新增接口============================================================
  1079. /**
  1080. * 删除外呼任务
  1081. */
  1082. @PostMapping( "/removeTask")
  1083. @ResponseBody
  1084. @Transactional
  1085. public AjaxResult removeTask(@RequestBody Map<String, Long[]> paramMap)
  1086. {
  1087. Long[] batchIds= paramMap.get("batchIds");
  1088. if(batchIds==null){
  1089. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "batchIds不能为空!", "");
  1090. }
  1091. for (Long batchId : batchIds) {
  1092. // 备份拨打记录数据
  1093. ccCallPhoneService.bakCallPhoneByBatchId(batchId);
  1094. // 删除拨打记录数据
  1095. ccCallPhoneService.delCallPhoneByBatchId(batchId);
  1096. // 备份任务数据
  1097. ccCallTaskService.bakCallTaskByBatchId(batchId);
  1098. }
  1099. // 删除任务数据
  1100. String batchIdsStr = Arrays.stream(batchIds)
  1101. .map(String::valueOf)
  1102. .collect(Collectors.joining(","));
  1103. return toAjax(ccCallTaskService.deleteCcCallTaskByBatchIds(batchIdsStr));
  1104. }
  1105. /**
  1106. * 获取电话工具条的网关列表
  1107. */
  1108. @PostMapping("/myPhoneBar/params")
  1109. @ResponseBody
  1110. public AjaxResult getMyPhoneBaseParams(@RequestBody Map<String,String> param) {
  1111. String extNum = param.get("extNum");
  1112. String myGateway = param.get("myGateway");
  1113. if(extNum == null){
  1114. return AjaxResult.error("分机号参数缺失");
  1115. }
  1116. // 获取分机号
  1117. CcExtNum ccExtNum = ccExtNumService.selectCcExtNumByExtNum(Long.valueOf(extNum));
  1118. String extnum = ccExtNum.getExtNum().toString();
  1119. String opnum = ccExtNum.getUserCode();
  1120. String password = ccExtNum.getExtPass();
  1121. String groupId = "1";
  1122. String skillLevel = "9";
  1123. String projectId = "1";
  1124. //1.创建token
  1125. String loginToken = ccExtNumService.createToken(extnum, opnum, groupId, skillLevel, projectId);
  1126. //2.获取加密密码
  1127. String encryptStr = DESUtil.encrypt(password + "," + DateUtils.format(DateUtils.addDays(new Date(), 1), "yyyyMMddHHmm"));
  1128. encryptStr = String.format("var _phoneEncryptPassword='%s';", encryptStr);
  1129. CcGateways ccGatewaysVo = new CcGateways();
  1130. //判断指定网关还是全部网关
  1131. if(StringUtils.isNotBlank(myGateway)){
  1132. List<Long> gatewayIds = Arrays.stream(myGateway.split(","))
  1133. .map(Long::parseLong)
  1134. .collect(Collectors.toList());
  1135. ccGatewaysVo.setGatewayIds(gatewayIds);
  1136. }else{
  1137. String wgName = param.get("wgName");
  1138. if(StringUtils.isNotBlank(wgName)){
  1139. ccGatewaysVo.setGwName(wgName);
  1140. }else{
  1141. // 网关用途 0 已废弃; 1 电话条; 2 外呼任务; 3 无限制
  1142. Map<String, Object> params = new HashMap<>();
  1143. params.put("purposes", Arrays.asList(1,3));
  1144. ccGatewaysVo.setParams(params);
  1145. }
  1146. }
  1147. //3.获取工具条网关列表
  1148. List<CcGateways> gatewaysList = ccGatewaysService.selectCcGatewaysList(ccGatewaysVo);
  1149. List<JSONObject> gatewayList = new ArrayList<>();
  1150. for (CcGateways ccGateways: gatewaysList) {
  1151. JSONObject configGateway = new JSONObject();
  1152. configGateway.put("uuid", ccGateways.getId().toString());
  1153. configGateway.put("updateTime", ccGateways.getUpdateTime());
  1154. configGateway.put("gatewayAddr", ccGateways.getGwAddr());
  1155. configGateway.put("callerNumber", ccGateways.getCaller());
  1156. configGateway.put("calleePrefix", ccGateways.getCalleePrefix());
  1157. configGateway.put("callProfile", ccGateways.getProfileName());
  1158. configGateway.put("priority", ccGateways.getPriority());
  1159. configGateway.put("concurrency", ccGateways.getMaxConcurrency());
  1160. configGateway.put("register", ccGateways.getRegister());
  1161. configGateway.put("authUsername", ccGateways.getAuthUsername());
  1162. configGateway.put("audioCodec", ccGateways.getCodec());
  1163. gatewayList.add(configGateway);
  1164. }
  1165. JSONObject callConfig = new JSONObject();
  1166. String scriptServer = ccParamsService.getParamValueByCode("call-center-server-ip-addr", "");
  1167. String scriptPort = ccParamsService.getParamValueByCode("call-center-websocket-port", "");
  1168. callConfig.put("scriptServer", scriptServer);
  1169. callConfig.put("scriptPort", scriptPort);
  1170. callConfig.put("loginToken", loginToken);
  1171. callConfig.put("encryptPsw", encryptStr);
  1172. callConfig.put("gatewayList", gatewayList);
  1173. //登录账号
  1174. callConfig.put("opNum", opnum);
  1175. //登录用户名称
  1176. SysUser sysUser = userService.selectUserByLoginName(opnum);
  1177. if(sysUser != null){
  1178. callConfig.put("userName", sysUser.getUserName());
  1179. }
  1180. return AjaxResult.success(callConfig);
  1181. }
  1182. /**
  1183. * 查询未绑定的分机管理列表
  1184. */
  1185. @GetMapping("/extnum/selectUnBindCcExtNumList")
  1186. @ResponseBody
  1187. public AjaxResult selectUnBindCcExtNumList()
  1188. {
  1189. return AjaxResult.success(ccExtNumService.selectUnBindCcExtNumList());
  1190. }
  1191. /**
  1192. * 查询公司未绑定的分机管理列表
  1193. */
  1194. @PostMapping("/extnum/selectCompanyUnBindCcExtNumList")
  1195. @ResponseBody
  1196. public AjaxResult selectCompanyUnBindCcExtNumList(@RequestBody CcExtNum ccExtNum)
  1197. {
  1198. return AjaxResult.success(ccExtNumService.selectCcExtNumList(ccExtNum));
  1199. }
  1200. /**
  1201. * 查询未绑定的分机管理列表分页
  1202. */
  1203. @PostMapping("/extnum/selectUnBindCcExtNumListPage")
  1204. @ResponseBody
  1205. public TableDataInfo selectUnBindCcExtNumListPage(@RequestBody CcExtNum ccExtNum)
  1206. {
  1207. Integer pageNum = ccExtNum.getPageNum() != null ? ccExtNum.getPageNum().intValue() : 1;
  1208. Integer pageSize = ccExtNum.getPageSize() != null ? ccExtNum.getPageSize().intValue() : 10;
  1209. startPage(pageNum, pageSize);
  1210. List<CcExtNum> list = ccExtNumService.selectUnBindCcExtNumListPage(ccExtNum);
  1211. return getDataTable(list);
  1212. }
  1213. /**
  1214. * 通用查询分机列表分页
  1215. */
  1216. @PostMapping("/extnumPage")
  1217. @ResponseBody
  1218. public TableDataInfo extnumPage(@RequestBody CcExtNum ccExtNum)
  1219. {
  1220. Integer pageNum = ccExtNum.getPageNum() != null ? ccExtNum.getPageNum().intValue() : 1;
  1221. Integer pageSize = ccExtNum.getPageSize() != null ? ccExtNum.getPageSize().intValue() : 10;
  1222. startPage(pageNum, pageSize);
  1223. List<CcExtNum> list = ccExtNumService.selectCcExtNumList(ccExtNum);
  1224. if(!CollectionUtils.isEmpty(list)){
  1225. list.forEach(extNum -> {
  1226. if(StringUtils.isNotBlank(extNum.getUserCode()) && extNum.getUserCode().startsWith("_cp_")){
  1227. extNum.setUserCode("");
  1228. }
  1229. });
  1230. }
  1231. return getDataTable(list);
  1232. }
  1233. /**
  1234. * 新增企业绑定未使用的分机(实际只是公司占位,需销售来绑定)
  1235. */
  1236. @PostMapping("/companyBindExtNum")
  1237. @ResponseBody
  1238. @Transactional
  1239. public AjaxResult companyBindExtNum(@RequestBody Map<String,String> param)
  1240. {
  1241. String companyName = param.get("companyName");
  1242. String sipExtNumIds = param.get("sipExtNumIds");
  1243. if(StringUtils.isBlank(companyName) || StringUtils.isBlank(sipExtNumIds)){
  1244. return AjaxResult.error("参数companyName或sipExtNumIds缺失");
  1245. }
  1246. //公司绑定分机
  1247. List<Long> extNumList = Arrays.stream(sipExtNumIds.split(","))
  1248. .map(String::trim)
  1249. .filter(StringUtils::isNotBlank)
  1250. .map(Long::parseLong)
  1251. .collect(Collectors.toList());
  1252. CcExtNum extNum = new CcExtNum();
  1253. extNum.setUserCode(companyName);
  1254. extNum.setSipExtNumList(extNumList);
  1255. return toAjax(ccExtNumService.updateCompanyBindExtNum(extNum));
  1256. }
  1257. /**
  1258. * 公司批量解绑分机,根据分机号
  1259. */
  1260. @PostMapping("/companyBatchUnbindSipExt")
  1261. @ResponseBody
  1262. public AjaxResult companyBatchUnbindSipExt(@RequestBody Set<Long> extNums)
  1263. {
  1264. if(extNums == null || extNums.isEmpty()){
  1265. return AjaxResult.error("参数为空");
  1266. }
  1267. return toAjax(ccExtNumService.companyBatchUnbindSipExt(extNums));
  1268. }
  1269. /**
  1270. * 新增用户且绑定未使用的分机返回用户
  1271. */
  1272. @PostMapping("/user/addUserOrBindExtNumReturnUser")
  1273. @ResponseBody
  1274. @Transactional
  1275. public AjaxResult addUserOrBindExtNumReturnUser(@RequestBody SysUser user)
  1276. {
  1277. if(StringUtils.isBlank(user.getPassword())){
  1278. throw new RuntimeException("密码不能为空");
  1279. }
  1280. // 校验分机号是否为空
  1281. if (null == user.getExtNum()) {
  1282. throw new RuntimeException("新增用户失败,分机号不能为空");
  1283. }
  1284. // 校验分机号是否存在
  1285. CcExtNum extNum = ccExtNumService.selectCcExtNumByExtNum(user.getExtNum());
  1286. if (null == extNum) {
  1287. throw new RuntimeException("新增用户失败,分机号" + user.getExtNum() + "不存在");
  1288. }
  1289. user.setSalt(ShiroUtils.randomSalt());
  1290. user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
  1291. user.setPwdUpdateDate(DateUtils.getNowDate());
  1292. user.setCreateBy("ylrz");
  1293. int i;
  1294. SysUser sysUser = userService.selectUserByLoginName(user.getLoginName());
  1295. if (sysUser != null)
  1296. {
  1297. //优化一下,如果账号存在就更新账号
  1298. user.setUserId(sysUser.getUserId());
  1299. i = userService.updateUser(user);
  1300. }else{
  1301. i = userService.insertUser(user);
  1302. }
  1303. if(i>0){
  1304. //绑定分机
  1305. extNum.setUserCode(user.getLoginName());
  1306. int num = ccExtNumService.updateCcExtNum(extNum);
  1307. if(num>0){
  1308. user.setExtPass(extNum.getExtPass());
  1309. return AjaxResult.success(user);
  1310. } else {
  1311. throw new RuntimeException("用户信息处理成功,但分机号绑定失败");
  1312. }
  1313. }
  1314. throw new RuntimeException("新增用户和绑分机操作失败");
  1315. }
  1316. /**
  1317. * 修改用户且绑分机
  1318. */
  1319. @PostMapping("/user/editUserOrUnBindExtNum")
  1320. @ResponseBody
  1321. @Transactional
  1322. public AjaxResult editUserOrUnBindExtNum(@RequestBody SysUser user)
  1323. {
  1324. if (!userService.checkLoginNameUnique(user))
  1325. {
  1326. throw new RuntimeException("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
  1327. }
  1328. else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
  1329. {
  1330. throw new RuntimeException("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
  1331. }
  1332. user.setUpdateBy("ylrz");
  1333. AuthorizationUtils.clearAllCachedAuthorizationInfo();
  1334. int i = userService.updateUser(user);
  1335. if(i>0){
  1336. int cleanNum;
  1337. if(StringUtils.isNotBlank(user.getUserSource()) && user.getUserSource().equals("0")){
  1338. cleanNum = ccExtNumService.updateUserCodeByLoginName(user.getCompanyName(),user.getLoginName());
  1339. }else{
  1340. //先清除原分机绑定
  1341. cleanNum = ccExtNumService.cleanCcExtNumByUserCode(user.getLoginName());
  1342. }
  1343. if(cleanNum>0){
  1344. //修改绑定分机
  1345. CcExtNum extNum = new CcExtNum();
  1346. extNum.setExtNum(user.getExtNum());
  1347. extNum.setUserCode(user.getLoginName());
  1348. int updateNum = ccExtNumService.updateCcExtNumByUserCode(extNum);
  1349. if(updateNum>0){
  1350. CcExtNum num = ccExtNumService.selectCcExtNumByExtNum(user.getExtNum());
  1351. if(null != num){
  1352. user.setExtPass(num.getExtPass());
  1353. return AjaxResult.success(user);
  1354. }
  1355. }
  1356. }
  1357. }
  1358. throw new RuntimeException("修改用户失败");
  1359. }
  1360. /**
  1361. * 删除用户且解绑分机
  1362. */
  1363. @PostMapping("/deleteUserOrunBindExtNum")
  1364. @ResponseBody
  1365. @Transactional
  1366. public AjaxResult deleteUserOrunBindExtNum(@RequestBody SysUser user)
  1367. {
  1368. //先解绑分机
  1369. CcExtNum extNum = new CcExtNum();
  1370. extNum.setExtNum(user.getExtNum());
  1371. extNum.setUserCode(user.getUserCode());
  1372. int updateNum = ccExtNumService.updateCcExtNumByUserCode(extNum);
  1373. if(updateNum>0){
  1374. //删除用户
  1375. int i = userService.deleteUserById(user.getUserId());
  1376. if(i>0){
  1377. return AjaxResult.success();
  1378. }
  1379. }
  1380. throw new RuntimeException("删除用户且解绑分机失败");
  1381. }
  1382. /**
  1383. * 获取手动外呼客户沟通信息
  1384. * @param phoneNum 手机号
  1385. * @param callType 类型 1呼入 2外呼
  1386. * @param uuid 通话uuid
  1387. */
  1388. @GetMapping("/getCustCommunicationInfo")
  1389. @ResponseBody
  1390. public AjaxResult getCustCommunicationInfo(@RequestParam("phoneNum") String phoneNum, @RequestParam("callType") Integer callType, @RequestParam("uuid") String uuid)
  1391. {
  1392. Map<String,Object> mmap = new HashMap<>();
  1393. CcCustInfo ccCustInfo = ccCustInfoService.selectCcCustInfoByPhoneNum(phoneNum);
  1394. if (null == ccCustInfo) {
  1395. ccCustInfo = new CcCustInfo();
  1396. ccCustInfo.setCallRecordList(new ArrayList<>());
  1397. } else {
  1398. ccCustInfo.setCallRecordList(ccCustCallRecordService.selectCcCustCallRecordList(new CcCustCallRecord().setCustId(ccCustInfo.getId())));
  1399. }
  1400. ccCustInfo.setPhoneNum(phoneNum);
  1401. mmap.put("ccCustInfo", ccCustInfo);
  1402. mmap.put("callType", callType);
  1403. mmap.put("uuid", uuid);
  1404. // 省下拉框
  1405. List<SysDivisionData> sysDivisionData = sysDivisionDataService.selectSysDivisionDataList(null);
  1406. List<SysDivisionData> provinces = sysDivisionData.stream()
  1407. .filter(d -> d.getDeep() == 0)
  1408. .collect(Collectors.toList());
  1409. mmap.put("provinces", provinces);
  1410. // 市下拉框
  1411. List<SysDivisionData> citys = sysDivisionData.stream()
  1412. .filter(d -> d.getDeep() == 1)
  1413. .collect(Collectors.toList());
  1414. mmap.put("citys", citys);
  1415. // 区县下拉框
  1416. List<SysDivisionData> countys = sysDivisionData.stream()
  1417. .filter(d -> d.getDeep() == 2)
  1418. .collect(Collectors.toList());
  1419. mmap.put("countys", countys);
  1420. return AjaxResult.success(mmap);
  1421. }
  1422. /**
  1423. * 新增保存手动外呼沟通记录
  1424. */
  1425. @PostMapping("/add/custcallrecord")
  1426. @ResponseBody
  1427. public AjaxResult addAustcallrecord(@RequestBody CcCustInfo ccCustInfo)
  1428. {
  1429. ccCustInfoService.updateCcCustInfo(ccCustInfo);
  1430. CcCustInfo custInfoBak = ccCustInfoService.selectCcCustInfoByPhoneNum(ccCustInfo.getPhoneNum());
  1431. CcCustCallRecord callRecord = JSONObject.parseObject(ccCustInfo.getCallRecord(), CcCustCallRecord.class);
  1432. callRecord.setCustId(custInfoBak.getId());
  1433. //这里改成查询
  1434. callRecord.setUserId(ccCustInfo.getOpNum());
  1435. callRecord.setUserRealName(ccCustInfo.getUserName());
  1436. callRecord.setCreateTime(new Date());
  1437. CcCustCallRecord hisCallRecord = ccCustCallRecordService.selectCcCustCallRecordByUuid(callRecord.getUuid());
  1438. if (null == hisCallRecord) {
  1439. return toAjax(ccCustCallRecordService.insertCcCustCallRecord(callRecord));
  1440. } else {
  1441. callRecord.setId(hisCallRecord.getId());
  1442. return toAjax(ccCustCallRecordService.updateCcCustCallRecord(callRecord));
  1443. }
  1444. }
  1445. /**
  1446. * 查询手动外呼记录列表
  1447. */
  1448. @PostMapping("/outboundcdrList")
  1449. @ResponseBody
  1450. public TableDataInfo outboundcdrList(@RequestBody CcOutboundCdr ccOutboundCdr)
  1451. {
  1452. startPage();
  1453. List<CcOutboundCdr> list = ccOutboundCdrService.selectCcOutboundCdrList(ccOutboundCdr);
  1454. for (CcOutboundCdr data: list) {
  1455. data.setWavFileUrl("/recordings/files?filename=" + data.getRecordFilename());
  1456. try {
  1457. if(StringUtils.isNotEmpty(data.getCallee())){
  1458. data.setCallee(DESUtil.encrypt(URLEncoder.encode(data.getCallee(), "UTF-8")));
  1459. }
  1460. } catch (Throwable e) {
  1461. throw new RuntimeException(e);
  1462. }
  1463. }
  1464. return getDataTable(list);
  1465. }
  1466. /**
  1467. * 通话记录查询接口(返回完整的数据表格式)
  1468. */
  1469. @PostMapping("/call/phone/records")
  1470. @ResponseBody
  1471. public TableDataInfo getcallPhoneRecords(HttpServletRequest req, @RequestBody ApiCallRecordQueryParams queryParams)
  1472. {
  1473. TableDataInfo tableDataInfo;
  1474. // 校验请求方ip是否合法
  1475. if (!ClientIpCheck.checkIp(req)) {
  1476. tableDataInfo = new TableDataInfo();
  1477. tableDataInfo.setTotal(0);
  1478. tableDataInfo.setCode(AjaxResult.Type.NO_AUTH.value());
  1479. tableDataInfo.setMsg("未授权,请联系系统管理员添加ip白名单!");
  1480. return tableDataInfo;
  1481. }
  1482. // 分页参数处理
  1483. if (null == queryParams.getPageNum()
  1484. && null == queryParams.getPageSize()) {
  1485. queryParams.setPageNum(1);
  1486. queryParams.setPageSize(200000);
  1487. }
  1488. if (null == queryParams.getPageNum()) {
  1489. queryParams.setPageNum(1);
  1490. }
  1491. if (null == queryParams.getPageSize()) {
  1492. queryParams.setPageSize(20);
  1493. }
  1494. // 类型(01:呼入, 02:AI外呼, 03:人工外呼)
  1495. String callType = queryParams.getCallType();
  1496. if (StringUtils.isBlank(callType)) {
  1497. tableDataInfo = new TableDataInfo();
  1498. tableDataInfo.setTotal(0);
  1499. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  1500. tableDataInfo.setMsg("callType不能为空!");
  1501. return tableDataInfo;
  1502. }
  1503. // 校验参数
  1504. if (StringUtils.isNotEmpty(queryParams.getCalloutTimeStart())
  1505. && !DateValidatorUtils.isYmdHms(queryParams.getCalloutTimeStart())) {
  1506. tableDataInfo = new TableDataInfo();
  1507. tableDataInfo.setTotal(0);
  1508. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  1509. tableDataInfo.setMsg("calloutTimeStart格式不正确,请使用'yyyy-MM-dd HH:mm:ss'格式!");
  1510. return tableDataInfo;
  1511. }
  1512. if (StringUtils.isNotEmpty(queryParams.getCalloutTimeEnd())
  1513. && !DateValidatorUtils.isYmdHms(queryParams.getCalloutTimeEnd())) {
  1514. tableDataInfo = new TableDataInfo();
  1515. tableDataInfo.setTotal(0);
  1516. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  1517. tableDataInfo.setMsg("calloutTimeStart格式不正确,请使用'yyyy-MM-dd HH:mm:ss'格式!");
  1518. return tableDataInfo;
  1519. }
  1520. // 01:呼入, 02:AI外呼, 03:人工外呼
  1521. if ("01".equals(callType)) {
  1522. return getInboundRecords(queryParams);
  1523. } else if ("02".equals(callType)) {
  1524. return getAiCallRecordsTable(queryParams);
  1525. } else if ("03".equals(callType)) {
  1526. return getOutboundRecordsTable(queryParams);
  1527. } else {
  1528. tableDataInfo = new TableDataInfo();
  1529. tableDataInfo.setTotal(0);
  1530. tableDataInfo.setCode(AjaxResult.Type.INVALID_PARAM.value());
  1531. tableDataInfo.setMsg("callType参数不合法,呼入请输入01,AI外呼请输入02,手工外呼请输入03!");
  1532. return tableDataInfo;
  1533. }
  1534. }
  1535. //ai外呼记录查询
  1536. private TableDataInfo getAiCallRecordsTable(ApiCallRecordQueryParams queryParams) {
  1537. Map<String, Object> params = new HashMap<>();
  1538. if (null != queryParams.getTimeLenStart()) {
  1539. params.put("timeLenStart", queryParams.getTimeLenStart());
  1540. }
  1541. if (null != queryParams.getTimeLenEnd()) {
  1542. params.put("timeLenEnd", queryParams.getTimeLenEnd());
  1543. }
  1544. if (null != queryParams.getCalloutTimeStart()) {
  1545. params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
  1546. }
  1547. if (null != queryParams.getCalloutTimeEnd()) {
  1548. params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
  1549. }
  1550. if (null != queryParams.getAnsweredTimeStart()) {
  1551. params.put("answeredTimeStart", queryParams.getAnsweredTimeStart());
  1552. }
  1553. if (null != queryParams.getAnsweredTimeEnd()) {
  1554. params.put("answeredTimeEnd", queryParams.getAnsweredTimeEnd());
  1555. }
  1556. if (null != queryParams.getCallEndTimeStart()) {
  1557. params.put("callEndTimeStart", queryParams.getCallEndTimeStart());
  1558. }
  1559. if (null != queryParams.getCallEndTimeEnd()) {
  1560. params.put("callEndTimeEnd", queryParams.getCallEndTimeEnd());
  1561. }
  1562. CcCallPhone ccCallPhone = new CcCallPhone();
  1563. if (null != queryParams.getBatchId() && queryParams.getBatchId() > 0) {
  1564. ccCallPhone.setBatchId(queryParams.getBatchId());
  1565. }
  1566. ccCallPhone.setUuid(queryParams.getUuid());
  1567. ccCallPhone.setTelephone(queryParams.getTelephone());
  1568. ccCallPhone.setAcdOpnum(queryParams.getExtnum());
  1569. ccCallPhone.setCallstatus(queryParams.getCallstatus());
  1570. ccCallPhone.setCallerNumber(queryParams.getCallerNumber());
  1571. ccCallPhone.setParams(params);
  1572. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  1573. List<CcCallPhone> list = ccCallPhoneService.selectCcCallPhoneYlrzList(ccCallPhone);
  1574. list.forEach(callPhoneRecord -> {
  1575. if(StringUtils.isNotBlank(callPhoneRecord.getWavfile())){
  1576. if (callPhoneRecord.getWavfile().startsWith("/")) {
  1577. callPhoneRecord.setWavfile("/recordings/files?filename=" + callPhoneRecord.getWavfile().substring(1));
  1578. }else{
  1579. callPhoneRecord.setWavfile("/recordings/files?filename=" + callPhoneRecord.getWavfile());
  1580. }
  1581. }
  1582. callPhoneRecord.setTelephone(CommonUtils.maskPhoneNumber(callPhoneRecord.getTelephone()));
  1583. callPhoneRecord.setCallerNumber(CommonUtils.maskPhoneNumber(callPhoneRecord.getCallerNumber()));
  1584. callPhoneRecord.setCallstatusName( CcCallPhone.getCallStatusName(callPhoneRecord.getCallstatus()));
  1585. callPhoneRecord.setCalloutTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getCalloutTime())));
  1586. callPhoneRecord.setAnsweredTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getAnsweredTime())));
  1587. callPhoneRecord.setCallEndTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getCallEndTime())));
  1588. callPhoneRecord.setTimeLenSec(DateUtils.formatTimeLength(callPhoneRecord.getTimeLen()/1000));
  1589. });
  1590. return getDataTable(list);
  1591. }
  1592. //人工外呼记录查询
  1593. private TableDataInfo getOutboundRecordsTable(ApiCallRecordQueryParams queryParams) {
  1594. Map<String, Object> params = new HashMap<>();
  1595. if (null != queryParams.getTimeLenStart()) {
  1596. params.put("timeLenStart", queryParams.getTimeLenStart());
  1597. }
  1598. if (null != queryParams.getTimeLenEnd()) {
  1599. params.put("timeLenEnd", queryParams.getTimeLenEnd());
  1600. }
  1601. if (null != queryParams.getCalloutTimeStart()) {
  1602. params.put("calloutTimeStart", queryParams.getCalloutTimeStart());
  1603. }
  1604. if (null != queryParams.getCalloutTimeEnd()) {
  1605. params.put("calloutTimeEnd", queryParams.getCalloutTimeEnd());
  1606. }
  1607. if (null != queryParams.getAnsweredTimeStart()) {
  1608. params.put("answeredTimeStart", queryParams.getAnsweredTimeStart());
  1609. }
  1610. if (null != queryParams.getAnsweredTimeEnd()) {
  1611. params.put("answeredTimeEnd", queryParams.getAnsweredTimeEnd());
  1612. }
  1613. if (null != queryParams.getEndTimeStart()) {
  1614. params.put("endTimeStart", queryParams.getEndTimeStart());
  1615. }
  1616. if (null != queryParams.getEndTimeEnd()) {
  1617. params.put("endTimeEnd", queryParams.getEndTimeEnd());
  1618. }
  1619. CcCallPhone ccCallPhone = new CcCallPhone();
  1620. if (null != queryParams.getBatchId() && queryParams.getBatchId() > 0) {
  1621. ccCallPhone.setBatchId(queryParams.getBatchId());
  1622. }
  1623. CcOutboundCdr outboundCdr = new CcOutboundCdr();
  1624. outboundCdr.setUuid(queryParams.getUuid());
  1625. outboundCdr.setCaller(queryParams.getTelephone());
  1626. outboundCdr.setOpnum(queryParams.getExtnum());
  1627. outboundCdr.setParams(params);
  1628. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  1629. List<CcOutboundCdr> list = outboundCdrService.selectCcOutboundCdrYlrzList(outboundCdr);
  1630. list.forEach(callPhoneRecord -> {
  1631. if(StringUtils.isNotBlank(callPhoneRecord.getRecordFilename())){
  1632. if (callPhoneRecord.getRecordFilename().startsWith("/")) {
  1633. callPhoneRecord.setRecordFilename("/recordings/files?filename=" + callPhoneRecord.getRecordFilename().substring(1));
  1634. }else{
  1635. callPhoneRecord.setWavFileUrl("/recordings/files?filename=" + callPhoneRecord.getRecordFilename());
  1636. }
  1637. callPhoneRecord.setStartTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getStartTime())));
  1638. callPhoneRecord.setAnsweredTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getAnsweredTime())));
  1639. callPhoneRecord.setEndTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(callPhoneRecord.getEndTime())));
  1640. callPhoneRecord.setTimeLenSec(DateUtils.formatTimeLength(callPhoneRecord.getTimeLen()/1000));
  1641. callPhoneRecord.setTimeLenValidStr(DateUtils.formatTimeLength(callPhoneRecord.getTimeLenValid()/1000));
  1642. }
  1643. callPhoneRecord.setCallee(CommonUtils.maskPhoneNumber(callPhoneRecord.getCallee()));
  1644. });
  1645. return getDataTable(list);
  1646. }
  1647. /**
  1648. * 获取外呼网关列表接口
  1649. * purposes 1手动外呼电话条,2AI外呼,3不限制
  1650. * @param queryParams 网关参数
  1651. * @param req
  1652. */
  1653. @PostMapping("/gateway/myList")
  1654. @ResponseBody
  1655. public TableDataInfo getGatewayMyList(@RequestBody CcGateways queryParams, HttpServletRequest req){
  1656. // 校验请求方ip是否合法
  1657. if (!ClientIpCheck.checkIp(req)) {
  1658. TableDataInfo tableDataInfo;
  1659. tableDataInfo = new TableDataInfo();
  1660. tableDataInfo.setTotal(0);
  1661. tableDataInfo.setCode(AjaxResult.Type.NO_AUTH.value());
  1662. tableDataInfo.setMsg("未授权,请联系系统管理员添加ip白名单!");
  1663. return tableDataInfo;
  1664. }
  1665. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  1666. return getDataTable(ccGatewaysService.selectCcGatewaysList(queryParams));
  1667. }
  1668. /**
  1669. * 根据通话id集合查询uuid不为空的自动外呼数据
  1670. */
  1671. @PostMapping( "/getCcCallPhoneByIds")
  1672. @ResponseBody
  1673. public AjaxResult getCcCallPhoneByIds(@RequestBody List<String> callPhoneIds)
  1674. {
  1675. if(callPhoneIds==null){
  1676. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "callPhoneIds不能为空!", "");
  1677. }
  1678. List<CcCallPhone> list = ccCallPhoneService.selectCcCallPhoneListByIds(callPhoneIds);
  1679. if(!CollectionUtils.isEmpty(list)){
  1680. list.forEach(callPhoneRecord -> {
  1681. callPhoneRecord.setBizJson("");
  1682. try {
  1683. if(StringUtils.isNotEmpty(callPhoneRecord.getTelephone())){
  1684. callPhoneRecord.setTelephone(DESUtil.encrypt(URLEncoder.encode(callPhoneRecord.getTelephone(), "UTF-8")));
  1685. }else{
  1686. callPhoneRecord.setTelephone("");
  1687. }
  1688. if(StringUtils.isNotEmpty(callPhoneRecord.getCallerNumber())){
  1689. callPhoneRecord.setCallerNumber(DESUtil.encrypt(URLEncoder.encode(callPhoneRecord.getCallerNumber(), "UTF-8")));
  1690. }else{
  1691. callPhoneRecord.setCallerNumber("");
  1692. }
  1693. } catch (UnsupportedEncodingException e) {
  1694. }
  1695. });
  1696. }
  1697. return AjaxResult.success(list);
  1698. }
  1699. /**
  1700. * 根据UUID查询自动外呼对话详情
  1701. */
  1702. @PostMapping( "/getCcCallPhoneByUuid")
  1703. @ResponseBody
  1704. public AjaxResult getCcCallPhoneByUuid(@RequestBody CcCallPhone callPhone)
  1705. {
  1706. if(callPhone==null || StringUtils.isBlank(callPhone.getUuid())){
  1707. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "callPhone或uuid不能为空!", "");
  1708. }
  1709. return AjaxResult.success(ccCallPhoneService.selectCcCallPhoneDialogueByUuid(callPhone.getUuid()));
  1710. }
  1711. /**
  1712. * 修改任务
  1713. * @param ccCallTask
  1714. * @return
  1715. */
  1716. @PostMapping("/editTask")
  1717. @ResponseBody
  1718. public AjaxResult editTask(@RequestBody CcCallTask ccCallTask)
  1719. {
  1720. if ("acd".equals(ccCallTask.getAiTransferType())) {
  1721. ccCallTask.setAiTransferData(ccCallTask.getAiTransferGroupId());
  1722. } else if ("extension".equals(ccCallTask.getAiTransferType())) {
  1723. ccCallTask.setAiTransferData(ccCallTask.getAiTransferExtNumber());
  1724. } else if ("gateway".equals(ccCallTask.getAiTransferType())) {
  1725. JSONObject aiTransferData = new JSONObject();
  1726. aiTransferData.put("gatewayId", ccCallTask.getAiTransferGatewayId());
  1727. aiTransferData.put("destNumber", ccCallTask.getAiTransferGatewayDestNumber());
  1728. ccCallTask.setAiTransferData(JSONObject.toJSONString(aiTransferData));
  1729. }
  1730. return toAjax(ccCallTaskService.updateCcCallTask(ccCallTask));
  1731. }
  1732. /**
  1733. * 获取音色分页列表
  1734. */
  1735. @PostMapping("/voicecodePage")
  1736. @ResponseBody
  1737. public TableDataInfo voicecodePage(@RequestBody CcTtsAliyun queryParams)
  1738. {
  1739. if(queryParams==null){
  1740. queryParams = new CcTtsAliyun();
  1741. }
  1742. if(queryParams.getPageNum()==null){
  1743. queryParams.setPageNum(1);
  1744. }
  1745. if(queryParams.getPageSize()== null){
  1746. queryParams.setPageSize(10);
  1747. }
  1748. startPage(queryParams.getPageNum(), queryParams.getPageSize());
  1749. // 获取音色列表
  1750. List<CcTtsAliyun> list = ccTtsAliyunService.selectCcTtsAliyunList(queryParams);
  1751. return getDataTable(list);
  1752. }
  1753. /**
  1754. * 追加外呼名单(不自动启动任务,数据加密传输)
  1755. * @param encryptedData
  1756. */
  1757. @PostMapping(value ="/import/autoCallData")
  1758. @ResponseBody
  1759. public AjaxResult addCommonCallList(@RequestBody String encryptedData) {
  1760. // 解密数据
  1761. String decryptedJson;
  1762. try {
  1763. //base64特殊处理
  1764. encryptedData = URLDecoder.decode(encryptedData, "UTF-8").replaceAll("=+$", "");
  1765. decryptedJson = DESUtil.decrypt(encryptedData);
  1766. } catch (Throwable e) {
  1767. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数encryptedData解密失败", "");
  1768. }
  1769. // 2. 反序列化为 Java 对象
  1770. CommonCallListModel commonCallListModel = JSONObject.parseObject(decryptedJson, CommonCallListModel.class);
  1771. Long batchId = commonCallListModel.getBatchId();
  1772. if (null == batchId) {
  1773. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不能为空", "");
  1774. }
  1775. if (CollectionUtils.isEmpty(commonCallListModel.getPhoneList())) {
  1776. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数phoneList不能为空", "");
  1777. }
  1778. // 获取任务
  1779. CcCallTask ccCallTask = callTaskService.selectCcCallTaskByBatchId(batchId);
  1780. if (null == ccCallTask) {
  1781. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "参数batchId不合法,请输入正确的batchId", "");
  1782. }
  1783. // 通知类的通知内容必填
  1784. if (ccCallTask.getTaskType() == 2) {
  1785. for (CommonPhoneModel commonPhoneModel : commonCallListModel.getPhoneList()) {
  1786. if (StringUtils.isBlank(commonPhoneModel.getNoticeContent())) {
  1787. return AjaxResult.error(AjaxResult.Type.INVALID_PARAM, "号码" + commonPhoneModel.getPhoneNum() + "的noticeContent不能为空!", "");
  1788. }
  1789. }
  1790. }
  1791. // 追加名单
  1792. int successCount = 0;
  1793. List<CcCallPhone> callPhoneList = new ArrayList<>();
  1794. for (CommonPhoneModel commonPhoneModel : commonCallListModel.getPhoneList()) {
  1795. String phoneNum = commonPhoneModel.getPhoneNum();
  1796. if (StringUtils.isBlank(phoneNum)) {
  1797. continue;
  1798. }
  1799. CcCallPhone callPhone = buildCcCallPhone(ccCallTask, phoneNum, commonPhoneModel.getBizJson());
  1800. callPhone.setTtsText(commonPhoneModel.getNoticeContent());
  1801. callPhoneList.add(callPhone);
  1802. successCount ++;
  1803. if (callPhoneList.size() >= 200) {
  1804. ccCallPhoneService.batchInsertCcCallPhone(callPhoneList);
  1805. callPhoneList = new ArrayList<>();
  1806. }
  1807. }
  1808. if (!callPhoneList.isEmpty()) {
  1809. ccCallPhoneService.batchInsertCcCallPhone(callPhoneList);
  1810. }
  1811. log.info("成功追加" + successCount + "个名单");
  1812. if(!CollectionUtils.isEmpty(callPhoneList)){
  1813. callPhoneList.forEach(callPhoneRecord -> {
  1814. callPhoneRecord.setBizJson("");
  1815. try {
  1816. if(StringUtils.isNotEmpty(callPhoneRecord.getTelephone())){
  1817. callPhoneRecord.setTelephone(DESUtil.encrypt(URLEncoder.encode(callPhoneRecord.getTelephone(), "UTF-8")));
  1818. }else{
  1819. callPhoneRecord.setTelephone("");
  1820. }
  1821. if(StringUtils.isNotEmpty(callPhoneRecord.getCallerNumber())){
  1822. callPhoneRecord.setCallerNumber(DESUtil.encrypt(URLEncoder.encode(callPhoneRecord.getCallerNumber(), "UTF-8")));
  1823. }else{
  1824. callPhoneRecord.setCallerNumber("");
  1825. }
  1826. } catch (UnsupportedEncodingException e) {
  1827. }
  1828. });
  1829. }
  1830. return AjaxResult.success("成功追加" + successCount + "个名单",callPhoneList);
  1831. }
  1832. }