zoujiajian 1 year ago
parent
commit
20fee1d95f

+ 5 - 5
netflix-dao/src/main/java/com/cyksj/model/entity/CorpKfServicerSessionRecord.java

@@ -36,11 +36,6 @@ public class CorpKfServicerSessionRecord extends BaseEntity{
 	 */
 	private Integer changeType;
 
-	/**
-	 * 消息id
-	 */
-	private String msgId;
-
 	/**
 	 * 0未评价 1.满意 2.一般 3.不满意
 	 * 满意度
@@ -52,6 +47,11 @@ public class CorpKfServicerSessionRecord extends BaseEntity{
 	 */
 	private Boolean sendSatisfaction;
 
+	/**
+	 * 会话开始时间
+	 */
+	private Date startTime;
+
 	/**
 	 * 会话关闭时间
 	 */

+ 53 - 4
netflix-dao/src/main/java/com/cyksj/model/kf/CorpKfSatisfactionMsg.java

@@ -1,8 +1,11 @@
 package com.cyksj.model.kf;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.util.List;
+
 /**
  * 项目名: yhlxj2
  * 文件名: CorpKfSatisfactionMsg
@@ -11,12 +14,58 @@ import lombok.Setter;
  */
 @Getter
 @Setter
+@JsonInclude(JsonInclude.Include.NON_NULL)
 public class CorpKfSatisfactionMsg {
-	private String code;
-
+	private String touser;
+	private String open_kfid;
 	private String msgid;
-
 	private String msgtype;
+	private MsgMenu msgmenu;
+
+	@Getter
+	@Setter
+	public static class MsgMenu {
+		private String head_content;
+		private List<MenuItem> list;
+		private String tail_content;
+
+		@Getter
+		@Setter
+		public static class MenuItem {
+			private String type;
+			private Click click;
+//			private View view;
+//			private MiniProgram miniprogram;
+//			private Text text;
+
+			@Getter
+			@Setter
+			public static class Click {
+				private String id;
+				private String content;
+			}
+
+			@Getter
+			@Setter
+			public static class View {
+				private String url;
+				private String content;
+			}
+
+			@Getter
+			@Setter
+			public static class MiniProgram {
+				private String appid;
+				private String pagepath;
+				private String content;
+			}
 
-	private String msgmenu;
+			@Getter
+			@Setter
+			public static class Text {
+				private String content;
+				private int no_newline;
+			}
+		}
+	}
 }

+ 14 - 0
netflix-dao/src/main/java/com/cyksj/model/kf/ServiceStateResponse.java

@@ -0,0 +1,14 @@
+package com.cyksj.model.kf;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ServiceStateResponse {
+    private int errcode;
+    private String errmsg;
+    private Integer service_state;
+    //接待人员的userid。第三方应用为密文userid,即open_userid。仅当state=3时有效
+    private String servicer_userid;
+}

+ 2 - 2
netflix-service/src/main/java/com/cyksj/service/corp/WxCorpOps.java

@@ -235,7 +235,7 @@ public interface WxCorpOps {
 	/**
 	 * 发送满意度调查msg
 	 */
-	void sendSatisfactionMsg(String msgId) throws Exception;
+	void sendSatisfactionMsg(Long sessionId, String openKfId, String externalUserId) throws Exception;
 
 	CorpKfUserInfo getCorpKfUserInfo(String externalUserid) throws Exception;
 
@@ -259,7 +259,7 @@ public interface WxCorpOps {
 	 */
 	void sendTextMsg(String corpId, WxCorpKfMsgSendRequest wxCpKfMsgSendRequest) throws Exception;
 
-	Integer getCorpKfSessionStatus(String corpId, String openKfId, String externalUserid) throws Exception;
+	ServiceStateResponse getCorpKfSessionStatus(String corpId, String openKfId, String externalUserid) throws Exception;
 
 	/**
 	 * 获取素材

+ 27 - 17
netflix-service/src/main/java/com/cyksj/service/corp/impl/CorpServiceImpl.java

@@ -648,6 +648,10 @@ public class CorpServiceImpl implements CorpService {
 			String msgType = item.getMsgType();
 			corpKfAccountSessionChat.setOpenKfId(openKfid);
 			corpKfAccountSessionChat.setMsgid(msgId);
+			if (StrUtil.isEmpty(servicerUserId)) {
+				ServiceStateResponse corpKfSessionStatus = wxCorpOps.getCorpKfSessionStatus(corpId, openKfId, externalUserId);
+				servicerUserId = corpKfSessionStatus.getServicer_userid();
+			}
 			corpKfAccountSessionChat.setServicerUserid(servicerUserId);
 			corpKfAccountSessionChat.setExternalUserid(externalUserId);
 			corpKfAccountSessionChat.setOrign(origin);
@@ -660,32 +664,37 @@ public class CorpServiceImpl implements CorpService {
 				//会话状态为待处理 则分配接待人员
 				assignKfSession(corpId, openKfId, externalUserId, corpKfAccountSessionConfig);
 			}
-			syncSessionSatisfaction(openKfId, item);
+			syncSessionSatisfaction(item);
 		}
 	}
 
-	private void syncSessionSatisfaction(String openKfId, WxCpKfMsgListResp.WxCpKfMsgItem item) throws Exception {
+	private void syncSessionSatisfaction(WxCpKfMsgListResp.WxCpKfMsgItem item) throws Exception {
 		Integer satisfaction = null;
 		WxCorpTextMsg text = item.getText();
 		//自定义菜单id
 		if (text.getMenu_id() != null) {
+			String[] split = text.getMenu_id().split("-");
+			if (split.length < 2) {
+				return;
+			}
+			String menuId = split[0];
+			String sessionId = split[1];
 			//满意
-			if ("101".equals(text.getMenu_id())) {
+			if ("101".equals(menuId)) {
 				satisfaction = 1;
 			}
 			//一般
-			if ("102".equals(text.getMenu_id())) {
+			if ("102".equals(menuId)) {
 				satisfaction = 2;
 			}
 			//不满意
-			if ("103".equals(text.getMenu_id())) {
+			if ("103".equals(menuId)) {
 				satisfaction = 3;
 			}
 			if (satisfaction != null) {
 				corpKfServicerSessionRecordMapper.update(null, Wrappers.lambdaUpdate(CorpKfServicerSessionRecord.class)
 						.set(CorpKfServicerSessionRecord::getSatisfaction, satisfaction)
-						.eq(CorpKfServicerSessionRecord::getOpenKfId, openKfId)
-						.eq(CorpKfServicerSessionRecord::getMsgId, item.getMsgId()));
+						.eq(CorpKfServicerSessionRecord::getId, sessionId));
 			}
 		}
 	}
@@ -705,7 +714,6 @@ public class CorpServiceImpl implements CorpService {
 			newSession.setExternalUserid(externalUserId);
 			newSession.setChangeType(changeType);
 			newSession.setServiceState(0);
-			newSession.setMsgId(msgId);
 			corpKfServicerSessionRecordMapper.insert(newSession);
 			//等待用户删除
 			delQueueUser(openKfId, externalUserId);
@@ -716,7 +724,7 @@ public class CorpServiceImpl implements CorpService {
 			setDbSessionState(openKfId, externalUserId, sendTime);
 			//记录新的客服会话
 			String newServicerUserid = wxCpKfMsgItem.getNewServicerUserid();
-			transCorpKfSessionToServicer(corpId, openKfId, newServicerUserid, externalUserId, changeType, 3);
+			transCorpKfSessionToServicer(corpId, openKfId, newServicerUserid, externalUserId, changeType, 3, DateTime.of(sendTime * 1000));
 		}
 		//3-结束会话 4-重新接入已结束/已转接会话
 		if (changeType == 3 || changeType == 4) {
@@ -758,9 +766,8 @@ public class CorpServiceImpl implements CorpService {
 	/**
 	 * 变更用户会话状态
 	 * serviceState 0未处理 1由智能助手接待 2待接入池排队中 3由人工接待 4 已结束/未开始
-	 *
 	 */
-	private void transCorpKfSessionToServicer(String corpId, String openKfId, String userid, String externalUserId, Integer changeType, Integer serviceState) throws Exception {
+	private void transCorpKfSessionToServicer(String corpId, String openKfId, String userid, String externalUserId, Integer changeType, Integer serviceState, Date sendTime) throws Exception {
 		//记录接待人员会话
 		CorpKfServicerSessionRecord corpKfServicerSessionRecord = new CorpKfServicerSessionRecord();
 		corpKfServicerSessionRecord.setOpenKfId(openKfId);
@@ -768,6 +775,7 @@ public class CorpServiceImpl implements CorpService {
 		corpKfServicerSessionRecord.setServicerUserid(userid);
 		corpKfServicerSessionRecord.setExternalUserid(externalUserId);
 		corpKfServicerSessionRecord.setChangeType(changeType);
+		corpKfServicerSessionRecord.setStartTime(sendTime);
 		corpKfServicerSessionRecordMapper.insert(corpKfServicerSessionRecord);
 		//调用微信客服接口 变更会话状态
 		wxCorpOps.transCorpKfSessionToServicer(corpId, openKfId, userid, externalUserId, serviceState);
@@ -783,7 +791,8 @@ public class CorpServiceImpl implements CorpService {
 			return;
 		}
 		//查询会话状态
-		Integer state = wxCorpOps.getCorpKfSessionStatus(corpId, openKfId, externalUserid);
+		ServiceStateResponse serviceStateResponse = wxCorpOps.getCorpKfSessionStatus(corpId, openKfId, externalUserid);
+		Integer state = serviceStateResponse.getService_state();
 		//0.未处理 1.人工智能接待 可调用api发送消息
 		if (state == null || state != 0 || state != 1) {
 			log.info("目前openKfId:{}用户eid:{}会话处于状态中state:{},无法发送消息", openKfId, externalUserid, state);
@@ -804,8 +813,9 @@ public class CorpServiceImpl implements CorpService {
 	 */
 	public void assignKfSession(String corpId, String openKfId, String externalUserid, CorpKfAccountSessionConfig corpKfAccountSessionConfig) throws Exception {
 		//查询用户会话状态 0待处理就进行处理
-		Integer sessionStatus = wxCorpOps.getCorpKfSessionStatus(corpId, openKfId, externalUserid);
-		if (sessionStatus != 0) {
+		ServiceStateResponse serviceStateResponse = wxCorpOps.getCorpKfSessionStatus(corpId, openKfId, externalUserid);
+		Integer state = serviceStateResponse.getService_state();
+		if (state != 0) {
 			return;
 		}
 		//用户是否已有会话
@@ -864,7 +874,7 @@ public class CorpServiceImpl implements CorpService {
 			//随机分配一个客服
 			CorpKfServicerResp.CorpKfServicer corpKfServicer = corpKfServicers.get(RandomUtil.randomInt(corpKfServicers.size()));
 			//变更会话状态
-			transCorpKfSessionToServicer(corpId, openKfId, corpKfServicer.getUserid(), externalUserid, null, 3);
+			transCorpKfSessionToServicer(corpId, openKfId, corpKfServicer.getUserid(), externalUserid, null, 3, DateTime.now());
 			return;
 		}
 		//筛选符合条件的客服
@@ -883,7 +893,7 @@ public class CorpServiceImpl implements CorpService {
 		//选择第一个分配接待
 		CorpKfServicerDto corpKfServicerDto = filterKfCs.get(0);
 		//变更会话状态
-		transCorpKfSessionToServicer(corpId, openKfId, corpKfServicerDto.getServicerUserid(), externalUserid, null, 3);
+		transCorpKfSessionToServicer(corpId, openKfId, corpKfServicerDto.getServicerUserid(), externalUserid, null, 3, DateTime.now());
 	}
 
 	private void moveWaitingQueue(String corpId, String openKfId, String externalUserId) throws Exception {
@@ -925,7 +935,7 @@ public class CorpServiceImpl implements CorpService {
 		if (corpKfServicerSessionRecord != null) {
 			corpKfServicerSessionRecord.setCloseTime(DateTime.of(sendTime * 1000));
 			corpKfServicerSessionRecord.setServiceState(1);
-			wxCorpOps.sendSatisfactionMsg(corpKfServicerSessionRecord.getMsgId());
+			wxCorpOps.sendSatisfactionMsg(corpKfServicerSessionRecord.getId(), openKfId, externalUserId);
 			corpKfServicerSessionRecord.setSendSatisfaction(true);
 			corpKfServicerSessionRecordMapper.updateById(corpKfServicerSessionRecord);
 		}

+ 11 - 12
netflix-service/src/main/java/com/cyksj/service/corp/impl/WxCorpOpsImpl.java

@@ -60,8 +60,8 @@ public class WxCorpOpsImpl implements WxCorpOps {
 	@Autowired
 	private RedisService redisService;
 
-	//微信客服满意度内容
-	private static final String SATISFACTION_CONTENT = "{\"head_content\":\"您对本次服务是否满意呢? \",\"list\":[{\"type\":\"click\",\"click\":{\"id\":\"101\",\"content\":\"满意\"}},{\"type\":\"click\",\"click\":{\"id\":\"102\",\"content\":\"一般\"}},{\"type\":\"click\",\"click\":{\"id\":\"103\",\"content\":\"不满意\"}}]}";
+	//微信客服满意度
+	private static final String SATISFACTION = "{\"touser\":\"EXTERNAL_USERID\",\"open_kfid\":\"OPEN_KFID\",\"msgid\":\"MSGID\",\"msgtype\":\"msgmenu\",\"msgmenu\":{\"head_content\":\"本次服务已结束,如有其他需要可重新发起对话。\\n您对本次服务是否满意呢? \",\"list\":[{\"type\":\"click\",\"click\":{\"id\":\"101-%s\",\"content\":\"满意\"}},{\"type\":\"click\",\"click\":{\"id\":\"101-%s\",\"content\":\"一般\"}},{\"type\":\"click\",\"click\":{\"id\":\"101-%s\",\"content\":\"不满意\"}}]}}";
 
 	@Override
 	public CorpExternalContactInfo getExternalContact(String corpId, String userId) throws Exception {
@@ -986,12 +986,11 @@ public class WxCorpOpsImpl implements WxCorpOps {
 	}
 
 	@Override
-	public void sendSatisfactionMsg(String msgId) throws Exception {
+	public void sendSatisfactionMsg(Long sessionId, String openKfId, String externalUserId) throws Exception {
 		String url = "https://qyapi.weixin.qq.com/cgi-bin/kf/send_msg?access_token=" + getAccessToken(yhlXWxCorpConfig.getCorpId());
-		CorpKfSatisfactionMsg corpKfSatisfactionMsg = new CorpKfSatisfactionMsg();
-		corpKfSatisfactionMsg.setCode(msgId);
-		corpKfSatisfactionMsg.setMsgtype("msgtype");
-		corpKfSatisfactionMsg.setMsgmenu(SATISFACTION_CONTENT);
+		CorpKfSatisfactionMsg corpKfSatisfactionMsg = Jsons.parseObject(String.format(SATISFACTION, sessionId, sessionId, sessionId), CorpKfSatisfactionMsg.class);
+		corpKfSatisfactionMsg.setTouser(externalUserId);
+		corpKfSatisfactionMsg.setOpen_kfid(openKfId);
 		HttpResponse<String> res =
 				J11HttpC.custom()
 						.ofPost()
@@ -1124,7 +1123,7 @@ public class WxCorpOpsImpl implements WxCorpOps {
 
 
 	@Override
-	public Integer getCorpKfSessionStatus(String corpId, String openKfId, String externalUserid) throws Exception {
+	public ServiceStateResponse getCorpKfSessionStatus(String corpId, String openKfId, String externalUserid) throws Exception {
 		String url = "https://qyapi.weixin.qq.com/cgi-bin/kf/service_state/get?access_token=" + getAccessToken(corpId);
 		JSONObject jsonObject = new JSONObject();
 		jsonObject.putOpt("open_kfid", openKfId);
@@ -1139,11 +1138,11 @@ public class WxCorpOpsImpl implements WxCorpOps {
 		if (200 != res.statusCode()) {
 			throw BusinessRuntimeException.getInstance("用户会话状态消息: " + res.body());
 		}
-		JSONObject re = Jsons.parseObject(res.body(), JSONObject.class);
-		if (re.getInt("errcode") != 0) {
-			throw BusinessRuntimeException.getInstance("添加接待人员信息错误: " + re.getStr("errmsg"));
+		ServiceStateResponse serviceStateResponse = Jsons.parseObject(res.body(), ServiceStateResponse.class);
+		if (serviceStateResponse.getErrcode() != 0) {
+			throw BusinessRuntimeException.getInstance("添加接待人员信息错误: " + serviceStateResponse.getErrmsg());
 		}
-		return re.getInt("service_state");
+		return serviceStateResponse;
 	}
 
 	@Override

+ 3 - 5
netflix-web/src/main/java/com/cyksj/web/controller/manage/corp/wxkf/CorpKfMsgController.java

@@ -36,15 +36,13 @@ public class CorpKfMsgController {
 	 * 发送满意度调查消息
 	 */
 	@PostMapping("/send/satisfaction/msg")
-	public void sendSatisfactionMsg(String msgId) throws Exception {
-		wxCorpOps.sendSatisfactionMsg(msgId);
-		CorpKfServicerSessionRecord corpKfServicerSessionRecord = corpKfServicerSessionRecordMapper.selectOne(Wrappers.lambdaQuery(CorpKfServicerSessionRecord.class)
-				.eq(CorpKfServicerSessionRecord::getMsgId, msgId)
-				.last("limit 1"));
+	public void sendSatisfactionMsg(Long id) throws Exception {
+		CorpKfServicerSessionRecord corpKfServicerSessionRecord = corpKfServicerSessionRecordMapper.selectById(id);
 		//更新发送满意度字段
 		if (corpKfServicerSessionRecord != null) {
 			corpKfServicerSessionRecord.setSendSatisfaction(true);
 			corpKfServicerSessionRecordMapper.updateById(corpKfServicerSessionRecord);
+			wxCorpOps.sendSatisfactionMsg(id, corpKfServicerSessionRecord.getOpenKfId(), corpKfServicerSessionRecord.getExternalUserid());
 		}
 	}