ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -811,8 +811,18 @@ LoginUser loginUser = getLoginUser(); String orgid = loginUser.getUser().getOrgid(); serviceSubtaskCountReq.setOrgid(orgid); PageUtils.startPageByPost(serviceSubtaskCountReq.getPageNum(), serviceSubtaskCountReq.getPageSize()); return success(serviceSubtaskService.getSfStatisticsScriptDetails(serviceSubtaskCountReq)); //注意:这里不能再调用 PageUtils.startPageByPost。 //返回结构是 Map,且不传 type 时会执行两条 SQL,PageHelper 只作用于第一条 SQL, //分页已放到 Service 里按题目(scriptid)完成,保证 total 是题目总数。 Map<String, Object> details = serviceSubtaskService.getSfStatisticsScriptDetails(serviceSubtaskCountReq); AjaxResult ajax = success(details.get("data")); //兼容旧前端:data 仍然是 {scriptid: 题目} 的 Map; //同时按 RuoYi 习惯补上 rows/total/pageNum/pageSize 方便前端分页 ajax.put("rows", details.get("rows")); ajax.put("total", details.get("total")); ajax.put("pageNum", details.get("pageNum")); ajax.put("pageSize", details.get("pageSize")); return ajax; } /** smartor/src/main/java/com/smartor/service/IServiceSubtaskService.java
@@ -200,7 +200,7 @@ public List<ServiceSubtaskStatistic> getSfStatisticsScript(ServiceSubtaskCountReq serviceSubtaskCountReq); public Map<String, ServiceSubtaskScriptCount> getSfStatisticsScriptDetails(ServiceSubtaskCountReq serviceSubtaskCountReq); public Map<String, Object> getSfStatisticsScriptDetails(ServiceSubtaskCountReq serviceSubtaskCountReq); public List<PatArchiveSrmVO> sendMsgTemplate(List<PatArchiveSrmVO> patArchiveSrmVOS); smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -5004,8 +5004,7 @@ } @Override public Map<String, ServiceSubtaskScriptCount> getSfStatisticsScriptDetails(ServiceSubtaskCountReq serviceSubtaskCountReq) { Map<String, ServiceSubtaskScriptCount> result = new HashMap<>(); public Map<String, Object> getSfStatisticsScriptDetails(ServiceSubtaskCountReq serviceSubtaskCountReq) { List<ServiceSubtaskScriptCount> allCounts = new ArrayList<>(); List<ServiceSubtaskScriptCount> allItemCounts = new ArrayList<>(); String type = serviceSubtaskCountReq.getType(); @@ -5029,7 +5028,23 @@ allItemCounts = serviceSubtaskMapper.getSfStatisticsScriptItemDetails(serviceSubtaskCountReq); } for (ServiceSubtaskScriptCount count : allCounts) { //返回结构是 Map,且不传 type 时会执行两条 SQL,PageHelper 没法对整体分页, //所以在题目合并完成之后按题目(scriptid)在这里分页,保证 total 和每页数据都是题目维度的。 allCounts.sort(Comparator .comparing(ServiceSubtaskScriptCount::getSubtaskType, Comparator.nullsLast(String::compareTo)) .thenComparing(ServiceSubtaskScriptCount::getScriptid, Comparator.nullsLast(Long::compareTo))); int pageNum = ObjectUtils.isNotEmpty(serviceSubtaskCountReq.getPageNum()) && serviceSubtaskCountReq.getPageNum() > 0 ? serviceSubtaskCountReq.getPageNum() : 1; int pageSize = ObjectUtils.isNotEmpty(serviceSubtaskCountReq.getPageSize()) && serviceSubtaskCountReq.getPageSize() > 0 ? serviceSubtaskCountReq.getPageSize() : 10; int total = allCounts.size(); int fromIndex = (int) Math.min((long) (pageNum - 1) * pageSize, total); int toIndex = Math.min(fromIndex + pageSize, total); List<ServiceSubtaskScriptCount> pageCounts = allCounts.subList(fromIndex, toIndex); Map<String, ServiceSubtaskScriptCount> pageData = new LinkedHashMap<>(); for (ServiceSubtaskScriptCount count : pageCounts) { Map<String, ServiceSubtaskScriptCount> itemCountMap = new HashMap<>(); //问卷加上空白选项 if (ObjectUtils.isNotEmpty(count.getTemplateid()) && ObjectUtils.isNotEmpty(count.getSubtaskType()) && count.getSubtaskType().equals("2")) { @@ -5060,8 +5075,13 @@ } } allItemCounts.forEach(itemCount -> { if (ObjectUtils.isNotEmpty(count.getScriptid()) && ObjectUtils.isNotEmpty(itemCount.getScriptid())) { if (count.getScriptid().equals(itemCount.getScriptid())) { //明细行已按“题目内容+任务类型”聚合并带出 script_content,不能用 scriptid 匹配: //同一道题会被复制到多个任务模板,每个模板的 scriptid 都不同 boolean sameQuestion = ObjectUtils.isNotEmpty(count.getScriptContent()) && ObjectUtils.isNotEmpty(itemCount.getScriptContent()) && count.getScriptContent().equals(itemCount.getScriptContent()) && Objects.equals(count.getSubtaskType(), itemCount.getSubtaskType()); if (sameQuestion) { //放入统计信息 itemCount.setScriptContent(count.getScriptContent()); itemCount.setScriptType(count.getScriptType()); @@ -5079,12 +5099,18 @@ } itemCountMap.put(itemCount.getOptionText(), itemCount); } } }); List<ServiceSubtaskScriptCount> itemCounts = new ArrayList<>(itemCountMap.values()); count.setDetails(itemCounts); result.put(count.getScriptid().toString(), count); pageData.put(count.getScriptid().toString(), count); } Map<String, Object> result = new HashMap<>(); // total 是题目总数(已按题目合并),rows/data 是当前页数据 result.put("total", total); result.put("pageNum", pageNum); result.put("pageSize", pageSize); result.put("rows", new ArrayList<>(pageCounts)); result.put("data", pageData); return result; } smartor/src/main/java/com/smartor/service/impl/SvyLibTemplateScriptServiceImpl.java
@@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import static net.sf.jsqlparser.parser.feature.Feature.values; @@ -157,8 +158,12 @@ } } itemCounts.forEach(itemCount ->{ if(ObjectUtils.isNotEmpty(count.getScriptid()) && ObjectUtils.isNotEmpty(itemCount.getScriptid())){ if(count.getScriptid().equals(itemCount.getScriptid())){ //明细行已按“题目内容+任务类型”聚合,不能用 scriptid 匹配(同一道题在每个任务模板里的 scriptid 都不同) boolean sameQuestion = ObjectUtils.isNotEmpty(count.getScriptContent()) && ObjectUtils.isNotEmpty(itemCount.getScriptContent()) && count.getScriptContent().equals(itemCount.getScriptContent()) && Objects.equals(count.getSubtaskType(), itemCount.getSubtaskType()); if(sameQuestion){ //放入统计信息 itemCount.setScriptContent(count.getScriptContent()); itemCount.setScriptType(count.getScriptType()); @@ -175,7 +180,6 @@ itemCount.setChosenPercentage(chosenPercentage.toString()); } itemCountMap.put(itemCount.getOptionText(), itemCount); } } }); List<ServiceSubtaskScriptCount> details = new ArrayList<>(itemCountMap.values()); smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -2281,14 +2281,14 @@ <select id="getSfStatisticsScriptDetails" parameterType="com.smartor.domain.ServiceSubtaskCountReq" resultMap="ServiceSubtaskScriptCountResult"> SELECT a.id as scriptid, a.templateid as templateid, a.script_type, MIN(a.id) as scriptid, MIN(a.templateid) as templateid, MIN(a.script_type) as script_type, a.script_content, b.subtask_type, b.completed_quantity, b.all_quantity, ROUND(b.completed_quantity/b.all_quantity,2) as completed_percentage SUM(b.completed_quantity) as completed_quantity, SUM(b.all_quantity) as all_quantity, ROUND(SUM(b.completed_quantity)/SUM(b.all_quantity),2) as completed_percentage FROM <if test="type == 1"> ivr_task_template_script a @@ -2351,25 +2351,37 @@ group by ssd.scriptid) b ON a.id = b.scriptid <!-- 适用单条查询 --> <if test="scriptids != null"> <if test="scriptids != null and scriptids != ''"> AND a.scriptid in (SELECT lib_script.scriptid FROM svy_lib_template_script lib_script WHERE lib_script.scriptid in (${scriptids})) </if> <!-- 同一道题会被复制到多个任务模板,按题目内容合并,保证一道题只返回一条 --> GROUP BY a.script_content, b.subtask_type ORDER BY MIN(a.id) </select> <select id="getSfStatisticsScriptItemDetails" parameterType="com.smartor.domain.ServiceSubtaskCountReq" resultMap="ServiceSubtaskScriptCountResult"> SELECT ssd.scriptid, a.script_content, ss.type as subtask_type, IFNULL(ssd.matchedtext,ssd.asrtext) AS option_text, COUNT(*) AS chosen_quantity FROM service_subtask_detail ssd INNER JOIN service_subtask ss ON ssd.sub_id = ss.id INNER JOIN <if test="type == 1"> ivr_task_template_script a ON a.id = ssd.scriptid </if> <if test="type == 2"> svy_task_template_script a ON a.id = ssd.scriptid </if> where 1=1 and ss.del_flag=0 and ssd.del_flag=0 <if test="orgid != null and orgid != ''"> and ss.orgid = #{orgid} </if> @@ -2408,7 +2420,7 @@ <if test="configValue != null and configValue != ''"> AND ssd.categoryid IN (${configValue}) </if> group by ssd.scriptid, IFNULL(ssd.matchedtext,ssd.asrtext) group by a.script_content, ss.type, IFNULL(ssd.matchedtext,ssd.asrtext) </select> <select id="getDataByTime" resultMap="ServiceSubtaskResult">