From d7e3192804fca756d881af360ffd5eea157ef9ad Mon Sep 17 00:00:00 2001
From: 陈昶聿 <chychen@nbjetron.com>
Date: 星期三, 21 十月 2026 15:45:18 +0800
Subject: [PATCH] 【市一】电话挂断服务
---
smartor/src/main/java/com/smartor/domain/PatArchiveReq.java | 19 ++
smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java | 51 +++++
smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml | 32 +-
smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml | 55 +++---
smartor/src/main/java/com/smartor/domain/PhoneCallReqYQVO.java | 21 ++
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java | 267 ++++++++++++++++++++++++++---
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java | 9
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java | 14 +
ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java | 44 ++++
smartor/src/main/java/com/smartor/mapper/PatMedInhospMapper.java | 9 +
10 files changed, 435 insertions(+), 86 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
index 0ef614f..7947abd 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/PatMedInhospController.java
@@ -70,13 +70,8 @@
SysUser user = getLoginUser().getUser();
patMedInhosp.setOrgid(user.getOrgid());
List<PatMedInhosp> list = patMedInhospService.selectPatMedInhospList(patMedInhosp);
- long count = PageUtils.count(new ISelect() {
- @Override
- public void doSelect() {
- patMedInhospService.selectPatMedInhospList(patMedInhosp);
- }
- });
- return getDataTable2(count, list);
+ // 鍒嗛〉鏌ヨ鏃� PageHelper 宸茬粡鎵ц杩� count锛岃繖閲岀洿鎺ョ敤 PageInfo 鍙栨�绘暟锛岄伩鍏嶅啀璺戜竴娆″叏閲忔煡璇�
+ return getDataTable(list);
}
/**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
index ab16600..f5a54a1 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
@@ -50,6 +50,20 @@
}
/**
+ * 缂撳瓨瀵硅薄锛屼粎褰� key 涓嶅瓨鍦ㄦ椂鎵嶅啓鍏ワ紙鍘熷瓙鎿嶄綔锛夛紝鐢ㄤ簬骞傜瓑浜掓枼鏍囪
+ *
+ * @param key 缂撳瓨鐨勯敭鍊�
+ * @param value 缂撳瓨鐨勫��
+ * @param timeout 鏃堕棿
+ * @param timeUnit 鏃堕棿棰楃矑搴�
+ * @return true=鏈鍐欏叆鎴愬姛锛堜箣鍓嶄笉瀛樺湪锛夛紱false=key 宸插瓨鍦紝鏈啓鍏�
+ */
+ public <T> boolean setCacheObjectIfAbsent(final String key, final T value, final long timeout, final TimeUnit timeUnit) {
+ Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value, timeout, timeUnit);
+ return Boolean.TRUE.equals(success);
+ }
+
+ /**
* 璁剧疆鏈夋晥鏃堕棿
*
* @param key Redis閿�
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java
index 0310368..ef2d3f3 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/HttpUtil.java
@@ -95,6 +95,50 @@
return httpClient;
}
+ /**
+ * POST JSON锛屽彧鏍¢獙 HTTP 鐘舵�佺爜锛屽厑璁稿搷搴斾綋涓虹┖銆�
+ * <p>
+ * 鐢ㄤ簬 /hangup 杩欑被"鎴愬姛鍙洖 200銆佹病鏈夊搷搴斾綋"鐨勬帴鍙o細
+ * {@link #postJsonRequest(String, String)} 鍦ㄨ鍝嶅簲浣撴椂濡傛灉涓虹┖浼氭姏 RESPONSE_NULL_ERROR_CODE(999994)锛�
+ * 浼氭妸涓�娆℃垚鍔熺殑鎸傛柇璇垽鎴愬け璐ワ紙杩樹細瑙﹀彂鏃犳剰涔夌殑閲嶈瘯锛夈��
+ * <p>
+ * 闈� 2xx 鏃舵姏鍑虹殑 HttpRequestException 閲屽甫涓婄姸鎬佺爜鍜屽搷搴斾綋锛屾柟渚挎帓鏌ャ��
+ *
+ * @param url 璇锋眰鍦板潃
+ * @param request json 璇锋眰浣�
+ */
+ public static void postJsonRequestAllowEmptyResponse(String url, String request) throws HttpRequestException {
+ Assert.hasLength(url, "璇锋眰url涓嶈兘涓虹┖瀛楃涓层��");
+ EntityEnclosingMethod httpMethod = new PostMethod(url);
+ httpMethod.addRequestHeader("Content-Type", "application/json; charset=UTF-8");
+ setHeaderRequestId(httpMethod);
+ try {
+ RequestEntity entity = new StringRequestEntity(request, "application/json", "utf-8");
+ httpMethod.setRequestEntity(entity);
+ int resultCode = httpClient.executeMethod(httpMethod);
+ if (resultCode >= 200 && resultCode < 300) {
+ return;
+ }
+ String respJson = "";
+ try {
+ respJson = httpMethod.getResponseBodyAsString();
+ } catch (Exception ignore) {
+ // 璇讳笉鍒板搷搴斾綋涓嶅奖鍝嶅垽鏂紝鐘舵�佺爜宸茬粡鑳借鏄庨棶棰�
+ }
+ throw new HttpRequestException(resultCode, respJson);
+ } catch (UnsupportedEncodingException e) {
+ throw new HttpRequestException(ENCODING_ERROR_CODE, e);
+ } catch (HttpException e) {
+ throw new HttpRequestException(HTTP_ERROR_CODE, e);
+ } catch (IOException e) {
+ throw new HttpRequestException(IO_ERROR_CODE, e);
+ } finally {
+ if (httpMethod != null) {
+ httpMethod.releaseConnection();
+ }
+ }
+ }
+
public static Boolean postJsonRequest(String url, String request) throws HttpRequestException {
Assert.hasLength(url, "璇锋眰url涓嶈兘涓虹┖瀛楃涓层��");
EntityEnclosingMethod httpMethod = new PostMethod(url);
diff --git a/smartor/src/main/java/com/smartor/domain/PatArchiveReq.java b/smartor/src/main/java/com/smartor/domain/PatArchiveReq.java
index ab80bd9..28d7cd5 100644
--- a/smartor/src/main/java/com/smartor/domain/PatArchiveReq.java
+++ b/smartor/src/main/java/com/smartor/domain/PatArchiveReq.java
@@ -232,4 +232,23 @@
@ApiModelProperty("闄㈠尯")
@Excel(name = " 闄㈠尯 ")
private String campusid;
+
+ /**
+ * 鍒涘缓鏃堕棿锛堣寖鍥存煡璇�-寮�濮嬶級
+ * <p>
+ * PatArchiveMapper.xml 閲� selectPatArchiveInfoByAllhosp / ByInhosp / ByPhysical /
+ * ByInhospQC / ByPhysicalQC 绛変互鏈璞′负鍙傛暟锛屼笖閮戒娇鐢ㄤ簡
+ * {@code <if test="createTimeStart != null">}锛屽睘鎬х己澶辨椂 MyBatis 鍙� ContextMap
+ * 浼氳蛋 MetaObject.getValue 骞舵姏 ReflectionException锛圱here is no getter for property ...锛夈��
+ */
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿-寮�濮�")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTimeStart;
+
+ /**
+ * 鍒涘缓鏃堕棿锛堣寖鍥存煡璇�-缁撴潫锛�
+ */
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿-缁撴潫")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTimeEnd;
}
diff --git a/smartor/src/main/java/com/smartor/domain/PhoneCallReqYQVO.java b/smartor/src/main/java/com/smartor/domain/PhoneCallReqYQVO.java
index defbbb5..f0ab112 100644
--- a/smartor/src/main/java/com/smartor/domain/PhoneCallReqYQVO.java
+++ b/smartor/src/main/java/com/smartor/domain/PhoneCallReqYQVO.java
@@ -1,5 +1,6 @@
package com.smartor.domain;
+import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -165,4 +166,24 @@
@ApiModelProperty(value = "鏀鹃煶鐨勫師濮嬫枃鏈唴瀹�")
private String origin;
+ /**
+ * 鎾斁缁撴潫锛堜笅鍒掔嚎瀛楁鍏煎锛�
+ * <p>
+ * 骞冲彴涓婂叾瀹冨瓧娈甸兘鏄笅鍒掔嚎椋庢牸锛坋nd_time銆乤sr_text銆乺ecord_path鈥︼級锛岄儴鍒嗙増鏈帹閫佹挱鏀剧姸鎬佹椂鐢ㄧ殑鏄�
+ * play_stop 鑰屼笉鏄� playstop銆傚瓧娈电粦涓嶄笂鏃� playstop 浼氫繚鎸侀粯璁ゅ�� false锛屽鑷�"鎾畬浜�"琚綋鎴�
+ * "鍒氬紑濮嬫挱"锛屾案杩滀笉瑙﹀彂鎸傛柇锛屾墍浠ヨ繖閲屾妸涓ょ鍐欐硶閮芥帴浣忋��
+ */
+ @JsonProperty("play_stop")
+ @ApiModelProperty(value = "鎾斁缁撴潫(涓嬪垝绾垮吋瀹瑰瓧娈�)")
+ private Boolean playStopUnderline;
+
+ /**
+ * 鏈鍥炶皟鏄惁琛ㄧず"鎾斁缁撴潫"銆�
+ * <p>
+ * playstop / play_stop 浠讳竴涓� true 鍗宠涓烘挱鏀剧粨鏉燂紝閬垮厤瀛楁鍚嶅樊寮傛垨瀛楁缂哄け瀵艰嚧鍒ゆ柇澶辩湡銆�
+ */
+ public boolean playStopIsTrue() {
+ return Boolean.TRUE.equals(playstop) || Boolean.TRUE.equals(playStopUnderline);
+ }
+
}
diff --git a/smartor/src/main/java/com/smartor/mapper/PatMedInhospMapper.java b/smartor/src/main/java/com/smartor/mapper/PatMedInhospMapper.java
index 52a80b7..112dfef 100644
--- a/smartor/src/main/java/com/smartor/mapper/PatMedInhospMapper.java
+++ b/smartor/src/main/java/com/smartor/mapper/PatMedInhospMapper.java
@@ -2,6 +2,7 @@
import java.util.List;
+import com.smartor.domain.PatArchivetag;
import com.smartor.domain.PatMedInhosp;
import com.smartor.domain.PatMedInhospVO;
import com.smartor.domain.PatMedReq;
@@ -30,6 +31,14 @@
public String getTagnameBypatid(Long patid);
/**
+ * 鎸夋。妗圛D鎵归噺鏌ヨ鏍囩鍚嶇О锛堢敤浜庡垪琛ㄩ〉鏇挎崲閫愯鏌ヨ鐨� N+1锛�
+ *
+ * @param patids 妗fID闆嗗悎
+ * @return 姣忎釜妗fID涓�鏉¤褰曪紝tagname 涓鸿妗f鐨勬爣绛惧悕鎷兼帴涓�
+ */
+ public List<PatArchivetag> selectTagnameByPatids(@Param("patids") List<Long> patids);
+
+ /**
* 鏌ヨ鎮h�呬綇闄㈣褰曞垪琛�
*
* @param patMedInhosp 鎮h�呬綇闄㈣褰�
diff --git a/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
index d30b56e..4511145 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/PatMedInhospServiceImpl.java
@@ -37,6 +37,12 @@
@Slf4j
@Service
public class PatMedInhospServiceImpl implements IPatMedInhospService {
+
+ /**
+ * 鎵归噺鏌ユ爣绛炬椂鍗曟 IN 鐨勬渶澶т釜鏁�
+ */
+ private static final int TAG_QUERY_BATCH_SIZE = 500;
+
@Autowired
private PatMedInhospMapper patMedInhospMapper;
@Autowired
@@ -116,14 +122,51 @@
}
List<PatMedInhosp> patMedInhospList = patMedInhospMapper.selectPatMedInhospList(patMedInhosp);
- for (PatMedInhosp patMedInhosp1 : patMedInhospList) {
- String tagname = patMedInhospMapper.getTagnameBypatid(patMedInhosp1.getPatid());
- patMedInhosp1.setTagname(tagname);
- }
+ fillTagnames(patMedInhospList);
return patMedInhospList;
}
/**
+ * 鎵归噺鍥炲~鎮h�呮爣绛俱��
+ * <p>
+ * 鍘熸潵鏄嬁鍒板垪琛ㄥ悗閫愯璋冪敤 getTagnameBypatid锛屽睘浜庡吀鍨嬬殑 N+1锛氬垎椤� 10 鏉″氨鏄� 10 娆℃煡璇紝
+ * 闈炲垎椤佃皟鐢紙瀵煎嚭銆佸畾鏃朵换鍔★級鍑犲崈鏉″氨鏄嚑鍗冩鏌ヨ銆傝繖閲屾敼鎴愭寜 patid 鍘婚噸鍚庡垎鎵� IN 鏌ヨ锛�
+ * 涓�鎵规渶澶� {@link #TAG_QUERY_BATCH_SIZE} 涓紝閬垮厤 IN 鍒楄〃杩囬暱銆�
+ *
+ * @param patMedInhospList 寰呭洖濉殑浣忛櫌璁板綍鍒楄〃
+ */
+ private void fillTagnames(List<PatMedInhosp> patMedInhospList) {
+ if (CollectionUtils.isEmpty(patMedInhospList)) {
+ return;
+ }
+ List<Long> patids = patMedInhospList.stream()
+ .map(PatMedInhosp::getPatid)
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toList());
+ if (patids.isEmpty()) {
+ return;
+ }
+
+ Map<Long, String> tagMap = new HashMap<>(patids.size());
+ for (int i = 0; i < patids.size(); i += TAG_QUERY_BATCH_SIZE) {
+ List<Long> batch = patids.subList(i, Math.min(i + TAG_QUERY_BATCH_SIZE, patids.size()));
+ List<PatArchivetag> tags = patMedInhospMapper.selectTagnameByPatids(batch);
+ if (CollectionUtils.isEmpty(tags)) {
+ continue;
+ }
+ for (PatArchivetag tag : tags) {
+ if (tag.getPatid() != null) {
+ tagMap.put(tag.getPatid(), tag.getTagname());
+ }
+ }
+ }
+ for (PatMedInhosp patMedInhosp : patMedInhospList) {
+ patMedInhosp.setTagname(tagMap.get(patMedInhosp.getPatid()));
+ }
+ }
+
+ /**
* 褰掍竴鍖栧叆闄㈠簥浣嶆帓搴忓弬鏁�
* <p>
* asc / 1 -> asc锛堝簥浣嶆搴忥級锛宒esc / 2 -> desc锛堝簥浣嶅�掑簭锛夛紝鍏朵綑锛堝惈涓嶄紶锛�-> null锛堜笉鎺掑簭锛夈��
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
index 3f9709d..c7f170a 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -60,6 +60,8 @@
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -185,6 +187,30 @@
@Value("${hangup}")
private String hangup;
+
+ /**
+ * 鎸傛柇璇锋眰鏈�澶ч噸璇曟鏁帮紙鍚娆★級
+ */
+ private static final int HANGUP_MAX_RETRY = 3;
+
+ /**
+ * 鎸傛柇璇锋眰閲嶈瘯闂撮殧锛堟绉掞級
+ */
+ private static final long HANGUP_RETRY_INTERVAL_MS = 300L;
+
+ /**
+ * 鍏滃簳鎸傛柇鐨勬渶灏忓欢鏃讹紙姣锛夛細绛夊钩鍙版妸缁撴潫璇挱瀹屽啀鎸�
+ */
+ private static final long HANGUP_FALLBACK_MIN_DELAY_MS = 8000L;
+
+ /**
+ * 鍏滃簳鎸傛柇瀹氭椂鍣ㄣ��
+ * <p>
+ * 闆ㄧ划杩欏鐨勬寕鏂師鏈緷璧�"骞冲彴鎾畬缁撴潫璇悗鍐嶅洖璋冧竴娆� PlayEventCallback(playstop=true)"锛�
+ * 骞冲彴涓嶅洖璋冪數璇濆氨涓�鐩存寕鐫�銆傝繖閲岀敤涓�涓畧鎶ょ嚎绋嬫睜鍦ㄧ粨鏉熻涓嬪彂鍚庢寜瀛楁暟浼扮畻鏃堕暱鍋氬厹搴曟寕鏂紝
+ * 涓庡钩鍙板洖璋冭蛋鍚屼竴涓箓绛夋爣璁帮紝涓嶄細閲嶅鎸傛柇銆�
+ */
+ private ScheduledExecutorService hangupFallbackExecutor;
@Value("${app_key_yq}")
private String app_key_yq;
@@ -1996,6 +2022,130 @@
}
/**
+ * 缁撴潫璇紦瀛� key锛堝彧瑕佸啓杩囪 key 灏辫鏄庢湰娆″璇濆凡缁忔敹灏撅紝缁撴潫璇负绌轰篃绠楋級
+ */
+ private String jsyKey(String uuid) {
+ return uuid + "- jsy";
+ }
+
+ /**
+ * 鏈瀵硅瘽鏄惁宸茬粡鏀跺熬锛堝嵆宸茬粡涓嬪彂杩囩粨鏉熻锛夈��
+ * <p>
+ * 娉ㄦ剰锛氫笉鑳界敤 getCacheObject(...) != null 鍒ゆ柇锛岀粨鏉熻涓虹┖鏃跺啓鍏ョ殑鏄┖鍊硷紝
+ * 璇诲嚭鏉ユ槸 null 浣� key 鏄瓨鍦ㄧ殑锛屽繀椤荤敤 hasKey銆�
+ */
+ private boolean isDialogueEnded(String uuid) {
+ return StringUtils.isNotEmpty(uuid) && Boolean.TRUE.equals(redisCache.hasKey(jsyKey(uuid)));
+ }
+
+ /**
+ * 鎸傛柇鐢佃瘽锛氬箓绛� + 閲嶈瘯 + 寮傚父涓嶅鎶� + 娓呯悊缁撴潫璇紦瀛樸��
+ * <p>
+ * 骞冲彴鍥炶皟锛圥layEventCallback 鎾斁缁撴潫锛夊拰鍏滃簳瀹氭椂浠诲姟閮戒細璋冭繖閲岋紝
+ * 閫氳繃 redis 鐨� {uuid}- hangup-sent 鏍囪淇濊瘉鍚屼竴娆¢�氳瘽鍙湡姝f寕鏂竴娆°��
+ *
+ * @param uuid 閫氳瘽 uuid
+ * @param phone 琚彨鍙风爜
+ * @param reason 鎸傛柇鍘熷洜锛堜粎鐢ㄤ簬鏃ュ織鎺掓煡锛�
+ * @return true=鏈纭疄鍙戝嚭浜嗘寕鏂姹�
+ */
+ private boolean doHangup(String uuid, String phone, String reason) {
+ if (StringUtils.isEmpty(uuid)) {
+ log.warn("鎸傛柇璺宠繃锛歶uid 涓虹┖, reason={}", reason);
+ return false;
+ }
+ String sentKey = uuid + "- hangup-sent";
+ if (!redisCache.setCacheObjectIfAbsent(sentKey, "1", 30, TimeUnit.MINUTES)) {
+ log.info("鎸傛柇璺宠繃锛氳閫氳瘽宸叉寕鏂繃, uuid={}, reason={}", uuid, reason);
+ return false;
+ }
+ Map<String, String> req = new HashMap<>();
+ req.put("uuid", uuid);
+ req.put("caller", phone);
+ String body = new Gson().toJson(req);
+ for (int i = 1; i <= HANGUP_MAX_RETRY; i++) {
+ try {
+ // 鍙牎楠� HTTP 鐘舵�佺爜锛�/hangup 閫氬父鎴愬姛鍙洖 200 涓旀病鏈夊搷搴斾綋锛�
+ // 鐢� postJsonRequest 浼氬洜"鍝嶅簲涓簄ull"鎶婃垚鍔熻鍒ゆ垚澶辫触
+ HttpUtil.postJsonRequestAllowEmptyResponse(hangup, body);
+ log.info("鎸傛柇鎴愬姛, uuid={}, reason={}, 绗瑊}娆�, url={}", uuid, reason, i, hangup);
+ redisCache.setCacheObject(uuid + "- hangup", "1", 10, TimeUnit.MINUTES);
+ redisCache.deleteObject(jsyKey(uuid));
+ redisCache.deleteObject(uuid + "- hangup-planned");
+ return true;
+ } catch (Exception e) {
+ //鎶婂紓甯哥被鍨嬪拰淇℃伅鏀惧湪鍚屼竴琛岋紝鍗曡 grep 灏辫兘鐪嬪嚭鏄�"杩炰笉涓�"杩樻槸"杩斿洖闈�200"
+ log.error("鎸傛柇澶辫触, uuid={}, reason={}, 绗瑊}娆�, url={}, body={}, 鍘熷洜={}: {}",
+ uuid, reason, i, hangup, body, e.getClass().getSimpleName(), e.getMessage(), e);
+ if (i < HANGUP_MAX_RETRY) {
+ try {
+ Thread.sleep(HANGUP_RETRY_INTERVAL_MS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ }
+ }
+ }
+ // 鍏ㄩ儴澶辫触锛氶噴鏀惧箓绛夋爣璁帮紝鍏佽骞冲彴涓嬩竴娆″洖璋冩垨涓嬩竴涓厹搴曚换鍔¢噸璇�
+ redisCache.deleteObject(sentKey);
+ log.error("鎸傛柇鏈�缁堝け璐ワ紝宸查噴鏀鹃噸璇曟爣璁�, uuid={}, reason={}, url={}", uuid, reason, hangup);
+ return false;
+ }
+
+ /**
+ * 瀹夋帓涓�娆″厹搴曟寕鏂��
+ * <p>
+ * 缁撴潫璇笅鍙戝悗锛屽钩鍙版甯稿簲璇ュ啀鍥炶皟 PlayEventCallback(playstop=true)锛屾鏃剁敱 doHangup 绔嬪嵆鎸傛柇锛�
+ * 浣嗗钩鍙板瓧娈电己澶�/涓嶅洖璋冩椂鐢佃瘽浼氫竴鐩存寕鐫�锛屾墍浠ヨ繖閲屾寜缁撴潫璇瓧鏁颁及绠楁挱鏀炬椂闀匡紝鍒扮偣鍏滃簳鎸備竴娆°��
+ * 鍚屼竴涓� uuid 鍙畨鎺掍竴娆★紙{uuid}- hangup-planned 骞傜瓑锛夈��
+ *
+ * @param uuid 閫氳瘽 uuid
+ * @param phone 琚彨鍙风爜
+ * @param jsy 缁撴潫璇紙鍙兘涓虹┖锛屼负绌烘椂鎸夋渶灏忓欢鏃跺鐞嗭級
+ */
+ private void scheduleHangupFallback(String uuid, String phone, String jsy) {
+ if (StringUtils.isEmpty(uuid)) {
+ return;
+ }
+ if (!redisCache.setCacheObjectIfAbsent(uuid + "- hangup-planned", "1", 30, TimeUnit.MINUTES)) {
+ return;
+ }
+ // 涓枃 TTS 澶х害姣忕 3~4 涓瓧锛岀暀瓒充綑閲忓悗鍐嶅姞涓婃渶灏忓欢鏃�
+ int len = StringUtils.isEmpty(jsy) ? 0 : jsy.length();
+ long delay = HANGUP_FALLBACK_MIN_DELAY_MS + len * 400L;
+ if (delay > 60000L) {
+ delay = 60000L;
+ }
+ log.info("瀹夋帓鍏滃簳鎸傛柇, uuid={}, 缁撴潫璇暱搴�={}, 寤舵椂={}ms", uuid, len, delay);
+ getHangupFallbackExecutor().schedule(() -> {
+ try {
+ doHangup(uuid, phone, "缁撴潫璇挱瀹屽厹搴�");
+ } catch (Exception e) {
+ log.error("鍏滃簳鎸傛柇寮傚父, uuid={}", uuid, e);
+ }
+ }, delay, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 鍏滃簳鎸傛柇绾跨▼姹狅紙鎳掑姞杞斤紝瀹堟姢绾跨▼锛岃繘绋嬮��鍑轰笉鍙楀奖鍝嶏級
+ */
+ private ScheduledExecutorService getHangupFallbackExecutor() {
+ if (hangupFallbackExecutor == null) {
+ synchronized (this) {
+ if (hangupFallbackExecutor == null) {
+ hangupFallbackExecutor = Executors.newScheduledThreadPool(2, r -> {
+ Thread t = new Thread(r, "voice-hangup-fallback");
+ t.setDaemon(true);
+ return t;
+ });
+ }
+ }
+ }
+ return hangupFallbackExecutor;
+ }
+
+ /**
* 鐢佃瘽ASR閫氳瘽鍥炶皟(闆ㄧ划)
*
* @param phoneCallReqYQVO
@@ -2005,6 +2155,15 @@
//鍏堟妸璇ubId浠巆ache_exist涓墧闄わ紝鍙鏈夊洖璋冨氨鍓旈櫎锛堢洰鐨勬槸锛屽敖蹇cache-exist涓虹┖锛屽幓缂撳瓨涓嬩竴鎵硅鎵撶殑鐢佃瘽;杩欓噷鍓旈櫎涓嶅奖鍝嶇數璇濈殑姝e父涓氬姟锛�
// redisCache.removeElementFromList("cache-exist", phoneCallReqYQVO.getTaskid());
+ //uuid / taskid / phone 鏄悗闈㈡墍鏈夐�昏緫鐨勫墠鎻愶紝缂轰簡灏辩洿鎺ュ拷鐣ワ紝閬垮厤 Long.valueOf(null)銆乶ull.trim() 涔嬬被鐨� 500
+ if (StringUtils.isEmpty(phoneCallReqYQVO.getUuid()) || StringUtils.isEmpty(phoneCallReqYQVO.getTaskid())
+ || StringUtils.isEmpty(phoneCallReqYQVO.getPhone())) {
+ log.warn("闆ㄧ划鍥炶皟缂哄皯 uuid/taskid/phone锛岀洿鎺ュ拷鐣�: operate={}, uuid={}, taskid={}, phone={}",
+ phoneCallReqYQVO.getOperate(), phoneCallReqYQVO.getUuid(),
+ phoneCallReqYQVO.getTaskid(), phoneCallReqYQVO.getPhone());
+ return new PhoneCallBackYQVO();
+ }
+
//鍒ゆ柇鏄惁鎸傛満
String hangupState = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "- hangup");
Object cacheObject1 = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
@@ -2013,7 +2172,7 @@
}
if ("AsrCallback".equals(phoneCallReqYQVO.getOperate()) && phoneCallReqYQVO.getEnd_time() != null && phoneCallReqYQVO.getEnd_time() != -1) {
//澶勭悊鎸傛柇
- if (phoneCallReqYQVO.getAsrtext().contains("鎷ㄥ彨鐨勭敤鎴锋蹇�")) {
+ if (StringUtils.isNotEmpty(phoneCallReqYQVO.getAsrtext()) && phoneCallReqYQVO.getAsrtext().contains("鎷ㄥ彨鐨勭敤鎴锋蹇�")) {
//鍒ゆ柇 recordAccept-hungup 鏄惁鏈夊�硷紝濡傛灉鏈夛紝鍒欒鏄庝笉鐢ㄥ鐞嗕簡锛屼箣鍓嶅凡缁忓鐞嗚繃浜嗭紙recordAccept-hungup杩欎釜涓昏鏄粰"閫氳瘽璁板綍鐢ㄧ殑锛�"锛�
Object cacheObject = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
if (ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("1")) {
@@ -2024,7 +2183,9 @@
//濡傛灉鍙戦�佺姸鎬佷负6锛屽氨璇存槑宸茬粡鎵撳畬浜嗭紝涔熸病鏈夊繀瑕佺户缁線涓嬭蛋浜�
if (StringUtils.isNotEmpty(phoneCallReqYQVO.getTaskid())) {
ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(Long.valueOf(phoneCallReqYQVO.getTaskid()));
- if (serviceSubtask.getSendstate() == 6L) return new PhoneCallBackYQVO();
+ if (serviceSubtask != null && serviceSubtask.getSendstate() != null && serviceSubtask.getSendstate() == 6L) {
+ return new PhoneCallBackYQVO();
+ }
}
ServiceSubtask serviceSubtask2 = new ServiceSubtask();
@@ -2032,11 +2193,8 @@
serviceSubtask2.setSenduuid(phoneCallReqYQVO.getUuid());
serviceSubtask2.setId(Long.valueOf(phoneCallReqYQVO.getTaskid()));
serviceSubtaskMapper.updateServiceSubtask(serviceSubtask2);
- Map<String, String> req = new HashMap<>();
- req.put("uuid", phoneCallReqYQVO.getUuid());
- req.put("caller", phoneCallReqYQVO.getPhone());
- HttpUtil.postJsonRequest(hangup, new Gson().toJson(req));
- redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- hangup", "1", 2, TimeUnit.MINUTES);
+ //鎸傛柇锛堝箓绛� + 澶辫触閲嶈瘯锛屽紓甯镐笉鍐嶅線澶栨姏锛岄伩鍏嶅洖璋冪洿鎺� 500锛�
+ doHangup(phoneCallReqYQVO.getUuid(), phoneCallReqYQVO.getPhone(), "鎷ㄥ彨鐨勭敤鎴锋蹇�");
//鍏堟妸榛樿鐨剅ecordAccept-hungup鍒犻櫎锛屽啀鏇存柊
redisCache.deleteObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup", "1", 10, TimeUnit.MINUTES);
@@ -2049,36 +2207,53 @@
return new PhoneCallBackYQVO();
}
}
+ //缁撴潫璇凡缁忎笅鍙戣繃锛岃鏄庢湰娆″璇濆凡缁忔敹灏撅細瀹夋帓涓�娆″厹搴曟寕鏂��
+ //骞冲彴姝e父鎯呭喌涓嬩細鍐嶅洖璋� PlayEventCallback(playstop=true) 璁╂垜浠珛鍒绘寕鏂紱
+ //浣嗗钩鍙板瓧娈电己澶�/涓嶅洖璋冩椂鐢佃瘽浼氫竴鐩存寕鐫�锛屾墍浠ヨ繖閲屾寜缁撴潫璇瓧鏁颁及绠楁挱鏀炬椂闀垮埌鐐瑰厹搴曟寕涓�娆★紙骞傜瓑锛夈��
+ if (isDialogueEnded(phoneCallReqYQVO.getUuid())) {
+ scheduleHangupFallback(phoneCallReqYQVO.getUuid(), phoneCallReqYQVO.getPhone(),
+ redisCache.getCacheObject(jsyKey(phoneCallReqYQVO.getUuid())));
+ }
//瀹氫箟涓�涓垎鏁扮殑鍙橀噺
Boolean aBoolean1 = redisCache.hasKey(phoneCallReqYQVO.getUuid() + "SCORE");
if (!aBoolean1) redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", 0.0, 120, TimeUnit.MINUTES);
PhoneCallBackYQVO phoneCallBackYQVO = new PhoneCallBackYQVO();
//channel_create 閫氶亾鍒涘缓鐨勬椂鍊欙紝鍙互鎵ц涓�浜涘叾瀹冩搷浣滐紝璀鍙戜釜鐭俊涔嬬被鐨�; 鎴戜滑鐨勪笟鍔″彲浠ヤ笉鐢ㄧ PlayEventCallback 杩欎釜鏄挱鏀捐闊崇殑,鏆傛椂鐢ㄤ笉鍒� End_time()= -1鎴杗ull琛ㄧず褰撳墠鐨刟srtext涓嶆槸涓�鍙ュ畬鏁寸殑璇�
- if (phoneCallReqYQVO.getOperate().equals("channel_create")) {
+ if ("channel_create".equals(phoneCallReqYQVO.getOperate())) {
return phoneCallBackYQVO;
}
//PlayEventCallback 杩欎釜鏄挱鏀捐闊崇殑 playstart锛氭斁闊冲紑濮嬶紙闂鎾姤寮�濮嬶級 playstop锛� 鏀鹃煶缁撴潫锛堥棶棰樻挱鎶ョ粨鏉燂級
- if (phoneCallReqYQVO.getOperate().equals("PlayEventCallback")) {
- String cacheJSY = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "- jsy");
- if (phoneCallReqYQVO.getOperate().equals("PlayEventCallback") && phoneCallReqYQVO.getPlaystop() == false) {
- //鍒ゆ柇redis涓槸鍚︽湁缁撴潫璇�
- if (StringUtils.isEmpty(cacheJSY)) {
+ if ("PlayEventCallback".equals(phoneCallReqYQVO.getOperate())) {
+ //缁撴潫璇槸鍚﹀凡涓嬪彂锛堢敤 hasKey 鍒ゆ柇锛岀粨鏉熻涓虹┖涔熺畻宸叉敹灏撅級
+ boolean dialogueEnded = isDialogueEnded(phoneCallReqYQVO.getUuid());
+ //playstop 鍙兘鏄� null锛屽钩鍙颁篃鍙兘鐢� play_stop锛岀粺涓�鐢� VO 鍒ゆ柇
+ boolean playStop = phoneCallReqYQVO.playStopIsTrue();
+ String cacheJSY = redisCache.getCacheObject(jsyKey(phoneCallReqYQVO.getUuid()));
+ log.info("PlayEventCallback: uuid={}, playstop={}, 鏄惁宸蹭笅鍙戠粨鏉熻={}",
+ phoneCallReqYQVO.getUuid(), playStop, dialogueEnded);
+ if (!playStop) {
+ //鏀鹃煶寮�濮�
+ if (!dialogueEnded) {
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop", false, 120, TimeUnit.MINUTES);
log.error("PlayEventCallbackPlaystop鐨勫�间负-------锛歿}", false);
+ } else {
+ //骞冲彴寮�濮嬫挱缁撴潫璇紝鍏滃簳鎸傛柇鍦ㄦ柟娉曞叆鍙e凡缁忓畨鎺掕繃锛岃繖閲屽彧鐣欐棩蹇椾究浜庢帓鏌�
+ log.info("缁撴潫璇紑濮嬫挱鏀�, uuid={}, 缁撴潫璇�={}", phoneCallReqYQVO.getUuid(), cacheJSY);
}
} else {
- //濡傛灉缁撴潫璇笉涓虹┖锛屽垯瑕佹寕鐢佃瘽浜�
- if (StringUtils.isNotEmpty(cacheJSY)) {
- Map<String, String> req = new HashMap<>();
- req.put("uuid", phoneCallReqYQVO.getUuid());
- req.put("caller", phoneCallReqYQVO.getPhone());
-// HttpUtils.sendPost(hangup, new Gson().toJson(req));
- HttpUtil.postJsonRequest(hangup, new Gson().toJson(req));
- ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(Long.valueOf(phoneCallReqYQVO.getTaskid()));
- //璁板綍鐢佃瘽鍙戦�佺姸鎬�
- setFailPreachForm(serviceSubtask, "3", "閫氳瘽姝e父缁撴潫", "9");
- //鍒犻櫎缁撴潫璇殑缂撳瓨
- redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "- jsy");
+ //鏀鹃煶缁撴潫
+ if (dialogueEnded) {
+ //缁撴潫璇挱瀹岋紝绔嬪嵆鎸傛柇锛堝箓绛� + 澶辫触閲嶈瘯锛屽紓甯镐笉澶栨姏锛�
+ doHangup(phoneCallReqYQVO.getUuid(), phoneCallReqYQVO.getPhone(), "缁撴潫璇挱鏀剧粨鏉�");
+ //璁板綍鐢佃瘽鍙戦�佺姸鎬侊細鎸傛柇鎴愯触閮借钀藉簱锛屼笉鑳藉啀璁╁洖璋冪洿鎺� 500
+ if (StringUtils.isNotEmpty(phoneCallReqYQVO.getTaskid())) {
+ try {
+ ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(Long.valueOf(phoneCallReqYQVO.getTaskid()));
+ setFailPreachForm(serviceSubtask, "3", "閫氳瘽姝e父缁撴潫", "9");
+ } catch (Exception e) {
+ log.error("鎸傛柇鍚庢洿鏂板瓙浠诲姟鐘舵�佸け璐�, taskid={}", phoneCallReqYQVO.getTaskid(), e);
+ }
+ }
} else {
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop", true, 120, TimeUnit.MINUTES);
log.error("-------PlayEventCallbackPlaystop鐨勫�间负锛歿}", true);
@@ -2098,6 +2273,10 @@
//閫氳繃瀛愪换鍔D鑾峰彇鍒版ā鏉夸俊鎭�
ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(Long.valueOf(phoneCallReqYQVO.getTaskid()));
+ if (serviceSubtask == null) {
+ log.warn("鍥炶皟瀵瑰簲鐨勫瓙浠诲姟涓嶅瓨鍦紝鐩存帴蹇界暐, taskid={}, operate={}", phoneCallReqYQVO.getTaskid(), phoneCallReqYQVO.getOperate());
+ return phoneCallBackYQVO;
+ }
IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
//鑾峰彇妯℃澘闂
IvrTaskTemplateScript ivrTaskTemplateScript = new IvrTaskTemplateScript();
@@ -2106,8 +2285,24 @@
//鑾峰彇闂ID 鍜� 搴忓彿
String scriptId = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim());
log.error("scriptId鏄灏戯細{}", scriptId);
+ if (StringUtils.isEmpty(scriptId)) {
+ //褰撳墠娌℃湁"姝e湪闂殑闂"锛岃鏄庢湰娆¢�氳瘽宸茬粡鏀跺熬锛堢粨鏉熻宸蹭笅鍙戝悗锛屽钩鍙拌繕浼氳ˉ Silent/Asr 鍥炶皟锛夛紝
+ //鍘熸潵杩欓噷鐩存帴 Long.valueOf(null) 浼氭姏 NumberFormatException 璁╁洖璋� 500銆�
+ //杩欓噷鐩存帴蹇界暐锛屽苟纭繚鍏滃簳鎸傛柇宸茬粡鎺掍笂锛岄伩鍏嶇數璇濈户缁寕鐫�銆�
+ log.warn("鏈彇鍒板綋鍓嶉棶棰業D锛屾寜閫氳瘽宸叉敹灏惧鐞�, taskid={}, phone={}, operate={}",
+ phoneCallReqYQVO.getTaskid(), phoneCallReqYQVO.getPhone(), phoneCallReqYQVO.getOperate());
+ if (isDialogueEnded(phoneCallReqYQVO.getUuid())) {
+ scheduleHangupFallback(phoneCallReqYQVO.getUuid(), phoneCallReqYQVO.getPhone(),
+ redisCache.getCacheObject(jsyKey(phoneCallReqYQVO.getUuid())));
+ }
+ return phoneCallBackYQVO;
+ }
//褰撳墠棰樼殑淇℃伅
IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO = iIvrTaskTemplateScriptService.getTaskTempScriptInfoByid(Long.valueOf(scriptId));
+ if (ivrTaskTemplateScriptVO == null) {
+ log.warn("褰撳墠闂涓嶅瓨鍦紝蹇界暐鍥炶皟, taskid={}, scriptId={}", phoneCallReqYQVO.getTaskid(), scriptId);
+ return phoneCallBackYQVO;
+ }
//鍒ゆ柇UUID鏄惁瀛樺湪
Boolean aBoolean = redisCache.hasKey(phoneCallReqYQVO.getUuid());
if (!aBoolean) {
@@ -2380,9 +2575,10 @@
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
// //鑾峰彇涓嬩竴棰�
log.error("鑾峰彇涓嬩竴棰樼殑淇℃伅锛歿}", ivrTaskTemplateScriptVO);
- if (ivrTaskTemplateScriptVO.getBranchFlag().equals("1") || ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() != null && ivrTaskTemplateScriptVO.getNextScriptno() != 0) {
+ //branchFlag 鍙兘涓� null锛岀粺涓�鎸夊垎鏀�0澶勭悊锛岄伩鍏� NPE 鎶婂洖璋冩墦 500
+ if ("1".equals(ivrTaskTemplateScriptVO.getBranchFlag()) || "0".equals(ivrTaskTemplateScriptVO.getBranchFlag()) && ivrTaskTemplateScriptVO.getNextScriptno() != null && ivrTaskTemplateScriptVO.getNextScriptno() != 0) {
Long nextQuestion = null;
- if (ivrTaskTemplateScriptVO.getBranchFlag().equals("1")) {
+ if ("1".equals(ivrTaskTemplateScriptVO.getBranchFlag())) {
nextQuestion = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getNextQuestion();
//鏇存柊鍒嗘暟
double score = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
@@ -2508,7 +2704,8 @@
if (ObjectUtils.isNotEmpty(countObj)) count = (Integer) countObj;
if (count != null && count >= ivrTaskTemplate.getMateNum()) {
//濡傛灉count宸茬粡澶т簬鎴栫瓑浜庢病鏈夊尮閰嶆鏁�
- if (ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() == 0 || ivrTaskTemplateScriptVO.getBranchFlag().equals("1") && ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getBranchFlag().equals("1") && ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
+ //branchFlag 鍙兘涓� null锛岀粺涓�鎸夊垎鏀�0澶勭悊锛岄伩鍏� NPE 鎶婂洖璋冩墦 500
+ if ("0".equals(ivrTaskTemplateScriptVO.getBranchFlag()) && ivrTaskTemplateScriptVO.getNextScriptno() == null || "0".equals(ivrTaskTemplateScriptVO.getBranchFlag()) && ivrTaskTemplateScriptVO.getNextScriptno() == 0 || "1".equals(ivrTaskTemplateScriptVO.getBranchFlag()) && ivrTaskTemplateScriptVO.getNextScriptno() == null || "1".equals(ivrTaskTemplateScriptVO.getBranchFlag()) && ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
//濡傛灉鏄渶鍚庝竴閬撻锛屾垨鑰呮病鏈変笅涓�棰樹簡锛屽氨鐩存帴鎸傛満
ServiceTask serviceTask1 = serviceTaskService.selectServiceTaskByTaskid(serviceSubtask.getTaskid());
phoneCallBackYQVO.setType("text");
@@ -2938,7 +3135,9 @@
@Override
public Integer recordAccept(PhoneCallRecordVO phoneCallRecordVO) {
Object cacheObject = redisCache.getCacheObject(phoneCallRecordVO.getTaskid() + "recordAccept-hungup");
- if (phoneCallRecordVO.getHangup_cause().equals("NO_USER_RESPONSE") || ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("1")) {
+ // hangup_cause 骞冲彴涓嶄竴瀹氭瘡娆¢兘甯︼紝杩欓噷鍒ょ┖锛岄伩鍏嶆暣鏉¢�氳瘽璁板綍鍥炶皟鐩存帴 NPE 500
+ boolean noUserResponse = "NO_USER_RESPONSE".equals(phoneCallRecordVO.getHangup_cause());
+ if (noUserResponse || ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("1")) {
//鏃犱汉鎺ュ惉
//璁板綍鐢佃瘽鍙戦�佺姸鎬�
ServiceSubtask serviceSubtask = serviceSubtaskMapper.selectServiceSubtaskById(Long.valueOf(phoneCallRecordVO.getTaskid()));
@@ -2951,9 +3150,13 @@
// if (phoneCallRecordVO.getAnswered() != null && phoneCallRecordVO.getAnswered() == true) {
log.error("鏈変汉鎺ョ數璇濅簡锛屽苟涓斿畬浜�");
//璇存槑鏈変汉鎺ヤ簡
- int startIndex = phoneCallRecordVO.getRecord_path().indexOf("voice") + "voice".length() + 1; // 鍔�1鏄烦杩�/绗﹀彿
- int endIndex = phoneCallRecordVO.getRecord_path().lastIndexOf("/");
- String result = phoneCallRecordVO.getRecord_path().substring(startIndex, endIndex);
+ //褰曢煶璺緞鍙仛鏃ュ織鐣欑棔锛氬钩鍙扮粰绌�/鏍煎紡涓嶇鏃跺師鏉ョ殑 substring 浼氭姏寮傚父锛屽鑷存暣鏉″洖璋� 500銆佺姸鎬佸拰褰曢煶閮戒笉澶勭悊
+ String recordPath = phoneCallRecordVO.getRecord_path();
+ if (StringUtils.isNotEmpty(recordPath) && recordPath.contains("voice") && recordPath.lastIndexOf("/") > 0) {
+ log.info("閫氳瘽褰曢煶璺緞, taskid={}, record_path={}", phoneCallRecordVO.getTaskid(), recordPath);
+ } else {
+ log.warn("閫氳瘽璁板綍鍥炶皟鏈彇鍒版湁鏁堝綍闊宠矾寰�, taskid={}, record_path={}", phoneCallRecordVO.getTaskid(), recordPath);
+ }
ServiceSubtask serviceSubtask = new ServiceSubtask();
serviceSubtask.setRemark("鐢佃瘽鎷ㄦ墦宸插畬鎴�");
serviceSubtask.setSendstate(6L);
diff --git a/smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml b/smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml
index 329cf76..21a0367 100644
--- a/smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/PatArchiveMapper.xml
@@ -215,10 +215,10 @@
<if test="filterDrname != null ">and filter_drname = #{filterDrname}</if>
<if test="filterDrcode != null ">and filter_drcode = #{filterDrcode}</if>
<if test="createTimeStart != null">
- AND date_format(create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND create_time < date(#{createTimeEnd}) + interval 1 day
</if>
<if test="pageSize != null and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
</select>
@@ -269,10 +269,10 @@
<if test="telcode != null and telcode != ''">and telcode = #{telcode}</if>
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
<if test="createTimeStart != null">
- AND date_format(a.create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND a.create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(a.create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND a.create_time < date(#{createTimeEnd}) + interval 1 day
</if>
<if test="tagIds != null and tagIds != ''">and c.tagid in
<foreach collection="tagIds" item="tagId" open="(" separator="," close=")">
@@ -556,10 +556,10 @@
</foreach>
</if>
<if test="createTimeStart != null">
- AND date_format(a.create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND a.create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(a.create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND a.create_time < date(#{createTimeEnd}) + interval 1 day
</if>
order by a.update_time desc
<if test="pn != null and ps != null">limit ${pn},${ps}</if>
@@ -631,7 +631,7 @@
and d.orgid = #{orgid}
<if test="name != null and name != ''">and a.name like concat('%', #{name}, '%')</if>
<if test="idcardno != null and idcardno != ''">and a.idcardno = #{idcardno}</if>
- <if test="pid != null and pid != ''">and a.id = #{id}</if>
+ <if test="pid != null and pid != ''">and a.id = #{pid}</if>
<if test="campusid != null and campusid != ''">and a.campusid = #{campusid}</if>
<if test="telcode != null and telcode != ''">and a.telcode = #{telcode}</if>
<if test="notrequiredFlag != null and notrequiredFlag != ''">and a.notrequired_flag = #{notrequiredFlag}
@@ -793,10 +793,10 @@
</foreach>
</if>
<if test="createTimeStart != null">
- AND date_format(a.create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND a.create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(a.create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND a.create_time < date(#{createTimeEnd}) + interval 1 day
</if>
<if test="isFilter == true">
AND NOT exists ( SELECT 1 FROM pat_filterlist f where d.patid=f.patid)
@@ -890,10 +890,10 @@
</foreach>
</if>
<if test="createTimeStart != null">
- AND date_format(a.create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND a.create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(a.create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND a.create_time < date(#{createTimeEnd}) + interval 1 day
</if>
<if test="isFilter == true">
AND NOT exists ( SELECT 1 FROM pat_filterlist f where d.patid=f.patid)
@@ -968,15 +968,15 @@
and d.orgid = #{orgid}
<if test="name != null and name != ''">and a.name like concat('%', #{name}, '%')</if>
<if test="idcardno != null and idcardno != ''">and a.idcardno = #{idcardno}</if>
- <if test="pid != null and pid != ''">and a.id = #{id}</if>
+ <if test="pid != null and pid != ''">and a.id = #{pid}</if>
<if test="telcode != null and telcode != ''">and a.telcode = #{telcode}</if>
<if test="notrequiredFlag != null and notrequiredFlag != ''">and a.notrequired_flag = #{notrequiredFlag}
</if>
<if test="createTimeStart != null">
- AND date_format(a.create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND a.create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(a.create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND a.create_time < date(#{createTimeEnd}) + interval 1 day
</if>
<if test="hospitalname != null and hospitalname != ''">
AND d.hospitalname = #{hospitalname}
@@ -1228,10 +1228,10 @@
</foreach>
</if>
<if test="createTimeStart != null">
- AND date_format(a.create_time,'%y%m%d') >= date_format(#{createTimeStart},'%y%m%d')
+ AND a.create_time >= date(#{createTimeStart})
</if>
<if test="createTimeEnd != null">
- AND date_format(a.create_time,'%y%m%d') <= date_format(#{createTimeEnd},'%y%m%d ')
+ AND a.create_time < date(#{createTimeEnd}) + interval 1 day
</if>
<if test="isFilter == true">
AND NOT exists ( SELECT 1 FROM pat_filterlist f where d.patid=f.patid)
diff --git a/smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml b/smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml
index 9a47f1f..f241ff6 100644
--- a/smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/PatMedInhospMapper.xml
@@ -247,18 +247,15 @@
AND b.del_flag = 0
AND a.idcardno IS NOT NULL
<if test="inhospid != null">and b.inhospid = #{inhospid}</if>
- <if test="startOutHospTime != null ">and date_format(b.endtime,'%y%m%d') >=
- date_format(#{startOutHospTime},'%y%m%d')
- </if>
- <if test="endOutHospTime != null ">and date_format(b.endtime,'%y%m%d') <=
- date_format(#{endOutHospTime},'%y%m%d')
- </if>
- <if test="startInHospTime != null ">and date_format(b.starttime,'%y%m%d') >=
- date_format(#{startInHospTime},'%y%m%d')
- </if>
- <if test="endInHospTime != null ">and date_format(b.starttime,'%y%m%d') <=
- date_format(#{endInHospTime},'%y%m%d')
- </if>
+ <!--
+ 鏃堕棿鑼冨洿涓嶈鍐欐垚 date_format(b.endtime,'%y%m%d') >= date_format(#{...},'%y%m%d')锛�
+ 鍒椾笂濂楀嚱鏁颁細璁� endtime / starttime 涓婄殑绱㈠紩褰诲簳澶辨晥锛堣�屼笖 %y 鏄袱浣嶅勾浠斤級銆�
+ 杩欓噷鎶婂嚱鏁版尓鍒板弬鏁颁晶锛岃涔夌瓑浠凤細>= 褰撳ぉ 0 鐐癸紝< 娆℃棩 0 鐐广��
+ -->
+ <if test="startOutHospTime != null ">and b.endtime >= date(#{startOutHospTime})</if>
+ <if test="endOutHospTime != null ">and b.endtime < date(#{endOutHospTime}) + interval 1 day</if>
+ <if test="startInHospTime != null ">and b.starttime >= date(#{startInHospTime})</if>
+ <if test="endInHospTime != null ">and b.starttime < date(#{endInHospTime}) + interval 1 day</if>
<if test="hospitalname != null and hospitalname != ''">and hospitalname like concat('%', #{hospitalname},
'%')
</if>
@@ -276,7 +273,6 @@
<if test="orgid != null ">and b.orgid = #{orgid}</if>
<if test="campusid != null ">and b.campusid = #{campusid}</if>
<if test="serialnum != null ">and b.serialnum = #{serialnum}</if>
- <if test="endtime != null ">and b.endtime = #{endtime}</if>
<if test="patno != null ">and b.patno = #{patno}</if>
<if test="nurseId != null ">and b.nurse_id = #{nurseId}</if>
<if test="nurseName != null and nurseName != ''">and b.nurse_name = #{nurseName}</if>
@@ -353,20 +349,12 @@
<if test="medicalCode != null and medicalCode != ''">and b.medical_code = #{medicalCode}</if>
<if test="medicalName != null and medicalName != ''">and b.medical_name = #{medicalName}</if>
<if test="medicalCompany != null and medicalCompany != ''">and b.medical_company = #{medicalCompany}</if>
- GROUP BY
- b.inhospid,
- a.age,
- a.age_unit,
- a.telcode,
- a.id,
- a.sex
- <if test="cry != null and cry==1">
- order by b.endtime desc
- </if>
- <if test="cry != null and cry==2">
- order by b.endtime desc
- </if>
- <if test="cry != null and cry==3">
+ <!--
+ 鍘熸潵杩欓噷鏈変竴娈� GROUP BY b.inhospid, a.age, a.age_unit, a.telcode, a.id, a.sex銆�
+ b.inhospid 鏄富閿�乤.id = b.patid 鏄竴瀵逛竴鍏宠仈锛屽垎缁勪笉浼氬悎骞朵换浣曡锛屽彧浼氳 MySQL
+ 澶氬缓涓�寮犱复鏃惰〃銆佸苟璁╁垎椤电殑 count 鍙樻垚娲剧敓琛ㄣ�傝繖閲岀洿鎺ュ幓鎺夈��
+ -->
+ <if test="cry != null and (cry == 1 or cry == 2 or cry == 3)">
order by b.endtime desc
</if>
<if test="cry != null and cry==0">
@@ -661,6 +649,19 @@
AND d.del_flag = 0
</select>
+ <!-- 鎵归噺鏌ユ爣绛撅紝鏇夸唬鍒楄〃閫愯璋冪敤 getTagnameBypatid 鐨� N+1 鏌ヨ -->
+ <select id="selectTagnameByPatids" resultType="com.smartor.domain.PatArchivetag">
+ SELECT d.patid AS patid,
+ GROUP_CONCAT(d.tagname, ', ') AS tagname
+ FROM pat_archivetag d
+ WHERE d.del_flag = 0
+ AND d.patid IN
+ <foreach collection="patids" item="patid" open="(" separator="," close=")">
+ #{patid}
+ </foreach>
+ GROUP BY d.patid
+ </select>
+
<select id="selectPatMedInhospByInhospid" parameterType="Long" resultMap="PatMedInhospResult">
<include refid="selectPatMedInhospVo"/>
--
Gitblit v1.9.3