浏览代码

新增:

1、新增访问访客的接口。
    2、新增通过语音触发访客预约的多轮逻辑
dev-vistor
10710 1年前
父节点
当前提交
1a732f8277
共有 6 个文件被更改,包括 358 次插入9 次删除
  1. +3
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmVisitorsPo.java
  2. +20
    -0
      xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/feign/RemoteVisitorsController.java
  3. +7
    -0
      xueyi-modules/xueyi-nlt/pom.xml
  4. +13
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/controller/DmIntentController.java
  5. +271
    -0
      xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/VisitorTemplate.java
  6. +44
    -9
      xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/staff/controller/DmVisitorsController.java

+ 3
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/digitalmans/domain/po/DmVisitorsPo.java 查看文件

@@ -68,6 +68,9 @@ public class DmVisitorsPo extends TBaseEntity {
@Excel(name = "上传头像")
protected String avatar;

@Excel(name = "租户id")
protected Long tenantId;

@GraphQLField
protected Long resourceId;



+ 20
- 0
xueyi-api/xueyi-api-system/src/main/java/com/xueyi/system/api/staff/feign/RemoteVisitorsController.java 查看文件

@@ -0,0 +1,20 @@
package com.xueyi.system.api.staff.feign;

import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.constant.basic.ServiceConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.system.api.organize.feign.factory.RemoteUserFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

@FeignClient(contextId = "remoteVisitorsController", value = ServiceConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteVisitorsController {

@GetMapping(value="/visitors/inner/selectByTenant")
public AjaxResult selectByTenantInner(@RequestParam(value = "tenantId") Long tenantId,
@RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

@PostMapping(value="/visitors/api/selectByTenant")
public AjaxResult selectByTenantApi(@RequestBody Long tenantId);

}

+ 7
- 0
xueyi-modules/xueyi-nlt/pom.xml 查看文件

@@ -81,6 +81,13 @@
<artifactId>xueyi-api-system</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.1</version>
</dependency>

</dependencies>

<build>


+ 13
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/controller/DmIntentController.java 查看文件

@@ -162,6 +162,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt

@Autowired
private ISysLlmService sysLlmService;

@Autowired
private VisitorTemplate visitorTemplate;
/**
* 意图请求
列表
@@ -228,6 +231,12 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
response.setH5(meetingOrderTemplate.handle(intent.getDevId(),intent.getContent(), enterpriseId));
response.setAction("Meeting");
return AjaxResult.success(response);
case "visitorAppoint":
response.setMsg("");
response.setSkillCode("2");
response.setAction("VisitorAppoint");
response.setH5(visitorTemplate.handle(intent.getDevId(), intent.getContent(), enterpriseId));
return AjaxResult.success(response);
case "delivery":
response.setMsg("");
response.setSkillCode("33");
@@ -239,6 +248,7 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
response.setH5(flightMessageTemplate.handle(intent.getDevId(),intent.getContent(), enterpriseId));
return AjaxResult.success(response);


}
}

@@ -551,6 +561,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt
// 做会议室处理
response.setH5(meetingOrderTemplate.handle(intent.getDevId(), intent.getContent(), Long.parseLong(SecurityContextHolder.getLocalMap().get("enterprise_id").toString())));
break;
case "2":
response.setH5(visitorTemplate.handle(intent.getDevId(), intent.getContent(), Long.parseLong(SecurityContextHolder.getLocalMap().get("enterprise_id").toString())));
break;
case "33":
// 做快递预约处理
response.setH5(deliveryOrderTemplate.handle(intent.getDevId(), intent.getContent(), Long.parseLong(SecurityContextHolder.getLocalMap().get("enterprise_id").toString())));


+ 271
- 0
xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/template/VisitorTemplate.java 查看文件

@@ -0,0 +1,271 @@
package com.xueyi.nlt.nlt.template;


import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.api.exception.NacosException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xueyi.common.core.constant.digitalman.SkillConstants;
import com.xueyi.common.core.web.result.AjaxResult;
import com.xueyi.nlt.api.nlt.domain.vo.CoversationSessionVo;
import com.xueyi.nlt.nlt.domain.vo.MeetingParamVo;
import com.xueyi.system.api.digitalmans.domain.dto.DmVisitorsDto;
import com.xueyi.system.api.staff.feign.RemoteVisitorsController;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service("visitor-order")
public class VisitorTemplate implements BaseTemplate{

private static final Logger log = LoggerFactory.getLogger(MeetingOrderTemplate.class);

@Autowired
private RemoteVisitorsController remoteVisitorsController;

@Autowired
NacosConfigManager nacosConfigManager;

@Autowired
private RedisTemplate<Object,Object> objectRedisTemplate;

private static final List<MeetingParamVo> DATE_PARAMS = new ArrayList<>();

@PostConstruct
private void init(){
try {
String meetingParams = nacosConfigManager.getConfigService().getConfig("meeting_date_and_hour", "DEFAULT_GROUP", 5000);
if (StringUtils.isNotBlank(meetingParams)) {
try {
DATE_PARAMS.addAll(JSONArray.parseArray(meetingParams, MeetingParamVo.class));
DATE_PARAMS.forEach(item -> {
// 将item.getContent()按照空格分割成数组,然后将数组转换成流,最后将流转化成整数数组赋值给item.getCompareArray()
item.setCompareArray(Arrays.stream(item.getContent().split(" ")).mapToInt(Integer::parseInt).toArray());
// item.setCompareArray(Arrays.stream(item.getContent().split(" ")));
String[] split = item.getContent().split(" ");
if (split != null && split.length > 0) {
int i = Integer.parseInt(split[0]);
if (i > -1) {
item.setMinute(i);
} else {
item.setMinute(-1);
}
i = Integer.parseInt(split[1]);
if (i > -1) {
item.setHour(i);
} else {
item.setHour(-1);
}
i = Integer.parseInt(split[2]);
if (i > -1) {
item.setDay(i);
} else {
item.setDay(-1);
}
i = Integer.parseInt(split[3]);
if (i > -1) {
item.setMonth(i);
} else {
item.setMonth(-1);
}
i = Integer.parseInt(split[4]);
if (i > -1) {
item.setDayOfWeek(i);
} else {
item.setDayOfWeek(-1);
}
i = Integer.parseInt(split[5]);
if (i > -1) {
item.setOffset(i);
} else {
item.setOffset(-1);
}
}
});
} catch (JSONException e) {
log.error("解析日期参数失败", e);
}
}
} catch (JSONException | NacosException e) {
log.error("解析日期参数失败", e);
}
}
@Override
public JSONObject handle(String dev, String content) {
return null;
}

@Override
public JSONObject handle(String devId, String content, Long tenantId) {
CoversationSessionVo session = (CoversationSessionVo) objectRedisTemplate.opsForValue().get("group:device" + ":" + devId + ":" +"session");
if (session == null) {
session = new CoversationSessionVo();
session.setCategory("visitorAppoint");
session.setFormat(new JSONObject());
session.getFormat().put("skillCode", SkillConstants.SkillType.CREATE_VISITOR_INFO.getCode());
}

CoversationSessionVo dateSession = processRegexDatetime(content,session);
if (dateSession != null ){
session = dateSession;
}

CoversationSessionVo nameSession = processRegexName(content, session, tenantId);
if (nameSession != null){
session = nameSession;
}

if(!content.startsWith("##")){
String regex = "1\\d{10}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
session.getFormat().put("phoneNumber", matcher.group());
}
}

objectRedisTemplate.opsForValue().set("group:device" + ":" + devId + ":" +"session", session, 1, TimeUnit.MINUTES);
session.getFormat().put("skillCode", SkillConstants.SkillType.CREATE_VISITOR_INFO.getCode());
session.getFormat().put("action", "VisitorAppoint");
return session.getFormat();
}

public CoversationSessionVo processRegexDatetime(String content, CoversationSessionVo session) {
List<Integer[]> timeList = new ArrayList<>();
DATE_PARAMS.forEach(item-> {
if (content.matches(item.getName())) {
int[] tmp = item.getCompareArray();
// 将int[]转化成Integer[]
Integer[] tmpInteger = new Integer[tmp.length];
for (int i = 0; i < tmp.length; i++) {
tmpInteger[i] = tmp[i];
}
timeList.add(tmpInteger);
}
});
if (timeList.size() == 0) {
//没有匹配正则,返回
return session;

}
Integer results[] = new Integer[6];
// 计算二维矩阵每列最大值
for (Integer[] item : timeList) {
for (int i = 0; i < item.length; i++) {
if (results[i] == null) {
results[i] = item[i];
} else {
if (results[i] < item[i]) {
results[i] = item[i];
}
}
}
}
if (results[2] > 0) {
DateTimeFormatter resultDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
if (!session.getFormat().containsKey("date")) {
session.getFormat().put("date",resultDateFormatter.format(LocalDateTime.now()));
}
LocalDateTime date = LocalDateTime.parse(session.getFormat().getString("date") + " 00:00:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
date = date.withDayOfMonth(results[2]);
if (results[3] > 0) {
date = date.withMonth(results[3]);
}
session.getFormat().put("date",resultDateFormatter.format(date));
}
if (results[4] > 0) {
LocalDateTime date = LocalDateTime.now();
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
int offset = results[4] - date.getDayOfWeek().getValue();
date = date.plusDays(offset);
session.getFormat().put("date",dateFormatter.format(date));
}
if (results[5] >= 0) {
LocalDateTime date = LocalDateTime.now();
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
date = date.plusDays(results[5]);
session.getFormat().put("date",dateFormatter.format(date));
}
return session;
}

public CoversationSessionVo processRegexName(String content, CoversationSessionVo session, Long tenantId){
if(!StringUtils.isEmpty(content)){
if(content.startsWith("##")){
content = content.replace("##", "");
JSONArray result = remoteVisitorsController.selectByTenantApi(tenantId).toJson().getJSONArray("data");
for(int i = 0; i < result.size(); i++){
JSONObject temp = result.getJSONObject(i);
if(content.equals(temp.getString("id"))){
session.getFormat().put("confirmedName", temp);
return session;
}
}
}

if(content.startsWith("@@")){
JSONObject newVisitor = new JSONObject();
newVisitor.put("name", content.replace("@@", ""));
session.getFormat().put("confirmedName", newVisitor);
return session;
}
}
JSONArray result = remoteVisitorsController.selectByTenantApi(tenantId).toJson().getJSONArray("data");
JSONArray newResult = new JSONArray();
for(int i = 0; i < result.size(); i++){
JSONObject temp = result.getJSONObject(i);
if(match(content, temp.getString("name"))){
newResult.add(temp);
}
}
session.getFormat().put("nameList", newResult);
return session;
}

public boolean match(String content, String regex){
String contentPinyin = toPinyin(content);
String regexPinyin = toPinyin(regex);
return contentPinyin.contains(regexPinyin);
}

public static String toPinyin(String chinese){
String pinyinStr = "";
char[] newChar = chinese.toCharArray();
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
for (int i = 0; i < newChar.length; i++) {
if (newChar[i] > 19967 && newChar[i] < 40959) {
try {
pinyinStr += PinyinHelper.toHanyuPinyinStringArray(newChar[i], defaultFormat)[0];
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
}else{
pinyinStr += newChar[i];
}
}
return pinyinStr;
}
}

+ 44
- 9
xueyi-modules/xueyi-system/src/main/java/com/xueyi/system/staff/controller/DmVisitorsController.java 查看文件

@@ -1,6 +1,8 @@
package com.xueyi.system.staff.controller;

import cn.hutool.core.text.CharSequenceUtil;
import com.xueyi.common.cache.utils.SourceUtil;
import com.xueyi.common.core.constant.basic.SecurityConstants;
import com.xueyi.common.core.utils.core.ObjectUtil;
import com.xueyi.common.core.utils.file.FileTypeUtil;
import com.xueyi.common.core.utils.file.MimeTypeUtil;
@@ -14,20 +16,19 @@ import com.xueyi.common.security.annotation.RequiresPermissions;
import com.xueyi.common.web.entity.controller.BaseController;
import com.xueyi.file.api.domain.SysFile;
import com.xueyi.file.api.feign.RemoteFileService;
import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto;
import com.xueyi.system.api.digitalmans.domain.dto.DmVisitorsDto;
import com.xueyi.system.api.digitalmans.feign.RemoteManDeviceService;
import com.xueyi.system.api.model.Source;
import com.xueyi.system.api.staff.feign.RemoteVisitorsController;
import com.xueyi.system.digitalmans.domain.query.DmManDeviceQuery;
import com.xueyi.system.digitalmans.service.IDmManDeviceService;
import com.xueyi.system.staff.domain.query.DmVisitorsQuery;
import com.xueyi.system.staff.service.IDmVisitorsService;
import com.xueyi.system.staff.service.impl.DmVisitorsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
@@ -46,6 +47,40 @@ public class DmVisitorsController extends BaseController<DmVisitorsQuery, DmVisi
@Autowired
private RemoteFileService remoteFileService;

@Autowired
DmVisitorsServiceImpl dmVisitorsService;

@Autowired
private RemoteVisitorsController remoteVisitorsController;

@Autowired
private RemoteManDeviceService manDeviceService;

@Autowired
IDmManDeviceService dmManDeviceService;

@PostMapping("/api/selectByTenant")
public AjaxResult select(@RequestBody Long tenantId){
List<DmManDeviceDto> manDeviceDtoList = dmManDeviceService.manDeviceListNotNullByTenantId(tenantId);
if(!manDeviceDtoList.isEmpty()){
R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(manDeviceDtoList.get(0).getDeviceId());
Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId());
return remoteVisitorsController.selectByTenantInner(tenantId, tenantId, source.getMaster(), SecurityConstants.INNER);
}else{
return AjaxResult.success();
}
}

@GetMapping("/inner/selectByTenant")
public AjaxResult selectByTenant(@RequestParam Long tenantId){
DmVisitorsQuery query = new DmVisitorsQuery();
query.setTenantId(tenantId);
System.out.println(query.toString());
List<DmVisitorsDto> result = dmVisitorsService.selectListScope(query);
return AjaxResult.success(result);
}


/** 定义节点名称 */
@Override
protected String getNodeName() {


正在加载...
取消
保存