鄂尔多斯-招源科技

CallPlanController.cs 68KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  1. using CallCenter.Utility;
  2. using CallCenterApi.DB;
  3. using CallCenterApi.Interface.Controllers.Base;
  4. using CallCenterApi.Interface.Models.Dto;
  5. using CallCenterApi.Interface.Models.Filter;
  6. using CallCenterApi.Interface.Models.Input;
  7. using CallCenterApi.Model;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Data;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Web;
  15. using System.Web.Mvc;
  16. namespace CallCenterApi.Interface.Controllers.callout
  17. {
  18. public class CallPlanController : BaseController
  19. {
  20. private readonly BLL.T_CTI_Task taskBLL = new BLL.T_CTI_Task();
  21. private readonly BLL.T_Call_TaskTelNum taskTellNumBLL = new BLL.T_Call_TaskTelNum();
  22. private readonly BLL.T_Sys_DictionaryValue dictValueBLL = new BLL.T_Sys_DictionaryValue();
  23. private readonly BLL.T_CTI_TaskAgent taskAgentBLL = new BLL.T_CTI_TaskAgent();
  24. private readonly BLL.T_Sys_UserAccount userAccount = new BLL.T_Sys_UserAccount();
  25. private readonly BLL.T_CTI_TaskRecord taskRecordBLL = new BLL.T_CTI_TaskRecord();
  26. private readonly BLL.CallResult callResultBLL = new BLL.CallResult();
  27. private readonly BLL.T_CTI_TaskDaily taskDailyBLL = new BLL.T_CTI_TaskDaily();
  28. private readonly BLL.T_CTI_TaskPhonePart taskPhonePartBLL = new BLL.T_CTI_TaskPhonePart();
  29. private readonly BLL.T_Sys_SeatGroup seatGroupBLL = new BLL.T_Sys_SeatGroup();
  30. private readonly BLL.T_Sys_SystemConfig systemConfigBLL = new BLL.T_Sys_SystemConfig();
  31. private readonly BLL.T_Call_PageField pageFieldBLL = new BLL.T_Call_PageField();
  32. private readonly BLL.T_Ask_PagerInfo pagerInfoBLL = new BLL.T_Ask_PagerInfo();
  33. private readonly BLL.T_Call_Answers ansBLL = new BLL.T_Call_Answers();
  34. private readonly BLL.T_Sys_Department departmentBLL = new BLL.T_Sys_Department();
  35. private readonly BLL.T_Ask_Question questionBLL = new BLL.T_Ask_Question();
  36. private readonly BLL.T_Ask_QuestionItems questionItemBLL = new BLL.T_Ask_QuestionItems();
  37. #region 外呼任务
  38. /// <summary>
  39. /// 获取列表
  40. /// </summary>
  41. /// <param name="filter"></param>
  42. /// <returns></returns>
  43. public ActionResult GetList(FilterCallPlan filter)
  44. {
  45. //if (!Request.IsAuthenticated)
  46. // return NoToken("未知错误,请重新登录");
  47. var sql = " and State>=0 and TaskType=" + filter.TaskType;
  48. if (!string.IsNullOrWhiteSpace(filter.Name))
  49. {
  50. sql += " and (TaskName like '%" + filter.Name.Trim() + "%' ) ";
  51. }
  52. var roleid = CurrentUser.UserData.F_RoleId;
  53. var deptid = CurrentUser.UserData.F_DeptId;
  54. var deptCode = CurrentUser.UserData.F_DeptCode;
  55. var usercode = CurrentUser.UserData.F_UserCode;
  56. if (roleid != 0)
  57. {
  58. if (roleid != 17)
  59. {
  60. if (deptCode.Replace("|0|1|", "").Length > 0)
  61. {
  62. sql += " and DeptId in (select F_DeptId from T_Sys_Department where F_DeptCode like '" + deptCode + "%') ";
  63. }
  64. }
  65. }
  66. var recordCount = 0;
  67. var dt = BLL.PagerBLL.GetListPager(
  68. "T_CTI_Task",
  69. "TaskID",
  70. "*",
  71. sql,
  72. "ORDER BY AddTime desc",
  73. filter.PageSize,
  74. filter.PageIndex,
  75. true,
  76. out recordCount);
  77. List<Model.T_CTI_Task> modelList = new BLL.T_CTI_Task().DataTableToList(dt);
  78. var list = new List<CallPlanDto>();
  79. //查询坐席组
  80. var agentGroupList = seatGroupBLL.DataTableToList(seatGroupBLL.GetList("").Tables[0]);
  81. //查询坐席
  82. var agentList = userAccount.DataTableToList(userAccount.GetList(" F_DeleteFlag=0 ").Tables[0]);
  83. //查询部门
  84. var deptList = departmentBLL.DataTableToList(departmentBLL.GetList(" F_State=1 ").Tables[0]);
  85. foreach (var model in modelList)
  86. {
  87. //计算数据
  88. string calledRate = "0";
  89. var allcount = model.y_HMCount ?? 0;
  90. float calledcount = model.y_HCCount ?? 0;
  91. calledRate = allcount == 0 ? "" : (calledcount / allcount * 100).ToString("f2") + "%";
  92. string connectedRate = "0";
  93. float connected = model.y_YJCount ?? 0;
  94. connectedRate = calledcount == 0 ? "0" : (connected / calledcount * 100).ToString("f2") + "%";
  95. var taskTellNumDt = taskTellNumBLL.GetList(" F_HCState=1 and F_YJState=1 and F_UserId>0 and F_TaskId=" + model.TaskID).Tables[0];
  96. float connectedAgentCount = taskTellNumDt?.Rows.Count ?? 0;
  97. var connectedAgentRate = "0";
  98. connectedAgentRate = connected == 0 ? "0" : (connectedAgentCount / connected * 100).ToString("f2") + "%";
  99. var agentGroupStr = model.AgentGroupId == -999 ? "不转坐席" : "";
  100. var agentGroup = agentGroupList.SingleOrDefault(x => x.F_ZXZID == model.AgentGroupId);
  101. var agentCount = agentList.Where(x => x.F_SeartGroupID == (agentGroup?.F_ZXZID ?? 0)).Count();
  102. var dept = deptList.SingleOrDefault(y => y.F_DeptId == model.DeptId);
  103. list.Add(new CallPlanDto
  104. {
  105. id = model.TaskID,
  106. name = model.TaskName,
  107. tasktype = model.TaskType == 1 ? "点击外呼" : "自动外呼",
  108. deptname = dept?.F_DeptName ?? "",
  109. state = Enum.GetName(typeof(EnumTaskState), (model.State ?? -1)),
  110. addtime = Convert.ToDateTime(model.AddTime).ToString("yyyy-MM-dd HH:mm:ss"),
  111. talkid = model.y_TkModelId ?? 0,
  112. pre = model.Pre, //线路前缀
  113. concurrencytype = model.ConcurrencyType,
  114. concurrency = model.Concurrency,
  115. planstartdate = model.PlanStartDate.ToString("yyyy-MM-dd"),
  116. planenddate = model.PlanEndDate.ToString("yyyy-MM-dd"),
  117. starttime1 = model.StartTime1.ToString("HH:mm:ss"),
  118. endtime1 = model.EndTime1.ToString("HH:mm:ss"),
  119. starttime2 = model.StartTime2.ToString("HH:mm:ss"),
  120. endtime2 = model.EndTime2.ToString("HH:mm:ss"),
  121. agentgroup = agentGroup?.F_ZXZName ?? agentGroupStr,//坐席组
  122. agentgroupid = model.AgentGroupId,
  123. agentcount = agentCount,//坐席组人数
  124. allcount = model.y_HMCount ?? 0, //号码总数
  125. calledcount = model.y_HCCount ?? 0, //已呼个数
  126. calledrate = calledRate, //已完成百分比
  127. callleftcount = (int)(allcount - calledcount), //剩余个数
  128. connected = model.y_YJCount ?? 0, //总应答数
  129. connectedrate = connectedRate, //应答率
  130. connectedagentcount = (int)connectedAgentCount, //转坐席数
  131. connectedagentrate = connectedAgentRate, //转坐席率
  132. });
  133. }
  134. var obj = new
  135. {
  136. rows = list,
  137. total = recordCount
  138. };
  139. return Content(obj.ToJson());
  140. }
  141. /// <summary>
  142. /// 获取实体
  143. /// </summary>
  144. /// <param name="id"></param>
  145. /// <returns></returns>
  146. public ActionResult GetModel(int id)
  147. {
  148. //if (!Request.IsAuthenticated)
  149. // return NoToken("未知错误,请重新登录");
  150. var model = taskBLL.GetModel(id);
  151. if (model == null)
  152. return Error("预测外呼任务不存在");
  153. //计算数据
  154. string calledRate = "0";
  155. var allcount = model.y_HMCount ?? 0;
  156. float calledcount = model.y_HCCount ?? 0;
  157. calledRate = allcount == 0 ? "" : (calledcount / allcount * 100).ToString("f2") + "%";
  158. string connectedRate = "0";
  159. float connected = model.y_YJCount ?? 0;
  160. connectedRate = calledcount == 0 ? "0" : (connected / calledcount * 100).ToString("f2") + "%";
  161. var taskTellNumDt = taskTellNumBLL.GetList(" F_HCState=1 and F_YJState=1 and F_UserId>0 and F_TaskId=" + model.TaskID).Tables[0];
  162. float connectedAgentCount = taskTellNumDt?.Rows.Count ?? 0;
  163. var connectedAgentRate = "0";
  164. connectedAgentRate = connected == 0 ? "0" : (connectedAgentCount / connected * 100).ToString("f2") + "%";
  165. //查询坐席组
  166. var agentGroupList = seatGroupBLL.DataTableToList(seatGroupBLL.GetList("").Tables[0]);
  167. //查询坐席
  168. var agentList = userAccount.DataTableToList(userAccount.GetList(" F_DeleteFlag=0 ").Tables[0]);
  169. var agentGroupStr = model.AgentGroupId == -999 ? "不转坐席" : "";
  170. var agentGroup = agentGroupList.SingleOrDefault(x => x.F_ZXZID == model.AgentGroupId);
  171. var agentCount = agentList.Where(x => x.F_SeartGroupID == (agentGroup?.F_ZXZID ?? 0)).Count();
  172. return Success("获取成功", new CallPlanDto
  173. {
  174. id = model.TaskID,
  175. name = model.TaskName,
  176. tasktype = model.TaskType == 1 ? "点击外呼" : "自动外呼",
  177. state = "暂停",
  178. addtime = Convert.ToDateTime(model.AddTime).ToString("yyyy-MM-dd HH:mm:ss"),
  179. talkid = model.y_TkModelId ?? 0,
  180. pre = model.Pre, //线路前缀
  181. recordpathid = model.RecordFileId,
  182. concurrencytypestr = model.ConcurrencyType == 0 ? "并发数" : "并发速率",
  183. concurrencytype = model.ConcurrencyType,
  184. concurrency = model.Concurrency,
  185. planstartdate = model.PlanStartDate.ToString("yyyy-MM-dd"),
  186. planenddate = model.PlanEndDate.ToString("yyyy-MM-dd"),
  187. starttime1 = model.StartTime1.ToString("HH:mm"),
  188. endtime1 = model.EndTime1.ToString("HH:mm"),
  189. starttime2 = model.StartTime2.ToString("HH:mm"),
  190. endtime2 = model.EndTime2.ToString("HH:mm"),
  191. agentgroup = agentGroup?.F_ZXZName ?? agentGroupStr,//坐席组
  192. agentgroupid = model.AgentGroupId,
  193. agentcount = agentCount,//坐席组人数
  194. allcount = model.y_HMCount ?? 0, //号码总数
  195. calledcount = model.y_HCCount ?? 0, //已呼个数
  196. calledrate = calledRate, //已完成百分比
  197. callleftcount = (int)(allcount - calledcount), //剩余个数
  198. connected = model.y_YJCount ?? 0, //总应答数
  199. connectedrate = connectedRate, //应答率
  200. connectedagentcount = (int)connectedAgentCount, //转坐席数
  201. connectedagentrate = connectedAgentRate, //转坐席率
  202. });
  203. }
  204. /// <summary>
  205. /// 添加/修改
  206. /// </summary>
  207. /// <param name="input"></param>
  208. /// <returns></returns>
  209. public ActionResult CreateOrUpdate(CallPlanInput input)
  210. {
  211. //if (!Request.IsAuthenticated)
  212. // return NoToken("未知错误,请重新登录");
  213. var model = new Model.T_CTI_Task();
  214. if (input.Id <= 0)
  215. {
  216. model.TaskName = input.Name;
  217. model.TaskType = input.Type;
  218. model.AgentGroupId = input.AgentGroupId;
  219. model.y_TkModelId = input.PagerId;
  220. model.Pre = input.Pre;
  221. if (input.ConcurrencyType == 0)
  222. {
  223. var num = 0;
  224. if (!int.TryParse(input.Concurrency.ToString(), out num))
  225. return Error("并发数必须为不小于1的整数");
  226. input.Concurrency = (int)input.Concurrency;
  227. }
  228. if (input.Concurrency < 1)
  229. return Error("输入的并发数和进号速率必须不小于1");
  230. model.ConcurrencyType = input.ConcurrencyType;
  231. model.Concurrency = input.ConcurrencyType == 0 ? (int)input.Concurrency : input.Concurrency;
  232. model.RecordFileId = input.RecordPathId;
  233. model.DeptId = input.DeptId <= 0 ? CurrentUser.UserData.F_DeptId : input.DeptId;
  234. model.y_HMCount = 0;
  235. model.y_HCCount = 0;
  236. model.y_YJCount = 0;
  237. model.y_HTCount = 0;
  238. model.TrunkGroupID = 0;
  239. model.CallType = 1;
  240. model.State = 2;
  241. model.AddTime = DateTime.Now;
  242. model.y_PSort = 2;
  243. model.y_SXH = 0;
  244. model.y_FPCount = 0;
  245. model.y_HSCount = 0;
  246. model.y_OkCount = 0;
  247. model.y_RFCount = 0;
  248. model.y_ConsCount = 0;
  249. model.y_InvlCount = 0;
  250. model.y_NoAnswerCount = 0;
  251. model.y_ShutDownCount = 0;
  252. model.PlanStartDate = input.PlanStartDate ?? DateTime.Now;
  253. model.PlanEndDate = input.PlanEndDate?.AddDays(1).AddSeconds(-1) ?? DateTime.Now;
  254. model.StartTime1 = input.StartTime1 ?? DateTime.Now;
  255. model.EndTime1 = input.EndTime1 ?? DateTime.Now;
  256. model.StartTime2 = input.StartTime2 ?? DateTime.Now;
  257. model.EndTime2 = input.EndTime2 ?? DateTime.Now;
  258. var taskId = taskBLL.Add(model);
  259. if (taskId > 0)
  260. {
  261. try
  262. {
  263. if (input.TempId > 0)
  264. {
  265. var fields = pageFieldBLL.DataTableToList(pageFieldBLL.GetList($" F_TaskId=0 and F_TempId={input.TempId}").Tables[0]);
  266. foreach (var item in fields)
  267. {
  268. pageFieldBLL.Add(new T_Call_PageField()
  269. {
  270. F_Name = item.F_Name,
  271. F_FeildId = item.F_FeildId,
  272. F_TaskId = (int)taskId,
  273. F_Sort = item.F_Sort,
  274. F_DBFieldlName = item.F_DBFieldlName
  275. });
  276. }
  277. }
  278. else
  279. {
  280. pageFieldBLL.UpdateByTaskId(taskId);
  281. }
  282. model.TaskID = taskId;
  283. DataTable dt = taskTellNumBLL.GetTableDesign();
  284. switch (input.ImportType)
  285. {
  286. case 1: //从文本文件导入
  287. var file = Request.Files[0];
  288. using (StreamReader sr = new StreamReader(file.InputStream))
  289. {
  290. String line;
  291. while ((line = sr.ReadLine()) != null)
  292. {
  293. var row = dt.NewRow();
  294. row["F_TaskId"] = model.TaskID;
  295. row["F_Phone"] = line.ToString();
  296. dt.Rows.Add(row);
  297. }
  298. }
  299. break;
  300. case 2: //从文本框中导入
  301. if (string.IsNullOrWhiteSpace(input.PhoneList))
  302. return Error("号码不可以为空");
  303. var arr = input.PhoneList.Split(new char[] { '\r', '\n', ',', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
  304. foreach (var p in arr)
  305. {
  306. var row = dt.NewRow();
  307. row["F_TaskId"] = model.TaskID;
  308. row["F_Phone"] = p;
  309. dt.Rows.Add(row);
  310. }
  311. break;
  312. case 3: //从号码段导入
  313. if (string.IsNullOrWhiteSpace(input.PhoneStr))
  314. return Error("号码不可以为空");
  315. double phoneInt = 0;
  316. if (!double.TryParse(input.PhoneStr, out phoneInt))
  317. return Error("请输入正确的手机号码段");
  318. phoneInt = phoneInt * 10000;
  319. for (int i = 1; i < 10000; i++)
  320. {
  321. var row = dt.NewRow();
  322. row["F_TaskId"] = model.TaskID;
  323. row["F_Phone"] = phoneInt + i;
  324. dt.Rows.Add(row);
  325. }
  326. break;
  327. case 4: //从Excel中导入
  328. string[] strArr = input.SelectIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  329. var idArr = strArr.Select(x => Convert.ToInt32(x)).ToArray();
  330. var fieldList = pageFieldBLL.DataTableToList(pageFieldBLL.GetList($"F_ID in ({string.Join(",", idArr)})").Tables[0]);
  331. NPOIHelper npoi = new NPOIHelper();
  332. var dtExcel = npoi.ExcelToTable(input.FilePath, 0);
  333. for (int i = 0; i < dtExcel.Rows.Count; i++)
  334. {
  335. var row = dt.NewRow();
  336. for (int j = 0; j < dtExcel.Columns.Count; j++)
  337. {
  338. if (fieldList.Count < (j + 1))
  339. break;
  340. row["F_TaskId"] = model.TaskID;
  341. var field = fieldList.SingleOrDefault(x => x.F_Id == idArr[j]);
  342. row[field.F_DBFieldlName] = dtExcel.Rows[i][j];
  343. }
  344. dt.Rows.Add(row);
  345. }
  346. break;
  347. }
  348. if (input.CheckFilter1)
  349. {
  350. PhoneNumFilter(dt);
  351. }
  352. if (input.CheckFilter2)
  353. {
  354. PhoneNumFilterMonth(dt);
  355. }
  356. taskTellNumBLL.SqlBulkCopy(dt);
  357. model.y_HMCount = dt.Rows.Count;
  358. if (taskBLL.Update(model))
  359. return Success("添加成功");
  360. return Error("添加失败");
  361. }
  362. catch (Exception e)
  363. {
  364. return Error(e.Message);
  365. }
  366. }
  367. return Error("添加失败");
  368. }
  369. model = taskBLL.GetModel(input.Id);
  370. if (model == null)
  371. return Error("当前外呼任务不存在");
  372. model.TaskName = input.Name;
  373. model.TaskType = input.Type;
  374. model.AgentGroupId = input.AgentGroupId;
  375. model.y_TkModelId = input.PagerId;
  376. //model.Pre = input.Pre;
  377. if (input.ConcurrencyType == 0)
  378. {
  379. var num = 0;
  380. if (!int.TryParse(input.Concurrency.ToString(), out num))
  381. return Error("并发数必须为不小于1的整数");
  382. input.Concurrency = (int)input.Concurrency;
  383. }
  384. if (input.Concurrency < 1)
  385. return Error("输入的并发数和进号速率必须不小于1");
  386. model.ConcurrencyType = input.ConcurrencyType;
  387. model.Concurrency = input.ConcurrencyType == 0 ? (int)input.Concurrency : input.Concurrency;
  388. model.PlanStartDate = input.PlanStartDate ?? DateTime.Now;
  389. model.PlanEndDate = input.PlanEndDate?.AddDays(1).AddSeconds(-1) ?? DateTime.Now;
  390. model.StartTime1 = input.StartTime1 ?? DateTime.Now;
  391. model.EndTime1 = input.EndTime1 ?? DateTime.Now;
  392. model.StartTime2 = input.StartTime2 ?? DateTime.Now;
  393. model.EndTime2 = input.EndTime2 ?? DateTime.Now;
  394. model.RecordFileId = input.RecordPathId;
  395. if (taskBLL.Update(model))
  396. return Success("修改成功");
  397. return Error("修改失败");
  398. }
  399. /// <summary>
  400. /// 更新状态
  401. /// </summary>
  402. /// <param name="id"></param>
  403. /// <param name="state"></param>
  404. /// <returns></returns>
  405. public ActionResult UpdateState(int[] ids, int state)
  406. {
  407. //if (!Request.IsAuthenticated)
  408. // return NoToken("未知错误,请重新登录");
  409. var sql = "";
  410. if (ids.Length > 0)
  411. {
  412. sql += " TaskID in (" + string.Join(",", ids) + ") ";
  413. }
  414. var model = taskBLL.GetList(sql).Tables[0];
  415. foreach (DataRow item in model.Rows)
  416. {
  417. if (Convert.ToInt32(item["State"]) == -1)
  418. return Error("选择的任务存在已删除状态,执行失败");
  419. }
  420. if (taskBLL.UpdateStateBatch(sql, state))
  421. return Success("修改成功");
  422. return Error("修改失败");
  423. }
  424. /// <summary>
  425. /// 更新并发数
  426. /// </summary>
  427. /// <param name="id"></param>
  428. /// <param name="concurrency"></param>
  429. /// <returns></returns>
  430. public ActionResult UpdateConcurrency(long id, float concurrency, int concurrencyType = 0)
  431. {
  432. //if (!Request.IsAuthenticated)
  433. // return NoToken("未知错误,请重新登录");
  434. var model = taskBLL.GetModel(id);
  435. if (model == null)
  436. return Error("该外呼任务不存在");
  437. if (concurrencyType == 0)
  438. {
  439. var num = 0;
  440. if (!int.TryParse(concurrency.ToString(), out num))
  441. return Error("并发数必须为不小于1的整数");
  442. concurrency = num;
  443. }
  444. if (concurrency < 1)
  445. return Error("输入的并发数和进号速率必须不小于1");
  446. model.ConcurrencyType = concurrencyType;
  447. model.Concurrency = concurrency;
  448. if (taskBLL.Update(model))
  449. return Success("修改成功");
  450. return Error("修改失败");
  451. }
  452. /// <summary>
  453. /// 清空号码
  454. /// </summary>
  455. /// <returns></returns>
  456. public ActionResult ClearPhone(long id)
  457. {
  458. //if (!Request.IsAuthenticated)
  459. // return NoToken("未知错误,请重新登录");
  460. var num = taskBLL.DeletePhoneByTaskId(id);
  461. if (num > 0)
  462. {
  463. var task = taskBLL.GetModel(id);
  464. return Success("删除成功");
  465. }
  466. return Error("删除失败");
  467. }
  468. /// <summary>
  469. /// 去除号码前缀
  470. /// </summary>
  471. /// <param name="callId"></param>
  472. /// <param name="tel"></param>
  473. /// <returns></returns>
  474. public ActionResult RemovePre(string callId, string tel)
  475. {
  476. //if (!Request.IsAuthenticated)
  477. // return NoToken("未知错误,请重新登录");
  478. var callResult = callResultBLL.GetModel(callId);
  479. if (callResult == null)
  480. return Error("通话记录未正常添加");
  481. var task = taskBLL.GetModel(callResult.TaskId);
  482. if (task == null)
  483. return Error("任务不存在");
  484. var len = task.Pre.Length;
  485. return Success("去除成功", tel.Substring(len));
  486. }
  487. /// <summary>
  488. /// 更新外呼任务状态
  489. /// </summary>
  490. /// <returns></returns>
  491. public ActionResult UpdateCallPlanState()
  492. {
  493. StringBuilder sb = new StringBuilder();
  494. var log = LogFactory.GetLogger(this.GetType().ToString());
  495. var list = taskBLL.DataTableToList(taskBLL.GetList(" state>=0 ").Tables[0]);
  496. foreach (var task in list)
  497. {
  498. if (task.PlanStartDate <= DateTime.Now && task.PlanEndDate > DateTime.Now)
  499. {
  500. if (task.State == 2)
  501. {
  502. if (task.PlanStartDate < DateTime.Now && DateTime.Now < task.StartTime1)
  503. {
  504. task.State = 0;
  505. if (!taskBLL.Update(task))
  506. return Error($"更新自动外呼任务状态为0=待处理失败,ID={task.TaskID},Name={task.TaskName}");
  507. log.Info($"更新自动外呼任务状态为0=待处理成功,ID={task.TaskID},Name={task.TaskName}");
  508. }
  509. }
  510. if (task.State == 0)
  511. {
  512. if ((DateTime.Now >= task.StartTime1 && DateTime.Now < task.EndTime1) || (DateTime.Now > task.StartTime2 && DateTime.Now < task.EndTime2))
  513. {
  514. task.State = 1;
  515. if (!taskBLL.Update(task))
  516. return Error($"更新自动外呼任务状态为1=处理中失败,ID={task.TaskID},Name={task.TaskName}");
  517. log.Info($"更新自动外呼任务状态为1=处理中成功,ID={task.TaskID},Name={task.TaskName}");
  518. }
  519. }
  520. if (task.State == 1)
  521. {
  522. if (task.PlanEndDate < DateTime.Now)
  523. {
  524. task.State = 0;
  525. if (!taskBLL.Update(task))
  526. return Error($"更新自动外呼任务状态为2=暂停失败,ID={task.TaskID},Name={task.TaskName}");
  527. log.Info($"更新自动外呼任务状态为2=暂停成功,ID={task.TaskID},Name={task.TaskName}");
  528. }
  529. }
  530. }
  531. }
  532. return Success("处理完成");
  533. }
  534. /// <summary>
  535. /// 获取号码
  536. /// </summary>
  537. /// <param name="id"></param>
  538. /// <param name="pageSize"></param>
  539. /// <param name="pageIndex"></param>
  540. /// <returns></returns>
  541. public ActionResult GetPhoneList(FilterCallPhone filter)
  542. {
  543. //if (!Request.IsAuthenticated)
  544. // return NoToken("未知错误,请重新登录");
  545. var model = taskBLL.GetModel(filter.Id);
  546. if (model == null)
  547. return Error("外呼任务不存在");
  548. var sql = "";
  549. if (filter.UserId > 0)
  550. {
  551. sql += $" and F_UserId={filter.UserId} ";
  552. }
  553. if (!string.IsNullOrWhiteSpace(filter.Phone))
  554. {
  555. sql += $" and F_Phone like '%{filter.Phone}%'";
  556. }
  557. if (filter.FPState > -1)
  558. {
  559. sql += $" and F_FPState={filter.FPState} ";
  560. }
  561. if (filter.HCState > -1)
  562. {
  563. sql += $" and F_HCState={filter.HCState} ";
  564. }
  565. if (filter.YJState > -1)
  566. {
  567. sql += $" and F_YJState={filter.YJState} ";
  568. }
  569. var field = "F_Id,t.TaskName,F_Phone,F_FPState,F_HCState,F_YJState,F_Username,tn.F_CreateTime";
  570. if (filter.TaskType == 2)
  571. {
  572. field += " F_Phone,F_HCState,F_YJState";
  573. }
  574. var recordCount = 0;
  575. var dt = BLL.PagerBLL.GetListPager(
  576. " T_Call_TaskTelNum tn left join T_CTI_Task t on t.TaskID=tn.F_TaskId left join T_Call_CallRecords c on c.TaskType=9 and c.TaskPhoneID=tn.F_Id and c.TaskID=tn.F_TaskId ",
  577. " F_Id ",
  578. field,
  579. " and F_TaskId=" + filter.Id + sql,
  580. "ORDER BY F_Id desc",
  581. filter.PageSize,
  582. filter.PageIndex,
  583. true,
  584. out recordCount);
  585. List<Model.T_Call_TaskTelNum> modelList = new BLL.T_Call_TaskTelNum().DataTableToListForShow(dt);
  586. var obj = new
  587. {
  588. rows = modelList.Select(x => new
  589. {
  590. taskname = x.TaskName,
  591. phone = x.F_Phone,
  592. agent = string.IsNullOrWhiteSpace(x.F_UserName) ? "" : x.F_UserName,
  593. isallot = x.F_FPState == null ? "" : (x.F_FPState > 0 ? "已分配" : "未分配"),
  594. iscalled = x.F_HCState > 0 ? "已呼叫" : "未呼叫",
  595. isconnected = x.F_YJState > 0 ? "已接通" : "未接通",
  596. createtime = Convert.ToDateTime(x.F_CreateTime).ToString("yyyy-MM-dd HH:mm:ss")
  597. }),
  598. total = recordCount
  599. };
  600. return Content(obj.ToJson());
  601. }
  602. /// <summary>
  603. /// 获取分配给当前登录坐席的号码
  604. /// </summary>
  605. /// <param name="filter"></param>
  606. /// <returns></returns>
  607. public ActionResult GetMyPhoneList(FilterCallPhone filter)
  608. {
  609. if (!Request.IsAuthenticated)
  610. return NoToken("未知错误,请重新登录");
  611. var sql = $" and t.State=1 and F_UserId={CurrentUser.UserData.F_UserId} ";
  612. if (filter.Id > 0)
  613. {
  614. var model = taskBLL.GetModel(filter.Id);
  615. sql += " and F_TaskId=" + filter.Id;
  616. if (model == null)
  617. return Error("外呼任务不存在");
  618. }
  619. if (!string.IsNullOrWhiteSpace(filter.Phone))
  620. {
  621. sql += $" and F_Phone like '%{filter.Phone}%'";
  622. }
  623. switch (filter.RequestType)
  624. {
  625. case 1://我的任务
  626. sql += $" and F_HCState=0 ";
  627. break;
  628. case 2://我的任务结果
  629. sql += $" and F_HCState=1 ";
  630. break;
  631. case 3://任务结果数据
  632. break;
  633. default:
  634. break;
  635. }
  636. if (filter.FPState > -1)
  637. {
  638. sql += $" and F_FPState={filter.FPState} ";
  639. }
  640. if (filter.HCState > -1)
  641. {
  642. sql += $" and F_HCState={filter.HCState} ";
  643. }
  644. if (filter.YJState > -1)
  645. {
  646. sql += $" and F_YJState={filter.YJState} ";
  647. }
  648. if (filter.YHFKID > -1)
  649. {
  650. sql += $" and F_YHFKID={filter.YHFKID} ";
  651. }
  652. if (filter.HJJGID > -1)
  653. {
  654. sql += $" and F_HJJGID={filter.HJJGID} ";
  655. }
  656. var field = "F_Id,t.TaskName,F_Phone,F_FPState,F_HCState,F_YJState,F_Username,tn.F_CreateTime,F_HJJGName,F_YHFKName";
  657. var recordCount = 0;
  658. var dt = BLL.PagerBLL.GetListPager(
  659. " T_Call_TaskTelNum tn left join T_CTI_Task t on t.TaskID=tn.F_TaskId",
  660. " F_Id ",
  661. field,
  662. sql,
  663. "ORDER BY F_LastCallTime desc,F_ID DESC ",
  664. filter.PageSize,
  665. filter.PageIndex,
  666. true,
  667. out recordCount);
  668. List<Model.T_Call_TaskTelNum> modelList = new BLL.T_Call_TaskTelNum().DataTableToListForShow(dt);
  669. var obj = new
  670. {
  671. rows = modelList.Select(x => new
  672. {
  673. id = x.F_Id,
  674. taskname = x.TaskName,
  675. phone = x.F_Phone,
  676. agent = string.IsNullOrWhiteSpace(x.F_UserName) ? "" : x.F_UserName,
  677. isallot = x.F_FPState == null ? "" : (x.F_FPState > 0 ? "已分配" : "未分配"),
  678. iscalled = x.F_HCState > 0 ? "已呼叫" : "未呼叫",
  679. isconnected = x.F_YJState > 0 ? "已接通" : "未接通",
  680. hjjg = x.F_HJJGName,
  681. yhfk = x.F_YHFKName,
  682. createtime = Convert.ToDateTime(x.F_CreateTime).ToString("yyyy-MM-dd HH:mm:ss"),
  683. lastcalltime = x.F_LastCallTime == null ? "" : Convert.ToDateTime(x.F_LastCallTime).ToString("yyyy-MM-dd HH:mm:ss")
  684. }),
  685. total = recordCount
  686. };
  687. return Content(obj.ToJson());
  688. }
  689. public ActionResult GetPhoneResult(FilterCallPhone filter)
  690. {
  691. var headList1 = new List<string>() { "序号", "外呼计划", "号码Id", "号码", "分配坐席", "呼叫状态", "接通状态", "呼叫结果", "结果反馈", "导入时间", "呼出时间" };
  692. //根据任务id查问卷
  693. var task = taskBLL.GetModel(filter.Id);
  694. if (task == null)
  695. return Error("该任务不存在");
  696. var headDt = DbHelperSQL.Query($"select Q.F_TITLE from T_Ask_Question Q LEFT JOIN T_Ask_PagerItems PIT ON PIT.F_QuestionId = Q.F_QuestionId LEFT JOIN T_Ask_PagerInfo PIN ON PIN.F_PagerId = PIT.F_PagerId LEFT JOIN T_CTI_Task T ON T.y_TkModelId = PIN.F_PagerId where T.TaskID ={task.TaskID} ORDER BY Q.F_SortModel").Tables[0];
  697. var headList2 = new List<string>();
  698. foreach (DataRow row in headDt.Rows)
  699. {
  700. headList2.Add(row["F_TITLE"]?.ToString() ?? "");
  701. }
  702. var headList = new List<string>();
  703. headList.AddRange(headList1);
  704. headList.AddRange(headList2);
  705. //查询数据
  706. var sql = "";
  707. if (filter.Id > 0)
  708. {
  709. var model = taskBLL.GetModel(filter.Id);
  710. sql += " and F_TaskId=" + filter.Id;
  711. if (model == null)
  712. return Error("外呼任务不存在");
  713. }
  714. if (!string.IsNullOrWhiteSpace(filter.Phone))
  715. {
  716. sql += $" and F_Phone like '%{filter.Phone}%'";
  717. }
  718. if (filter.FPState > -1)
  719. {
  720. sql += $" and F_FPState={filter.FPState} ";
  721. }
  722. if (filter.HCState > -1)
  723. {
  724. sql += $" and F_HCState={filter.HCState} ";
  725. }
  726. if (filter.YJState > -1)
  727. {
  728. sql += $" and F_YJState={filter.YJState} ";
  729. }
  730. if (filter.YHFKID > -1)
  731. {
  732. sql += $" and F_YHFKID={filter.YHFKID} ";
  733. }
  734. if (filter.HJJGID > -1)
  735. {
  736. sql += $" and F_HJJGID={filter.HJJGID} ";
  737. }
  738. var field = "F_Id,t.TaskName,F_Phone,F_FPState,F_HCState,F_YJState,F_Username,tn.F_CreateTime,F_HJJGName,F_YHFKName";
  739. var recordCount = 0;
  740. var dt = BLL.PagerBLL.GetListPager(
  741. " T_Call_TaskTelNum tn left join T_CTI_Task t on t.TaskID=tn.F_TaskId",
  742. " F_Id ",
  743. field,
  744. sql,
  745. "ORDER BY F_LastCallTime desc,F_ID DESC ",
  746. filter.PageSize,
  747. filter.PageIndex,
  748. true,
  749. out recordCount);
  750. List<Model.T_Call_TaskTelNum> modelList = new BLL.T_Call_TaskTelNum().DataTableToListForShow(dt);
  751. List<Model.T_Call_Answers> answerList = new List<T_Call_Answers>();
  752. if (modelList.Count > 0)
  753. {
  754. answerList = ansBLL.DataTableToListDTO(DbHelperSQL.Query($" select A.F_QID, A.F_CusTelID, A.F_Answer from T_Call_Answers A LEFT JOIN T_Ask_Question Q ON Q.F_QuestionId=A.F_QID where F_TaskID={ task.TaskID} AND F_CusTelID in ({ string.Join(", ", string.Join(", ", modelList.Select(x => x.F_Id).ToArray()))}) ORDER BY Q.F_SortModel ").Tables[0]);
  755. }
  756. var numList = modelList.Select(x => new
  757. {
  758. id = x.F_Id.ToString(),
  759. taskname = x.TaskName,
  760. phone = x.F_Phone,
  761. agent = string.IsNullOrWhiteSpace(x.F_UserName) ? "" : x.F_UserName,
  762. isallot = x.F_FPState == null ? "" : (x.F_FPState > 0 ? "已分配" : "未分配"),
  763. iscalled = x.F_HCState > 0 ? "已呼叫" : "未呼叫",
  764. isconnected = x.F_YJState > 0 ? "已接通" : "未接通",
  765. hjjg = x.F_HJJGName,
  766. yhfk = x.F_YHFKName,
  767. createtime = Convert.ToDateTime(x.F_CreateTime).ToString("yyyy-MM-dd HH:mm:ss"),
  768. lastcalltime = x.F_LastCallTime == null ? "" : Convert.ToDateTime(x.F_LastCallTime).ToString("yyyy-MM-dd HH:mm:ss")
  769. });
  770. var dataList = new List<List<string>>();
  771. foreach (var item in numList)
  772. {
  773. var answer = answerList.Where(x => (x.F_CusTelID?.ToString() ?? "") == item.id).GroupBy(x => x.F_QID).ToList();
  774. var itemList = new List<string>();
  775. itemList.AddRange(new string[] { item.id, item.taskname, item.phone, item.agent, item.isallot, item.iscalled, item.isconnected, item.hjjg, item.yhfk, item.createtime, item.lastcalltime });
  776. foreach (var i in answer)
  777. {
  778. itemList.Add(string.Join(", ", i.Where(x => !string.IsNullOrWhiteSpace(x.F_Answer)).Select(x => x.F_Answer).Distinct()));
  779. }
  780. dataList.Add(itemList);
  781. }
  782. return Success("获取成功", new
  783. {
  784. headlist = headList,
  785. datalist = dataList
  786. });
  787. }
  788. /// <summary>
  789. /// 坐席自主获取号码(点击外呼分配号码)
  790. /// </summary>
  791. /// <param name="id">外呼任务ID</param>
  792. /// <param name="userId">坐席ID</param>
  793. /// <returns></returns>
  794. public ActionResult AllotPhoneList(int id, int count)
  795. {
  796. //if (!Request.IsAuthenticated)
  797. // return NoToken("未知错误,请重新登录");
  798. if (count <= 0)
  799. return Error("参数错误");
  800. if (id <= 0)
  801. return Error("请选择外呼任务");
  802. var model = taskBLL.GetModel(id);
  803. if (model == null)
  804. return Error("外呼任务不存在");
  805. var obj = DbHelperSQL.GetSingle($"SELECT Count(F_ID) FROM T_Call_TaskTelNum WHERE F_UserId={CurrentUser.UserData.F_UserId} and F_TaskId={id} and F_HCState=0 ");
  806. var sum = obj == null ? 0 : Convert.ToInt32(obj);
  807. var num = 50 - sum;
  808. if (num <= 0)
  809. return Error("请先完成已分配任务");
  810. num = Math.Abs(num);
  811. var res = DbHelperSQL.ExecuteSql($"UPDATE T_Call_TaskTelNum SET F_FPState=1,F_UserId={CurrentUser.UserData.F_UserId},F_Username='{CurrentUser.UserData.F_UserName}' WHERE F_Id in(SELECT TOP({(count > num ? num : count)}) F_Id FROM T_Call_TaskTelNum WHERE F_TaskId={id} and F_FPState=0)");
  812. if (res > 0)
  813. return Success($"获取到{res}条可用号码");
  814. return Error("未获取到可用号码");
  815. }
  816. /// <summary>
  817. /// 取消分配
  818. /// </summary>
  819. /// <param name="ids"></param>
  820. /// <returns></returns>
  821. public ActionResult CancelPhone(int[] ids)
  822. {
  823. if (ids == null || ids.Length <= 0)
  824. return Error("请选择");
  825. var arr = string.Join(",", ids);
  826. if (taskTellNumBLL.CancelFP(arr))
  827. return Success("取消成功");
  828. return Error("取消失败");
  829. }
  830. /// <summary>
  831. /// 获取坐席可进行呼叫的点击外呼任务
  832. /// </summary>
  833. /// <returns></returns>
  834. public ActionResult GetMyCallPlan()
  835. {
  836. var roleid = CurrentUser.UserData.F_RoleId;
  837. var deptid = CurrentUser.UserData.F_DeptId;
  838. var deptCode = CurrentUser.UserData.F_DeptCode;
  839. var usercode = CurrentUser.UserData.F_UserCode;
  840. var sql = "";
  841. if (roleid != 0)
  842. {
  843. if (roleid != 17)
  844. {
  845. if (deptCode.Replace("|0|1|", "").Length > 0)
  846. {
  847. sql += " and DeptId in (select F_DeptId from T_Sys_Department where F_DeptCode like '" + deptCode + "%') ";
  848. }
  849. }
  850. }
  851. var taskList = taskBLL.DataTableToList(taskBLL.GetList("state=1 and tasktype=1 " + sql).Tables[0]);
  852. return Success("获取成功", taskList.Select(x => new
  853. {
  854. id = x.TaskID,
  855. name = x.TaskName
  856. }));
  857. }
  858. /// <summary>
  859. /// 获取拨出号码的详细信息+自定义导入信息
  860. /// </summary>
  861. /// <param name="id"></param>
  862. /// <returns></returns>
  863. public ActionResult GetCallNumDetail(int id)
  864. {
  865. var taskId = DbHelperSQL.GetSingle($"SELECT F_TaskId FROM T_Call_TaskTelNum WHERE F_ID={id}");
  866. if (taskId == null || (int)taskId <= 0)
  867. return Error("外呼任务不存在");
  868. var task = taskBLL.GetModel((int)taskId);
  869. if (task == null)
  870. return Error("外呼任务不存在");
  871. var fieldList = pageFieldBLL.DataTableToList(pageFieldBLL.GetList($"F_TaskId={task.TaskID}").Tables[0]);
  872. StringBuilder sb = new StringBuilder();
  873. Dictionary<string, string> dicTitle = new Dictionary<string, string>();
  874. foreach (var item in fieldList)
  875. {
  876. sb.Append(item.F_DBFieldlName + ",");
  877. dicTitle.Add(item.F_DBFieldlName, item.F_Name);
  878. }
  879. if (!string.IsNullOrWhiteSpace(sb.ToString()))
  880. {
  881. var callNum = DbHelperSQL.Query($"SELECT {sb.ToString().Trim(',')} FROM T_Call_TaskTelNum WHERE F_ID={id}").Tables[0];
  882. Dictionary<string, string> dic = new Dictionary<string, string>();
  883. for (int j = 0; j < callNum.Columns.Count; j++)
  884. {
  885. dic.Add(callNum.Columns[j].ColumnName, callNum.Rows[0][j].ToString());
  886. }
  887. return Success("获取成功", new
  888. {
  889. detail = dic.Select(x => new
  890. {
  891. field = x.Key,
  892. text = dicTitle[x.Key],
  893. value = x.Value,
  894. }),
  895. pagerid = task.y_TkModelId ?? 0,
  896. taskid = task.TaskID,
  897. id = id
  898. });
  899. }
  900. return Success("");
  901. }
  902. /// <summary>
  903. /// 更新拨出号码的 呼叫状态
  904. /// </summary>
  905. /// <returns></returns>
  906. public ActionResult UpdateCallState(int id)
  907. {
  908. var model = taskTellNumBLL.GetModel(id);
  909. if (model == null)
  910. return Error("该号码信息不存在");
  911. if (taskTellNumBLL.UpdateHC(model.F_Id, 1))
  912. return Success("更新成功");
  913. return Error("更新失败");
  914. }
  915. #region 问卷回答
  916. /// <summary>
  917. ///
  918. /// </summary>
  919. /// <param name="taskid">任务ID</param>
  920. /// <param name="custelid">客户电话ID</param>
  921. /// <param name="cusid">客户档案ID</param>
  922. /// <param name="ans">答案,数组形式["15_20_单选选项内容","17_25|36|58_复选选项内容1|选项内容2|选项内容3","30_0_问答题"]</param>
  923. /// <param name="hjjgid">呼叫结果</param>
  924. /// <param name="yhfkid">用户反馈</param>
  925. /// <returns></returns>
  926. public ActionResult Answers(CallNumberInput input)
  927. {
  928. if (input.Id <= 0)
  929. return Error("提交失败,当前号码不存在");
  930. var otnModel = taskTellNumBLL.GetModel(input.Id);
  931. if (otnModel.F_HCState <= 0)
  932. return Error("提交失败,号码未进行呼叫");
  933. int cc = 0;
  934. var ansModel = new Model.T_Call_Answers();
  935. string askqids = "";
  936. string ansids = "";
  937. if (input.Ans != null)
  938. {
  939. //先删除 后添加
  940. ansBLL.DeleteByTelid(input.Id, input.TaskId);
  941. ansModel.F_TaskID = input.TaskId;
  942. ansModel.F_CusTelID = input.Id;
  943. //ansModel.F_CusID = cusid;
  944. ansModel.F_OptBy = CurrentUser.UserData.F_UserId;
  945. ansModel.F_OptByName = CurrentUser.UserData.F_UserName;
  946. ansModel.F_OptOn = DateTime.Now;
  947. foreach (var item in input.Ans)
  948. {
  949. var nn = 0;
  950. var ii = item.Split('_');
  951. ansModel.F_QID = int.Parse(ii[0]);
  952. askqids += ii[0] + ",";
  953. ansids += ii[1] + ",";
  954. if (ii[1].IndexOf('|') > 0)
  955. {
  956. var iii = ii[1].Trim('|').Split('|');
  957. var iia = ii[2].Trim('|').Split('|');
  958. for (int i = 0; i < iii.Length; i++)
  959. {
  960. ansModel.F_QIID = int.Parse(iii[i]);
  961. ansModel.F_Answer = iia[i];
  962. if (ansBLL.Add(ansModel) > 0)
  963. nn++;
  964. }
  965. if (nn == iii.Length)
  966. cc++;
  967. }
  968. else
  969. {
  970. ansModel.F_QIID = int.Parse(ii[1]);
  971. ansModel.F_Answer = ii[2];
  972. if (ansBLL.Add(ansModel) > 0)
  973. cc++;
  974. }
  975. }
  976. }
  977. if (otnModel != null)
  978. {
  979. otnModel.F_HJJGId = input.HJJG;
  980. var hjconfig = new BLL.T_Sys_DictionaryValue().GetModel(input.HJJG);
  981. if (hjconfig != null)
  982. {
  983. otnModel.F_HJJGName = hjconfig.F_Name;
  984. if (hjconfig.F_Name == "正常接通")
  985. {
  986. otnModel.F_YJState = 1;
  987. }
  988. }
  989. otnModel.F_YHFKID = input.YHFK;
  990. var fkconfig = new BLL.T_Sys_DictionaryValue().GetModel(input.YHFK);
  991. if (fkconfig != null)
  992. otnModel.F_YHFKName = fkconfig.F_Name;
  993. otnModel.F_AskRes = askqids;
  994. otnModel.F_AskInfo = ansids;
  995. otnModel.F_Remark = input.Remark ?? "";
  996. taskTellNumBLL.Update(otnModel);
  997. //记录日志
  998. //planrecord(otnModel);
  999. }
  1000. if (cc == (input.Ans?.Length ?? 0))
  1001. {
  1002. return Success("提交成功!taskid=" + input.TaskId + ",custelid=" + input.Id + ",操作人:" + CurrentUser.UserData.F_UserCode);
  1003. }
  1004. else
  1005. {
  1006. ansBLL.DeleteByTelid(input.Id, input.TaskId);
  1007. return Error("问卷答案提交失败!taskid=" + input.TaskId + ",custelid=" + input.Id + ",操作人:" + CurrentUser.UserData.F_UserCode);
  1008. }
  1009. }
  1010. #endregion
  1011. public ActionResult GetTaskTelInfo(int id = 0)
  1012. {
  1013. if (id <= 0)
  1014. return Error("参数不正确");
  1015. var model = taskTellNumBLL.GetModel(id);
  1016. var paperid = 0;
  1017. if (model != null)
  1018. {
  1019. var anslist = ansBLL.GetModelList(" F_TaskID=" + model.F_TaskId.Value + " and F_CusTelID=" + id + " ");
  1020. var tmodel = taskBLL.GetModel(model.F_TaskId.Value);
  1021. if (tmodel != null)
  1022. {
  1023. paperid = (int)tmodel.y_TkModelId.Value;
  1024. #region 获取问卷试题信息以及答案
  1025. var pmodel = pagerInfoBLL.GetModel(paperid);
  1026. var qlist = questionBLL.GetModelList(" F_DeleteFlag=0 and F_QuestionId in (select F_QuestionId from T_Ask_PagerItems where F_PagerId=" + paperid + ") order by F_QuestionId ");
  1027. var qilist = questionItemBLL.GetModelList(" F_QuestionId in (select F_QuestionId from T_Ask_PagerItems where F_PagerId=" + paperid + ") order by F_ItemId ");
  1028. var newmodel = new
  1029. {
  1030. F_Title = pmodel.F_Title,
  1031. F_Remark = pmodel.F_Remark,
  1032. F_Questions = qlist.Select(q =>
  1033. {
  1034. var answers = "";
  1035. var qalist = anslist.Where(al => al.F_QID.Value == q.F_QuestionId).ToList<Model.T_Call_Answers>();
  1036. if (qalist.Count > 0)
  1037. {
  1038. if (q.F_Type > 1)
  1039. {
  1040. foreach (var item in qalist)
  1041. {
  1042. answers += item.F_QIID + "|";
  1043. }
  1044. }
  1045. else
  1046. {
  1047. answers = qalist[0].F_Answer;
  1048. }
  1049. }
  1050. return new
  1051. {
  1052. quesid = q.F_QuestionId,
  1053. questitle = q.F_Title,
  1054. questype = q.F_Type,
  1055. quescontent = q.F_Content,
  1056. quesremark = q.F_Remark,
  1057. quesanswers = answers.Trim('|'),
  1058. quesitems = qilist.Where(qq => qq.F_QuestionId == q.F_QuestionId).Select(qi =>
  1059. {
  1060. return new
  1061. {
  1062. itemid = qi.F_ItemId,
  1063. itemname = qi.F_ItemName,
  1064. itemremark = qi.F_Remark,
  1065. };
  1066. })
  1067. };
  1068. })
  1069. };
  1070. #endregion
  1071. var objy = new
  1072. {
  1073. taskModel = model,
  1074. paperModel = newmodel
  1075. };
  1076. return Success("获取详情成功", objy);
  1077. }
  1078. }
  1079. return Error("获取详情失败");
  1080. }
  1081. #endregion
  1082. #region 导入导出号码
  1083. /// <summary>
  1084. /// 导入号码信息
  1085. /// </summary>
  1086. /// <param name="type">导入方式:1=Excel; 2=txt .......</param>
  1087. /// <returns></returns>
  1088. public ActionResult ImportData(ImportDataInput input)
  1089. {
  1090. if (Request.Files.Count <= 0)
  1091. return Error("请正确上传Excel文件");
  1092. var file = Request.Files[0];
  1093. if (!file.ContentType.Equals("application/vnd.ms-excel") && !file.ContentType.Equals("application/x-xls") && !file.ContentType.Equals("application/x-xlsx") && !file.ContentType.Equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") && !file.ContentType.Equals("application/octet-stream"))
  1094. return Error($"请正确上传Excel文件:file.ContentType={file.ContentType}");
  1095. var filePath = "";
  1096. NPOIHelper npoi = new NPOIHelper();
  1097. var dt = npoi.ExcelToTable(file, 0, out filePath);
  1098. var obj = dt.AsEnumerable().Take(10).CopyToDataTable();
  1099. var colCount = obj.Columns.Count;
  1100. var rowCount = obj.Rows.Count;
  1101. string[] headArr = new string[colCount];
  1102. for (int i = 0; i < colCount; i++)
  1103. {
  1104. headArr[i] = obj.Columns[i].ToString();
  1105. }
  1106. string[][] itemArr = new string[rowCount][];
  1107. itemArr[0] = new string[rowCount];
  1108. for (int i = 0; i < rowCount; i++)
  1109. {
  1110. var row = obj.Rows[i];
  1111. var itemArray = row.ItemArray;
  1112. itemArr[i] = new string[itemArray.Count()];
  1113. for (int j = 0; j < itemArray.Count(); j++)
  1114. {
  1115. itemArr[i][j] = itemArray[j].ToString();
  1116. }
  1117. }
  1118. return Success("上传成功", new
  1119. {
  1120. filepath = filePath,
  1121. heads = headArr,
  1122. items = itemArr
  1123. });
  1124. }
  1125. /// <summary>
  1126. /// 导出号码信息
  1127. /// </summary>
  1128. /// <returns></returns>
  1129. public ActionResult ExportData(long taskId, int type = 0)
  1130. {
  1131. //if (!Request.IsAuthenticated)
  1132. // return NoToken("未知错误,请重新登录");
  1133. NPOIHelper npoi = new NPOIHelper();
  1134. var task = taskBLL.GetModel(taskId);
  1135. if (task == null)
  1136. return Error("该外呼任务不存在");
  1137. switch (type)
  1138. {
  1139. case 1:
  1140. var dt1 = taskTellNumBLL.GetPhoneList(" F_TaskId=" + task.TaskID + " and F_HCState=1 and (F_YJState=0 or F_YJState is null) ").Tables[0];
  1141. var msg1 = npoi.ExportToExcel(DateTime.Now.ToString("yyyyMMdd") + task.TaskName + "导出未接通号码", dt1);
  1142. return !string.IsNullOrWhiteSpace(msg1) ? Error(msg1) : Success("导出成功");
  1143. case 2:
  1144. var dt2 = taskTellNumBLL.GetPhoneList(" F_TaskId=" + task.TaskID + " and F_HCState=1 and F_YJState=1 ").Tables[0];
  1145. var msg2 = npoi.ExportToExcel(DateTime.Now.ToString("yyyyMMdd") + task.TaskName + "导出已接通号码", dt2);
  1146. return !string.IsNullOrWhiteSpace(msg2) ? Error(msg2) : Success("导出成功");
  1147. }
  1148. return Error("参数错误");
  1149. }
  1150. #endregion
  1151. #region 自动放音
  1152. /// <summary>
  1153. /// 获取自动放音文件
  1154. /// </summary>
  1155. /// <returns></returns>
  1156. public ActionResult GetRecordDropList()
  1157. {
  1158. //if (!Request.IsAuthenticated)
  1159. // return NoToken("未知错误,请重新登录");
  1160. var list = taskRecordBLL.DataTableToList(taskRecordBLL.GetList("").Tables[0]).Select(x => new
  1161. {
  1162. id = x.Id,
  1163. name = x.Name,
  1164. });
  1165. return Success("成功", list.ToList());
  1166. }
  1167. /// <summary>
  1168. /// 获取自动放音文件
  1169. /// </summary>
  1170. /// <returns></returns>
  1171. public ActionResult GetRecordList(FilterTalkRecord filter)
  1172. {
  1173. //if (!Request.IsAuthenticated)
  1174. // return NoToken("未知错误,请重新登录");
  1175. var recordCount = 0;
  1176. var dt = BLL.PagerBLL.GetListPager(
  1177. "T_CTI_TaskRecord ",
  1178. "id",
  1179. "*",
  1180. "",
  1181. "ORDER BY id desc",
  1182. filter.PageSize,
  1183. filter.PageIndex,
  1184. true,
  1185. out recordCount);
  1186. var list = taskRecordBLL.DataTableToList(dt).Select(x => new
  1187. {
  1188. id = x.Id,
  1189. name = x.Name,
  1190. recordpath = x.RecordPath,
  1191. recordtime = x.RecordTime,
  1192. });
  1193. var obj = new
  1194. {
  1195. rows = list,
  1196. total = recordCount
  1197. };
  1198. return Content(obj.ToJson());
  1199. }
  1200. /// <summary>
  1201. /// 获取录音
  1202. /// </summary>
  1203. /// <param name="id"></param>
  1204. /// <returns></returns>
  1205. public ActionResult GetRecord(int id)
  1206. {
  1207. //if (!Request.IsAuthenticated)
  1208. // return NoToken("未知错误,请重新登录");
  1209. var x = taskRecordBLL.GetModel(id);
  1210. return Success("成功", new
  1211. {
  1212. id = x.Id,
  1213. name = x.Name,
  1214. recordpath = x.RecordPath,
  1215. recordtime = x.RecordTime,
  1216. remark = x.Remark
  1217. });
  1218. }
  1219. /// <summary>
  1220. /// 添加/更新自动放音
  1221. /// </summary>
  1222. /// <param name="input"></param>
  1223. /// <returns></returns>
  1224. public ActionResult CreateOrUpdateRecord(Model.T_CTI_TaskRecord input)
  1225. {
  1226. //if (!Request.IsAuthenticated)
  1227. // return NoToken("未知错误,请重新登录");
  1228. Model.T_CTI_TaskRecord model = new Model.T_CTI_TaskRecord();
  1229. if (input.Id <= 0)
  1230. {
  1231. var dir = Server.MapPath("~/UploadRecord/");
  1232. if (!Directory.Exists(dir))
  1233. {
  1234. Directory.CreateDirectory(dir);
  1235. }
  1236. var file = Request.Files[0];
  1237. if (file.ContentType != "audio/x-wav" && file.ContentType != "audio/wav")
  1238. return Error("上传录音格式必须为.wav");
  1239. var name = DateTime.Now.ToString("yyyyMMddHHmmss") + Guid.NewGuid().ToString("N").Substring(0, 10) + ".wav";
  1240. var path = dir + name;
  1241. Request.Files[0].SaveAs(path);
  1242. FileInfo fileInfo = new FileInfo(path);
  1243. var fileName = FileUp.UploadFile(fileInfo, "/", "120.194.141.197", "Administrator", "hykj@800100");
  1244. var sysConfig = systemConfigBLL.GetModel(40);
  1245. if (sysConfig == null)
  1246. return Error("自动放音录音路径查询失败");
  1247. model.Name = input.Name;
  1248. model.RecordPath = sysConfig.F_ParamValue + fileName;
  1249. //model.RecordTime = input.RecordTime;
  1250. model.Remark = input.Remark;
  1251. if (taskRecordBLL.Add(model) > 0)
  1252. return Success("添加成功");
  1253. return Error("添加失败");
  1254. }
  1255. return Success("添加失败");
  1256. }
  1257. #endregion
  1258. #region 话单查询
  1259. /// <summary>
  1260. /// 话务分析
  1261. /// </summary>
  1262. /// <returns></returns>
  1263. public ActionResult GetTalkAnalysis(DateTime? start, DateTime? end)
  1264. {
  1265. //if (!Request.IsAuthenticated)
  1266. // return NoToken("未知错误,请重新登录");
  1267. //var where = "";
  1268. //if (start != null && end != null)
  1269. //{
  1270. // where += " PlanStartDate<'" + start.ToString() + "' and PlanEndDate>";
  1271. //}
  1272. var fir = taskPhonePartBLL.DataTableToList(taskPhonePartBLL.GetList("").Tables[0]);
  1273. var sec = taskDailyBLL.DataTableToList(taskDailyBLL.GetList("").Tables[0]);
  1274. var thi = taskDailyBLL.DataTableToList(taskDailyBLL.GetList().Tables[0]);
  1275. var obj = new
  1276. {
  1277. fir = fir.Select(x => new
  1278. {
  1279. date = x.Date.ToString("yyyy-MM-dd"),
  1280. phonepart = x.PhonePart,
  1281. province = x.Province,
  1282. city = x.City,
  1283. connectedcount = x.CalledCount == 0 ? "" : (x.ConnectedCount / x.CalledCount * 100).ToString("f2") + "%",
  1284. connectedagentcount = x.ConnectedCount == 0 ? "" : (x.ConnectedAgentCount / x.ConnectedCount * 100).ToString("f2") + "%",
  1285. }),
  1286. sec = sec.Select(x => new
  1287. {
  1288. date = x.Date.ToString("yyyy-MM-dd"),
  1289. allcount = x.AllCount,
  1290. calledcount = x.CalledCount,
  1291. connectedcount = x.ConnectedCount,
  1292. connectedagentcount = x.ConnectedAgentCount,
  1293. connectedrate = x.CalledCount == 0 ? "" : (x.ConnectedCount / x.CalledCount * 100).ToString("f2") + "%",
  1294. connectedagentrate = x.ConnectedCount == 0 ? "" : (x.ConnectedAgentCount / x.ConnectedCount * 100).ToString("f2") + "%",
  1295. taskid = x.TaskId,
  1296. taskname = x.TaskName
  1297. }),
  1298. thi = thi.Select(x => new
  1299. {
  1300. date = x.Date.ToString("yyyy-MM-dd"),
  1301. allcount = x.AllCount,
  1302. calledcount = x.CalledCount,
  1303. connectedcount = x.ConnectedCount,
  1304. connectedagentcount = x.ConnectedAgentCount,
  1305. connectedrate = x.CalledCount == 0 ? "" : (x.ConnectedCount / x.CalledCount * 100).ToString("f2") + "%",
  1306. connectedagentrate = x.ConnectedCount == 0 ? "" : (x.ConnectedAgentCount / x.ConnectedCount * 100).ToString("f2") + "%",
  1307. taskid = x.TaskId,
  1308. taskname = x.TaskName
  1309. })
  1310. };
  1311. return Success("", obj);
  1312. }
  1313. /// <summary>
  1314. /// 获取通话记录列表
  1315. /// </summary>
  1316. /// <returns></returns>
  1317. public ActionResult GetTalkRecords(FilterTalkRecord filter)
  1318. {
  1319. //if (!Request.IsAuthenticated)
  1320. // return NoToken("未知错误,请重新登录");
  1321. var sort = "ORDER BY startdate desc";
  1322. if (!string.IsNullOrWhiteSpace(filter.SortField))
  1323. {
  1324. var arr = filter.SortField.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1325. EnumTalkRecordsSortField e;
  1326. if (!Enum.TryParse(arr[0], out e))
  1327. return Error("排序字段参数错误");
  1328. sort = "ORDER BY " + e.ToString() + " " + arr[1];
  1329. }
  1330. StringBuilder where = new StringBuilder();
  1331. if (!string.IsNullOrWhiteSpace(filter.UserCode))
  1332. {
  1333. where.Append(" and agentid=" + filter.UserCode);
  1334. }
  1335. if (!string.IsNullOrWhiteSpace(filter.Phone))
  1336. {
  1337. where.Append(" and callee like '%" + filter.Phone + "%'");
  1338. }
  1339. if (filter.CallType != 0)
  1340. {
  1341. where.Append(" and calltype=" + filter.CallType);
  1342. }
  1343. if (!string.IsNullOrWhiteSpace(filter.TalkTime))
  1344. {
  1345. var arr = filter.TalkTime.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  1346. if (arr.Length == 2)
  1347. {
  1348. if (arr[0] == "1")
  1349. {
  1350. where.Append(" and talktime>" + arr[1]);
  1351. }
  1352. else if (arr[0] == "2")
  1353. {
  1354. where.Append(" and talktime=" + arr[1]);
  1355. }
  1356. else if (arr[0] == "3")
  1357. {
  1358. where.Append(" and talktime<" + arr[1]);
  1359. }
  1360. else { }
  1361. }
  1362. }
  1363. if (filter.StartTime == null || filter.EndTime == null)
  1364. {
  1365. filter.StartTime = DateTime.Now.AddDays(-3);
  1366. filter.EndTime = DateTime.Now;
  1367. }
  1368. where.Append(" and datediff(s,'" + filter.StartTime + "',getdate())>=0 and datediff(s,getdate(),'" + filter.EndTime + "')>=0 ");
  1369. // 全部=0
  1370. // 未接通=1
  1371. // 接通排队=2
  1372. // 接通未转入坐席=3
  1373. // 接通且分配坐席=4
  1374. int recordCount = 0;
  1375. Model.PageData<Model.CallResult> pageModel = new Model.PageData<Model.CallResult>();
  1376. StringBuilder fields = new StringBuilder();
  1377. var dt = BLL.PagerBLL.GetListPager(
  1378. "V_AutoCallResult",
  1379. "V_AutoCallResult.id",
  1380. "V_AutoCallResult.id,itemid, callee, agentid, username,startdate,enddate,getinagentdate,calltype,talktime,RecordPath",
  1381. where.ToString(),
  1382. sort,
  1383. filter.PageSize,
  1384. filter.PageIndex,
  1385. true,
  1386. out recordCount);
  1387. var config = new BLL.T_Sys_SystemConfig().GetModelList(" F_ParamCode='PlayPath' ").FirstOrDefault();
  1388. var callResultList = callResultBLL.DataTableToList(dt);
  1389. var list = new List<AutoCallRecordDto>();
  1390. callResultList.ForEach(x =>
  1391. {
  1392. var recordPath = "";
  1393. if (!string.IsNullOrWhiteSpace(x.RecordPath) && config != null && !string.IsNullOrEmpty(config.F_ParamValue))
  1394. {
  1395. var ym = config.F_ParamValue;
  1396. if (ym.Substring(ym.Length - 1) == "/")
  1397. {
  1398. ym = ym.Substring(0, ym.Length - 1);
  1399. }
  1400. recordPath = ym + x.RecordPath.Substring(x.RecordPath.IndexOf(':') + 1).Replace('\\', '/');
  1401. }
  1402. list.Add(new AutoCallRecordDto
  1403. {
  1404. id = x.Id,
  1405. taskid = x.TaskId,
  1406. callnumber = x.CallNumber,
  1407. usercode = x.Usercode == "0" ? "" : x.Usercode,
  1408. startdate = x.StartDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
  1409. getinagentdate = x.GetInAgentDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
  1410. enddate = x.EndDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
  1411. recordpath = recordPath,
  1412. username = x.Username,
  1413. state = x.State,
  1414. talktime = x.TalkTime > 0 ? x.TalkTime.ToString() : ""
  1415. });
  1416. });
  1417. var obj = new
  1418. {
  1419. rows = list,
  1420. total = recordCount
  1421. };
  1422. return Content(obj.ToJson());
  1423. }
  1424. #endregion
  1425. #region 过滤号码
  1426. #region 过滤号码-数据源
  1427. /// <summary>
  1428. /// 过滤号码
  1429. /// </summary>
  1430. /// <param name="dt"></param>
  1431. private DataTable PhoneNumFilter(DataTable dt)
  1432. {
  1433. var dtClone = dt.Copy();
  1434. foreach (DataRow row in dtClone.Rows)
  1435. {
  1436. var rows = dt.Select("[F_Phone]='" + row["F_Phone"] + "'");
  1437. if (rows.Length > 1)
  1438. {
  1439. for (int num = 0; num < rows.Count() - 1; num++)
  1440. {
  1441. dt.Rows.Remove(rows[num]);
  1442. }
  1443. }
  1444. }
  1445. return dt;
  1446. }
  1447. #endregion
  1448. #region 过滤号码-前三个月
  1449. private DataTable PhoneNumFilterMonth(DataTable dt, string phone = "F_Phone")
  1450. {
  1451. var taskTelNumDt = taskTellNumBLL.GetList(" datediff(mm,F_CreateTime,getdate())<=3 ").Tables[0];
  1452. foreach (DataRow row in taskTelNumDt.Rows)
  1453. {
  1454. var rows = dt.Select("[" + phone + "]='" + row["F_Phone"] + "'");
  1455. if (rows.Length > 1)
  1456. {
  1457. for (int num = 0; num < rows.Count() - 1; num++)
  1458. {
  1459. dt.Rows.Remove(rows[num]);
  1460. }
  1461. }
  1462. }
  1463. return dt;
  1464. }
  1465. #endregion
  1466. #endregion
  1467. }
  1468. }