Reviewed-on: http://39.105.23.186:3000/develop/digimeta-MultiSaas/pulls/166tags/B.2.3.1_20231118_release
| @@ -0,0 +1,26 @@ | |||
| package com.xueyi.system.api.digitalmans.domain.dto; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmH5MenuPo; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| import java.util.List; | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmH5MenuDto extends DmH5MenuPo { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| protected List<DmScreenIconDto> dmScreenIconDto; | |||
| protected List<DmH5MenuDto> children; | |||
| protected Integer level; | |||
| protected Integer displayType; | |||
| protected Integer pos; | |||
| } | |||
| @@ -20,6 +20,5 @@ public class DmScreenIconDto extends DmScreenIconPo { | |||
| private String iconUrl; | |||
| private Integer pos; | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| package com.xueyi.system.api.digitalmans.domain.po; | |||
| import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.xueyi.common.core.annotation.Excel; | |||
| import com.xueyi.common.core.web.entity.base.BaseEntity; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| import static com.xueyi.common.core.constant.basic.EntityConstants.REMARK; | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| @TableName(value = "dm_h5_menu", excludeProperty = { REMARK }) | |||
| public class DmH5MenuPo extends BaseEntity { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| /** 租户名 */ | |||
| @Excel(name = "父节点id") | |||
| protected Long parentId; | |||
| /** 菜单名 */ | |||
| @Excel(name = "菜单名") | |||
| protected String title; | |||
| /** 菜单类型 */ | |||
| @Excel(name = "菜单类型") | |||
| protected String menuType; | |||
| } | |||
| @@ -39,4 +39,10 @@ public class DmScreenIconPo extends TBaseEntity { | |||
| @Excel(name = "备注") | |||
| protected String remark; | |||
| protected String type; | |||
| protected Long manId; | |||
| protected Long pos; | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| package com.xueyi.system.api.digitalmans.domain.query; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmH5MenuPo; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| import java.util.List; | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmH5MenuQuery extends DmH5MenuPo { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| } | |||
| @@ -23,7 +23,7 @@ import java.util.List; | |||
| * @author yrx | |||
| */ | |||
| @FeignClient(contextId = "remoteDigitalmanService", value = ServiceConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) | |||
| public interface RemoteDigitalmanService { | |||
| public interface RemoteDigitalmanService { | |||
| /** | |||
| * 同步数字人信息 | 内部调用 | |||
| @@ -0,0 +1,24 @@ | |||
| package com.xueyi.system.api.digitalmans.feign; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.constant.basic.ServiceConstants; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.api.organize.feign.factory.RemoteUserFallbackFactory; | |||
| import org.springframework.cloud.openfeign.FeignClient; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.RequestHeader; | |||
| import org.springframework.web.bind.annotation.RequestParam; | |||
| import org.springframework.web.bind.annotation.ResponseBody; | |||
| import java.util.List; | |||
| @FeignClient(contextId = "remoteModelService", value = ServiceConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) | |||
| public interface RemoteModelService { | |||
| @GetMapping("/model/inner/menu_list") | |||
| @ResponseBody | |||
| public R<List<DmScreenIconDto>> getMenuList(@RequestParam(value = "devId")String devId, @RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); | |||
| } | |||
| @@ -20,7 +20,8 @@ public class SkillConstants { | |||
| REGISTER_VISITOR("3", "访客到访登记"), | |||
| INTRODUCE_STRANGER("24", "熟人介绍生人"), | |||
| BROADCAST_DISPLAY("25", "播报展示"), | |||
| OPEN_DOOR("26", "开门"); | |||
| OPEN_DOOR("26", "开门"), | |||
| DELIVERY("33", "寄快递"); | |||
| private final String code; | |||
| private final String info; | |||
| @@ -56,6 +56,7 @@ public class WebSocketClient extends WebSocketListener { | |||
| public static final Gson json = new Gson(); | |||
| // public static String question = "假设你是一位前台,你需要通过与其他人对话来获取会议相关信息,已知今天是2023-7-19,你需要获取会议日期,开始时间,持续时间,会议地点,会议主题。时间用类似00:00的格式输出。对方的话中可能不包含全部信息,对于未知的信息填充为none。如果所有信息都已知那么commit为true。否则为false。将你获得的信息输出为json格式。对方的话是:“明天下午开个会。从两点开到下午三点,在大会议室开,主题是访客接待”,只输出最后的json。输出只有一行,输出格式为{date:,start_time:,duration:,location:,theme:commit:}。";//可以修改question 内容,来向模型提问 | |||
| public static String question = "请帮我安排五一出行计划";//可以修改question 内容,来向模型提问 | |||
| public static String systemRole = ""; | |||
| public static List<String> questions = new ArrayList<>();//可以修改question 内容,来向模型提问 | |||
| public String answer = ""; | |||
| @@ -121,6 +122,10 @@ public class WebSocketClient extends WebSocketListener { | |||
| } | |||
| public void sendMsg(List<String> messages){ | |||
| if (messages.size() / 2 > 0) { | |||
| systemRole = messages.get(0); | |||
| messages.remove(0); | |||
| } | |||
| questions = messages; | |||
| question = null; | |||
| @@ -195,6 +200,13 @@ public class WebSocketClient extends WebSocketListener { | |||
| chat.addProperty("max_tokens",1024); | |||
| chat.addProperty("auditing","default"); | |||
| parameter.add("chat",chat); | |||
| if (!StringUtils.isEmpty(systemRole)) { | |||
| text = new JsonObject(); | |||
| //填充payload | |||
| text.addProperty("role","system"); | |||
| text.addProperty("content",systemRole); | |||
| ja.add(text); | |||
| } | |||
| if (!StringUtils.isEmpty(question)) { | |||
| text = new JsonObject(); | |||
| //填充payload | |||
| @@ -286,8 +298,9 @@ public class WebSocketClient extends WebSocketListener { | |||
| meetingJo.put("content",answer); | |||
| INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + preWebsocketJo.getString("orderId"), "meeting", meetingJo.toString()); | |||
| } | |||
| INSTANCE.redisTemplate.delete("gpt:websocket:1"); | |||
| // 清除systemRole | |||
| systemRole = ""; | |||
| }else { | |||
| // 添加缓存 | |||
| @@ -301,6 +314,8 @@ public class WebSocketClient extends WebSocketListener { | |||
| } | |||
| } else { | |||
| // 添加缓存 | |||
| INSTANCE.stringRedisTemplate.opsForValue().set("group:websocket:content", "-1"); | |||
| System.out.println("返回结果错误:\n" + responseData.getHeader().get("code") + responseData.getHeader().get("message")); | |||
| LOCK.notifyAll(); | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| package com.xueyi.nlt.nlt.controller; | |||
| import co.elastic.clients.elasticsearch.ElasticsearchClient; | |||
| import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery; | |||
| import co.elastic.clients.elasticsearch.core.SearchResponse; | |||
| @@ -42,9 +43,7 @@ import com.xueyi.nlt.nlt.domain.vo.IntentTemplateVo; | |||
| import com.xueyi.nlt.nlt.domain.vo.MarkRecordVo; | |||
| import com.xueyi.nlt.nlt.mapper.DmRegularMapper; | |||
| import com.xueyi.nlt.nlt.service.IDmIntentService; | |||
| import com.xueyi.nlt.nlt.template.FreeChatTemplate; | |||
| import com.xueyi.nlt.nlt.template.GenerativeKnowledgeTemplate; | |||
| import com.xueyi.nlt.nlt.template.MeetingOrderTemplate; | |||
| import com.xueyi.nlt.nlt.template.*; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmSkillDto; | |||
| import com.xueyi.system.api.digitalmans.domain.vo.DmBatchQuestionsVo; | |||
| @@ -125,12 +124,18 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| @Autowired | |||
| private MeetingOrderTemplate meetingOrderTemplate; | |||
| @Autowired | |||
| private DeliveryOrderTemplate deliveryOrderTemplate; | |||
| @Autowired | |||
| private GenerativeKnowledgeTemplate generativeKnowledgeTemplate; | |||
| @Autowired | |||
| private FreeChatTemplate freeChatTemplate; | |||
| @Autowired | |||
| private MovieChatTemplate movieChatTemplate; | |||
| @Autowired | |||
| private RemoteQuestionanswersService questionanswersService; | |||
| @@ -163,9 +168,8 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| @PostMapping("/api/conversation") | |||
| @ResponseBody | |||
| public AjaxResult conversationApi(@RequestBody DmIntentVo intent) { | |||
| TerminalSecurityContextHolder.setOperatorId(String.valueOf(intent.getOperator())); | |||
| log.info("对话详情:{}", intent.toString()); | |||
| log.info("交互对象:{}", intent.toString()); | |||
| TerminalSecurityContextHolder.setOperatorId(String.valueOf(intent.getOperator())); | |||
| redisTemplate.opsForValue().increment("dashboard:server", 1); | |||
| // 获取今天日期,并格式化成yyyy-MM-dd | |||
| SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |||
| @@ -221,6 +225,11 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| response.setH5(meetingOrderTemplate.handle(intent.getDevId(),intent.getContent(), enterpriseId)); | |||
| response.setAction("Meeting"); | |||
| return AjaxResult.success(response); | |||
| case "delivery": | |||
| response.setMsg(""); | |||
| response.setSkillCode("33"); | |||
| response.setH5(deliveryOrderTemplate.handle(intent.getDevId(),intent.getContent(), enterpriseId)); | |||
| return AjaxResult.success(response); | |||
| } | |||
| } | |||
| @@ -421,6 +430,12 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| // 开门记录 | |||
| redisTemplate.opsForValue().increment("dashboard:open_door", 1); | |||
| pushIntoDashboardRedis(enterpriseName,"开门","skill"); | |||
| }else if (SkillType.DELIVERY.getCode().equals(intent.getSkillCode()) ) { | |||
| if (!redisTemplate2.hasKey("group:device" + ":" + intent.getDevId() + ":" + "session")) { | |||
| // 获取名称为"meeting-order"的BaseTemplate的实例 | |||
| redisTemplate.opsForValue().increment("dashboard:delivery", 1); | |||
| pushIntoDashboardRedis(enterpriseName, "寄快递", "skill"); | |||
| } | |||
| } | |||
| // 判断是否有权限 | |||
| R<List<DmSkillDto>> skilllistInner = remoteskillService.skilllistInner(intent.getDevId(),"1",Long.parseLong(enterpriseId), source.getMaster(), SecurityConstants.INNER); | |||
| @@ -443,6 +458,10 @@ 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 "33": | |||
| // 做快递预约处理 | |||
| response.setH5(deliveryOrderTemplate.handle(intent.getDevId(), intent.getContent(), Long.parseLong(SecurityContextHolder.getLocalMap().get("enterprise_id").toString()))); | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -509,10 +528,10 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| // 从列表中获取知识库任务 | |||
| TaskKnowledgeVo vo = (TaskKnowledgeVo) redisTemplate2.opsForList().leftPop("group:task"); | |||
| log.info("从缓存中获取对象:{}",vo.toString()); | |||
| if (vo == null) { | |||
| return R.ok(null,"没有任务"); | |||
| } | |||
| log.info("从缓存中获取对象:{}",vo.toString()); | |||
| if (vo.getSplit() != SYS_DICT_DATA_SPLITED) { | |||
| // 请开始你的表演 | |||
| @@ -0,0 +1,13 @@ | |||
| package com.xueyi.nlt.nlt.domain; | |||
| import lombok.AllArgsConstructor; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| @Data | |||
| @AllArgsConstructor | |||
| @NoArgsConstructor | |||
| public class LlmContent { | |||
| private String role; | |||
| private String content; | |||
| } | |||
| @@ -13,27 +13,40 @@ import java.util.stream.Collectors; | |||
| @NoArgsConstructor | |||
| public class LlmContext implements Serializable { | |||
| List<Context> contextList; | |||
| private List<LlmContent> contentList; | |||
| @Data | |||
| public class Context { | |||
| private String role; | |||
| private String content; | |||
| public LlmContext(String message) { | |||
| contentList = new ArrayList<>(); | |||
| LlmContent ctx = new LlmContent("user",message); | |||
| contentList.add(ctx); | |||
| } | |||
| public LlmContext(String message) { | |||
| contextList = new ArrayList<>(); | |||
| Context ctx = new Context(); | |||
| ctx.setRole("user"); | |||
| ctx.setContent(message); | |||
| contextList.add(ctx); | |||
| // 声明方法parse,将List<String>转换为List<Context>,参数containsSystem缺省值为false | |||
| public static LlmContext parse(List<String> contentList, boolean containsSystem) { | |||
| int cur = 0; | |||
| LlmContext llmContext = new LlmContext(); | |||
| List<LlmContent> llmContents = new ArrayList<>(); | |||
| // 如果参数containsSystem为true,则将contentList中第一个元素的role设置为system | |||
| if (containsSystem) { | |||
| llmContents.add(new LlmContent("system", contentList.get(0))); | |||
| cur ++; | |||
| } | |||
| // 将剩余的元素按照role值为"user"和"assistant"的顺序加入到context中 | |||
| for (int i = containsSystem ? 1 : 0; i < contentList.size(); i++) { | |||
| LlmContent ctx = new LlmContent(); | |||
| ctx.setRole(i + cur % 2 == 0 ? "user" : "assistant"); | |||
| ctx.setContent(contentList.get(i)); | |||
| llmContents.add(ctx); | |||
| } | |||
| return llmContext; | |||
| } | |||
| public JSONArray toJson() { | |||
| //解释一下代码 | |||
| //1. contextList.stream() 生成一个流 | |||
| //2. collect(Collectors.toCollection(JSONArray::new)) 将流转换成JSONArray | |||
| return contextList.stream().collect(Collectors.toCollection(JSONArray::new)); | |||
| return contentList.stream().collect(Collectors.toCollection(JSONArray::new)); | |||
| } | |||
| @@ -9,4 +9,9 @@ public class LlmParam { | |||
| protected Double temperature; | |||
| protected Integer topK; | |||
| public LlmParam() { | |||
| this.maxTokens = 1024; | |||
| this.temperature = 0.75; | |||
| this.topK = 1; | |||
| } | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| package com.xueyi.nlt.nlt.service.impl; | |||
| import com.xueyi.nlt.netty.client.WebSocketClient; | |||
| import com.xueyi.nlt.nlt.domain.LlmContent; | |||
| import com.xueyi.nlt.nlt.domain.LlmContext; | |||
| import com.xueyi.nlt.nlt.domain.LlmParam; | |||
| import com.xueyi.nlt.nlt.domain.LlmResponse; | |||
| @@ -25,7 +26,7 @@ public class SparkServiceImpl implements ISysLlmService { | |||
| @Override | |||
| public LlmResponse chat(LlmContext context, LlmParam param) { | |||
| List<String> contentArr = context.getContextList().stream().map(LlmContext.Context::getContent).collect(Collectors.toList()); | |||
| List<String> contentArr = context.getContentList().stream().map(LlmContent::getContent).collect(Collectors.toList()); | |||
| synchronized (WebSocketClient.LOCK) { | |||
| webSocketClient.sendMsg(contentArr); | |||
| try { | |||
| @@ -0,0 +1,240 @@ | |||
| package com.xueyi.nlt.nlt.template; | |||
| import com.alibaba.cloud.nacos.NacosConfigManager; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.common.core.constant.digitalman.SkillConstants; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.CoversationSessionVo; | |||
| import com.xueyi.nlt.netty.client.WebSocketClient; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| 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.util.concurrent.TimeUnit; | |||
| @Service("delivery-order") | |||
| public class DeliveryOrderTemplate implements BaseTemplate{ | |||
| private static final Logger log = LoggerFactory.getLogger(DeliveryOrderTemplate.class); | |||
| private static JSONObject DELIVERY_PARAM; | |||
| @Autowired | |||
| WebSocketClient webSocketClient; | |||
| @Autowired | |||
| private RedisTemplate<Object,Object> objectRedisTemplate; | |||
| @Autowired | |||
| NacosConfigManager nacosConfigManager; | |||
| @PostConstruct | |||
| private void init(){ | |||
| try{ | |||
| DELIVERY_PARAM = JSONObject.parseObject(nacosConfigManager.getConfigService().getConfig("Delivery", "DEFAULT_GROUP", 5000)); | |||
| } catch (Exception e) { | |||
| log.error("获取快递参数失败", e); | |||
| } | |||
| } | |||
| @Override | |||
| public JSONObject handle(String dev, String content) {return null;} | |||
| @Override | |||
| public JSONObject handle(String devId, String content, Long tenantId) { | |||
| try{ | |||
| CoversationSessionVo session = (CoversationSessionVo) objectRedisTemplate.opsForValue().get("group:device" + ":" + devId + ":" +"session"); | |||
| if (session == null) { | |||
| session = new CoversationSessionVo(); | |||
| session.setCategory("delivery"); | |||
| session.setFormat(new JSONObject()); | |||
| session.getFormat().put("skillCode", SkillConstants.SkillType.DELIVERY.getCode()); | |||
| } | |||
| //匹配物品类别 | |||
| for(JSONObject type:DELIVERY_PARAM.getList("type", JSONObject.class )){ | |||
| if(content.contains(type.getString("key"))){ | |||
| session.getFormat().put("type",type.getInteger("value")); | |||
| break; | |||
| } | |||
| } | |||
| //匹配省市正则 | |||
| if(session.getFormat().containsKey("province")){ | |||
| JSONObject province = DELIVERY_PARAM.getList("province", JSONObject.class).get(session.getFormat().getInteger("province")-1); | |||
| for(String city:province.getList("city", String.class)){ | |||
| if(content.contains(city)){ | |||
| session.getFormat().put("city", city); | |||
| content = content.replace(city, "@@@"); | |||
| break; | |||
| } | |||
| } | |||
| for(JSONObject provinces:DELIVERY_PARAM.getList("province", JSONObject.class)){ | |||
| if(content.contains(provinces.getString("name"))){ | |||
| if(!provinces.getInteger("code").equals(session.getFormat().getInteger("province"))){ | |||
| if(session.getFormat().containsKey("city")){ | |||
| session.getFormat().remove("city"); | |||
| } | |||
| session.getFormat().put("province",provinces.getIntValue("code")); | |||
| content = content.replaceFirst(province.getString("name"), "@@@"); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| }else{ | |||
| for(JSONObject province:DELIVERY_PARAM.getList("province", JSONObject.class)) { | |||
| if (content.contains(province.getString("name"))) { | |||
| session.getFormat().put("province", province.getIntValue("code")); | |||
| content = content.replaceFirst(province.getString("name"), "@@@"); | |||
| for (String city : province.getList("city", String.class)) { | |||
| if (content.contains(city)) { | |||
| session.getFormat().put("city", city); | |||
| content = content.replace(city, "@@@"); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //匹配尺寸正则 | |||
| for(JSONObject size:DELIVERY_PARAM.getList("size", JSONObject.class)){ | |||
| if(content.contains(size.getString("key"))){ | |||
| session.getFormat().put("size", size.getString("value")); | |||
| break; | |||
| } | |||
| } | |||
| //匹配快递厂商正则 | |||
| for(String name:DELIVERY_PARAM.getList("name", String.class)){ | |||
| if(content.contains(name)){ | |||
| session.getFormat().put("name", name); | |||
| break; | |||
| } | |||
| } | |||
| //匹配取消 | |||
| for(String cancel:DELIVERY_PARAM.getList("cancel", String.class)){ | |||
| if(content.contains(cancel)){ | |||
| session.getFormat().put("cancel", 1); | |||
| break; | |||
| } | |||
| } | |||
| objectRedisTemplate.opsForValue().set("group:device" + ":" + devId + ":" +"session", session, 1, TimeUnit.MINUTES); | |||
| session.getFormat().put("skillCode", SkillConstants.SkillType.DELIVERY.getCode()); | |||
| return session.getFormat(); | |||
| }catch (Exception e){ | |||
| log.error(e.getMessage(), e); | |||
| return null; | |||
| } | |||
| } | |||
| public static void main(String[] args) { | |||
| JSONObject temp = JSONObject.parseObject("{\n" + | |||
| " \"type\":[{\"key\":\"酒\",\"value\":1},\n" + | |||
| " {\"key\":\"水果\",\"value\":2},\n" + | |||
| " {\"key\":\"文件\",\"value\":3},\n" + | |||
| " {\"key\":\"数码产品\",\"value\":4},\n" + | |||
| " {\"key\":\"其他\",\"value\":5}],\n" + | |||
| " \"province\":[{\"name\":\"黑龙江\",\"code\":1,\"city\":[\"哈尔滨\",\"齐齐哈尔\",\"鸡西\",\"鹤岗\",\"双鸭山\",\"大庆\",\"伊春\",\"佳木斯\",\"七台河\",\"牡丹江\",\"黑河\",\"绥化\",\"大兴安岭\"]},\n" + | |||
| " {\"name\":\"吉林\",\"code\":2,\"city\":[\"长春\",\"吉林\",\"四平\",\"辽源\",\"通化\",\"白山\",\"松原\",\"白城\",\"延边\"]},\n" + | |||
| " {\"name\":\"辽宁\",\"code\":3,\"city\":[\"沈阳\",\"大连\",\"鞍山\",\"抚顺\",\"本溪\",\"丹东\",\"锦州\",\"营口\",\"阜新\",\"辽阳\",\"盘锦\",\"铁岭\",\"朝阳\",\"葫芦岛\"]},\n" + | |||
| " {\"name\":\"河北\",\"code\":4,\"city\":[\"石家庄\",\"唐山\",\"秦皇岛\",\"邯郸\",\"邢台\",\"保定\",\"张家口\",\"承德\",\"沧州\",\"廊坊\",\"衡水\"]},\n" + | |||
| " {\"name\":\"甘肃\",\"code\":5,\"city\":[\"兰州\",\"嘉峪关\",\"金昌\",\"白银\",\"天水\",\"武威\",\"张掖\",\"平凉\",\"酒泉\",\"庆阳\",\"定西\",\"陇南\",\"临夏\",\"甘南\"]},\n" + | |||
| " {\"name\":\"青海\",\"code\":6,\"city\":[\"西宁\",\"海东\",\"海北\",\"黄南\",\"海南\",\"果洛\",\"玉树\",\"海西\"]},\n" + | |||
| " {\"name\":\"陕西\",\"code\":7,\"city\":[\"西安\",\"铜川\",\"宝鸡\",\"咸阳\",\"渭南\",\"延安\",\"汉中\",\"榆林\",\"安康\",\"商洛\"]},\n" + | |||
| " {\"name\":\"河南\",\"code\":8,\"city\":[\"郑州\",\"开封\",\"洛阳\",\"平顶山\",\"安阳\",\"鹤壁\",\"新乡\"]}\n" + | |||
| " ],\n" + | |||
| " \"size\":[{\"key\":\"小\",\"value\":\"S\"},\n" + | |||
| " {\"key\":\"中\",\"value\":\"M\"},\n" + | |||
| " {\"key\":\"大\",\"value\":\"L\"}],\n" + | |||
| " \"name\":[\"顺丰\",\"邮政\"],\n" + | |||
| " \"cancel\":[\"取消\"]\n" + | |||
| "}"); | |||
| String content = "我想寄一个寄到青海海南的大的顺丰快递,寄的是酒。取消"; | |||
| try{ | |||
| CoversationSessionVo session = null; | |||
| if (session == null) { | |||
| session = new CoversationSessionVo(); | |||
| session.setCategory("delivery"); | |||
| session.setFormat(new JSONObject()); | |||
| session.getFormat().put("skillCode", SkillConstants.SkillType.DELIVERY.getCode()); | |||
| } | |||
| //匹配物品类别 | |||
| for(JSONObject type:temp.getList("type", JSONObject.class )){ | |||
| if(content.contains(type.getString("key"))){ | |||
| session.getFormat().put("type", type.getInteger("value")); | |||
| break; | |||
| } | |||
| } | |||
| //匹配省市正则 | |||
| if(session.getFormat().containsKey("province")){ | |||
| JSONObject province = temp.getList("province", JSONObject.class).get(session.getFormat().getInteger("province")-1); | |||
| for(String city:province.getList("city", String.class)){ | |||
| if(content.contains(city)){ | |||
| session.getFormat().put("city", city); | |||
| content = content.replace(city, "@@@"); | |||
| break; | |||
| } | |||
| } | |||
| for(JSONObject provinces:temp.getList("province", JSONObject.class)){ | |||
| if(!provinces.getInteger("code").equals(session.getFormat().getInteger("province"))){ | |||
| if(session.getFormat().containsKey("city")){ | |||
| session.getFormat().remove("city"); | |||
| } | |||
| session.getFormat().put("province",province.getIntValue("code")); | |||
| content = content.replaceFirst(province.getString("name"), "@@@"); | |||
| break; | |||
| } | |||
| } | |||
| }else{ | |||
| for(JSONObject province:temp.getList("province", JSONObject.class)) { | |||
| if (content.contains(province.getString("name"))) { | |||
| session.getFormat().put("province", province.getIntValue("code")); | |||
| content = content.replaceFirst(province.getString("name"), "@@@"); | |||
| for (String city : province.getList("city", String.class)) { | |||
| if (content.contains(city)) { | |||
| session.getFormat().put("city", city); | |||
| content = content.replace(city, "@@@"); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //匹配尺寸正则 | |||
| for(String size:temp.getList("size", String.class)){ | |||
| if(content.contains(size)){ | |||
| session.getFormat().put("size", size); | |||
| break; | |||
| } | |||
| } | |||
| //匹配快递厂商正则 | |||
| for(String name:temp.getList("name", String.class)){ | |||
| if(content.contains(name)){ | |||
| session.getFormat().put("name", name); | |||
| break; | |||
| } | |||
| } | |||
| //匹配取消 | |||
| for(String cancel:temp.getList("cancel", String.class)){ | |||
| if(content.contains(cancel)){ | |||
| session.getFormat().put("cancel", 1); | |||
| break; | |||
| } | |||
| } | |||
| session.getFormat().put("skillCode", SkillConstants.SkillType.DELIVERY.getCode()); | |||
| System.out.println(session.getFormat()); | |||
| }catch (Exception e){ | |||
| log.error(e.getMessage(), e); | |||
| } | |||
| } | |||
| } | |||
| @@ -7,12 +7,17 @@ import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.common.core.context.SecurityContextHolder; | |||
| import com.xueyi.nlt.netty.client.WebSocketClient; | |||
| import com.xueyi.nlt.nlt.context.TerminalSecurityContextHolder; | |||
| import com.xueyi.nlt.nlt.domain.LlmContext; | |||
| import com.xueyi.nlt.nlt.domain.LlmParam; | |||
| import com.xueyi.nlt.nlt.domain.LlmResponse; | |||
| import com.xueyi.nlt.nlt.service.ISysLlmService; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.stereotype.Service; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| @@ -21,7 +26,7 @@ public class FreeChatTemplate implements BaseTemplate{ | |||
| private static final Logger log = LoggerFactory.getLogger(FreeChatTemplate.class); | |||
| @Autowired | |||
| WebSocketClient webSocketClient; | |||
| ISysLlmService sysLlmService; | |||
| @Autowired | |||
| private RedisTemplate<String,String> redisTemplate; | |||
| @@ -38,56 +43,35 @@ public class FreeChatTemplate implements BaseTemplate{ | |||
| redisTemplate.opsForList().leftPop(redisKey,2); | |||
| } | |||
| size = redisTemplate.opsForList().size(redisKey); | |||
| List<String> context = redisTemplate.opsForList().range(redisKey,size-6,size); | |||
| List<String> context = new ArrayList<>(); | |||
| context.add("你是一位公司前台事务的专家。"); | |||
| context.addAll(redisTemplate.opsForList().range(redisKey,size-6,size)); | |||
| context.add(content); | |||
| String result = null; | |||
| webSocketClient.sendMsg(context); | |||
| try { | |||
| WebSocketClient.LOCK.wait(); | |||
| result = (String)redisTemplate.opsForValue().get("group:websocket:content"); | |||
| } catch (InterruptedException e) { | |||
| log.warn(e.getMessage()); | |||
| Thread.currentThread().interrupt(); | |||
| } | |||
| String[] blockedWord = {"科大讯飞", "认知模型", "抱歉","认知智能模型"}; | |||
| for(String a :blockedWord){ | |||
| if(result != null && result.contains(a)){ | |||
| result = ""; | |||
| break; | |||
| } | |||
| } | |||
| //webSocketClient.sendMsg(context); | |||
| String resultFinal = ""; | |||
| //精简结果并赋予身份 | |||
| if(!StringUtils.isEmpty(result)){ | |||
| String promptBefore ="你需要完成的目标任务是:对我说的话进行总结。我的需求是:1、回答简短得体自然。50字以内。按照以上要求,我的输入是:"; | |||
| String promptAfter = ""; | |||
| webSocketClient.sendMsg(promptBefore + result + promptAfter); | |||
| try { | |||
| WebSocketClient.LOCK.wait(); | |||
| resultFinal = (String)redisTemplate.opsForValue().get("group:websocket:content"); | |||
| } catch (InterruptedException e) { | |||
| log.warn(e.getMessage()); | |||
| Thread.currentThread().interrupt(); | |||
| } | |||
| } | |||
| LlmContext llmContext = LlmContext.parse(context,true); | |||
| LlmParam param = new LlmParam(); | |||
| LlmResponse response = sysLlmService.chat(llmContext,param); | |||
| String result = response.getContent(); | |||
| blockedWord = new String[]{"科大讯飞", "认知模型", "抱歉", "认知智能模型","你的话","上下文","您的输入","你的输入","您提到的"}; | |||
| for(String a :blockedWord){ | |||
| if(resultFinal != null && resultFinal.contains(a)){ | |||
| resultFinal = ""; | |||
| break; | |||
| } | |||
| // 处理数据 | |||
| if (result.contains("我是科大讯飞")) { | |||
| result = result.replaceAll("科大讯飞", "缔智元"); | |||
| } | |||
| result = result.replaceAll("认知模型", "数字员工"); | |||
| result = result.replaceAll("认知智能模型", "数字员工"); | |||
| if (result.equals("-1")) { | |||
| result = "这个问题超出了我无法回答,您可以提出更多关于公司相关问题。"; | |||
| } | |||
| if(!StringUtils.isEmpty(resultFinal)){ | |||
| if(!StringUtils.isEmpty(result)){ | |||
| redisTemplate.opsForList().rightPush(redisKey,content); | |||
| redisTemplate.opsForList().rightPush(redisKey,resultFinal); | |||
| redisTemplate.opsForList().rightPush(redisKey,result); | |||
| } | |||
| JSONObject resultJson = new JSONObject(); | |||
| resultJson.put("msg",resultFinal); | |||
| resultJson.put("msg",result); | |||
| return resultJson; | |||
| } | |||
| } | |||
| @@ -0,0 +1,75 @@ | |||
| package com.xueyi.nlt.nlt.template; | |||
| import com.alibaba.druid.util.StringUtils; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.common.core.context.SecurityContextHolder; | |||
| import com.xueyi.nlt.netty.client.WebSocketClient; | |||
| import com.xueyi.nlt.nlt.context.TerminalSecurityContextHolder; | |||
| import com.xueyi.nlt.nlt.domain.LlmContext; | |||
| import com.xueyi.nlt.nlt.domain.LlmParam; | |||
| import com.xueyi.nlt.nlt.domain.LlmResponse; | |||
| import com.xueyi.nlt.nlt.service.ISysLlmService; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.stereotype.Service; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| @Service("movie-chat") | |||
| public class MovieChatTemplate implements BaseTemplate{ | |||
| private static final Logger log = LoggerFactory.getLogger(MovieChatTemplate.class); | |||
| @Autowired | |||
| WebSocketClient webSocketClient; | |||
| @Autowired | |||
| ISysLlmService sysLlmService; | |||
| @Autowired | |||
| private RedisTemplate<String,String> redisTemplate; | |||
| @Override | |||
| public JSONObject handle(String devId, String content) { | |||
| Long operatorId = TerminalSecurityContextHolder.getOperatorId(); | |||
| String redisKey = "group:nlp:" + SecurityContextHolder.getLocalMap().get("enterprise_id") + ":" + operatorId; | |||
| // 根据content内容调用模版并返回结果 | |||
| // 通过redis获取数字人上下文信息 | |||
| Long size = redisTemplate.opsForList().size(redisKey); | |||
| if (size > 8) { | |||
| redisTemplate.opsForList().leftPop(redisKey,2); | |||
| } | |||
| size = redisTemplate.opsForList().size(redisKey); | |||
| List<String> context = new ArrayList<>(); | |||
| context.add("你现在扮演一位电影专家,你的话十分严谨。"); | |||
| context.addAll(redisTemplate.opsForList().range(redisKey,size-6,size)); | |||
| context.add(content); | |||
| LlmContext llmContext = LlmContext.parse(context,true); | |||
| LlmParam param = new LlmParam(); | |||
| LlmResponse response = sysLlmService.chat(llmContext,param); | |||
| String result = response.getContent(); | |||
| String[] blockedWord = {"科大讯飞", "认知模型", "抱歉","认知智能模型"}; | |||
| for(String a :blockedWord){ | |||
| if(result != null && result.contains(a)){ | |||
| result = ""; | |||
| break; | |||
| } | |||
| } | |||
| JSONObject resultJson = new JSONObject(); | |||
| resultJson.put("msg",result); | |||
| return resultJson; | |||
| } | |||
| @Override | |||
| public JSONObject handle(String dev, String content, Long tenantId) { | |||
| return null; | |||
| } | |||
| } | |||
| @@ -1,15 +1,25 @@ | |||
| package com.xueyi.system.digitalmans.controller; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.common.core.web.validate.V_A; | |||
| import com.xueyi.common.core.web.validate.V_E; | |||
| import com.xueyi.common.log.annotation.Log; | |||
| import com.xueyi.common.log.enums.BusinessType; | |||
| import com.xueyi.common.security.annotation.InnerAuth; | |||
| import com.xueyi.common.security.annotation.RequiresPermissions; | |||
| import com.xueyi.common.web.entity.controller.BaseController; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.api.digitalmans.domain.query.DmH5MenuQuery; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmModelUploadDto; | |||
| import com.xueyi.system.digitalmans.domain.query.DmDigitalmanQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmModelQuery; | |||
| import com.xueyi.system.digitalmans.service.IDmDigitalmanService; | |||
| import com.xueyi.system.digitalmans.service.IDmManDeviceService; | |||
| import com.xueyi.system.digitalmans.service.IDmModelService; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.validation.annotation.Validated; | |||
| @@ -30,11 +40,38 @@ public class DmModelController extends BaseController<DmModelQuery, DmModelDto, | |||
| @Autowired | |||
| IDmModelService modelService; | |||
| /** 定义节点名称 */ | |||
| @Autowired | |||
| IDmManDeviceService dmManDeviceService; | |||
| @Autowired | |||
| IDmDigitalmanService dmDigitalmanService; | |||
| @Override | |||
| protected String getNodeName() { | |||
| return "模型" ; | |||
| } | |||
| /** | |||
| * 查询模型列表 | |||
| */ | |||
| @InnerAuth | |||
| @GetMapping("/inner/menu_list") | |||
| public R<List<DmScreenIconDto>> getMenuList(@RequestParam(value = "devId")String devId) { | |||
| DmManDeviceDto manDeviceDto = dmManDeviceService.manDeviceInfoInner(devId); | |||
| if (manDeviceDto == null) { | |||
| return R.fail("设备不存在"); | |||
| } | |||
| DmDigitalmanQuery digitalmanQuery = new DmDigitalmanQuery(); | |||
| digitalmanQuery.setManCode(manDeviceDto.getManCode()); | |||
| List<DmDigitalmanDto> digitalmanDtos = dmDigitalmanService.selectList(digitalmanQuery); | |||
| if (digitalmanDtos == null || digitalmanDtos.size() == 0) { | |||
| return R.fail("设备不存在"); | |||
| } | |||
| DmH5MenuQuery query = new DmH5MenuQuery(); | |||
| // 获取H5列表 | |||
| return R.ok(super.baseService.selectH5MenuList(digitalmanDtos.get(0).getId())); | |||
| } | |||
| /** | |||
| * 查询模型列表 | |||
| */ | |||
| @@ -98,6 +135,13 @@ public class DmModelController extends BaseController<DmModelQuery, DmModelDto, | |||
| return super.batchRemove(idList); | |||
| } | |||
| @GetMapping("get_custom_menu") | |||
| public AjaxResult getCustomMenu() { | |||
| return AjaxResult.success(baseService.selectCustomH5MenuList()); | |||
| } | |||
| /** | |||
| * 获取模型选择框列表 | |||
| */ | |||
| @@ -0,0 +1,37 @@ | |||
| package com.xueyi.system.digitalmans.controller.api; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.api.digitalmans.feign.RemoteModelService; | |||
| import com.xueyi.system.resource.controller.api.BaseApiController; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.List; | |||
| @RestController | |||
| @RequestMapping("/api/menu/") | |||
| public class DmMenuApiController extends BaseApiController { | |||
| private static final Logger log = LoggerFactory.getLogger(DmMenuApiController.class); | |||
| @Autowired | |||
| RemoteModelService remoteModelService; | |||
| @GetMapping(value = "list/{devId}") | |||
| @ResponseBody | |||
| public AjaxResult list(@PathVariable(value = "devId") String devId) { | |||
| DeviceTenantSourceMergeVo vo = super.getDeviceTenantSourceMergeVo(devId); | |||
| R<List<DmScreenIconDto>> listR = remoteModelService.getMenuList(devId, vo.getTenantId(), vo.getSourceSlave(), SecurityConstants.INNER); | |||
| if (listR.isOk()) { | |||
| return AjaxResult.success(listR.getData()); | |||
| } | |||
| log.error("获取菜单列表失败{}", listR.getMsg()); | |||
| return AjaxResult.error("获取菜单列表失败"); | |||
| } | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| package com.xueyi.system.digitalmans.domain.dto; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.system.digitalmans.domain.merge.DmBroadcastResourceMerge; | |||
| import com.xueyi.system.digitalmans.domain.po.DmBroadcastPo; | |||
| import com.xueyi.system.digitalmans.domain.po.DmManIconPo; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| import java.util.List; | |||
| /** | |||
| * 播报 数据传输对象 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmManIconDto extends DmManIconPo { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| } | |||
| @@ -0,0 +1,38 @@ | |||
| package com.xueyi.system.digitalmans.domain.po; | |||
| import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.xueyi.common.core.annotation.Excel; | |||
| import com.xueyi.common.core.web.tenant.base.TBaseEntity; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| import static com.xueyi.common.core.constant.basic.EntityConstants.REMARK; | |||
| import static com.xueyi.common.core.constant.basic.EntityConstants.SORT; | |||
| /** | |||
| * 播报 持久化对象 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| @TableName(value = "dm_man_icon_merge", excludeProperty = { SORT, REMARK }) | |||
| public class DmManIconPo extends TBaseEntity { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| /** 使用状态 */ | |||
| @Excel(name = "数字人Id") | |||
| protected Long manId; | |||
| /** 资源类型 */ | |||
| @Excel(name = "按钮Id") | |||
| protected Long iconId; | |||
| protected Long pos; | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.xueyi.system.digitalmans.domain.query; | |||
| import com.xueyi.system.digitalmans.domain.po.DmBroadcastPo; | |||
| import com.xueyi.system.digitalmans.domain.po.DmManIconPo; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| /** | |||
| * 播报 数据查询对象 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmManIconQuery extends DmManIconPo { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| } | |||
| @@ -1,10 +1,14 @@ | |||
| package com.xueyi.system.digitalmans.manager; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmModelUploadDto; | |||
| import com.xueyi.system.digitalmans.domain.query.DmModelQuery; | |||
| import com.xueyi.common.web.entity.manager.IBaseManager; | |||
| import java.util.List; | |||
| /** | |||
| * 模型管理 数据封装层 | |||
| * | |||
| @@ -13,4 +17,8 @@ import com.xueyi.common.web.entity.manager.IBaseManager; | |||
| public interface IDmModelManager extends IBaseManager<DmModelQuery, DmModelDto> { | |||
| int uploadResourceByResourceId(DmModelUploadDto dto); | |||
| List<DmH5MenuDto> selectCustomH5MenuList(); | |||
| List<DmScreenIconDto> selectH5MenuList(Long id); | |||
| } | |||
| @@ -3,25 +3,21 @@ package com.xueyi.system.digitalmans.manager.impl; | |||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
| import com.xueyi.common.core.constant.basic.OperateConstants; | |||
| import com.xueyi.common.web.entity.domain.SlaveRelation; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmModelIconPo; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmScreenIconPo; | |||
| import com.xueyi.system.api.digitalmans.domain.po.*; | |||
| import com.xueyi.system.digitalmans.controller.DmQAndAController; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmModelUploadDto; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanPo; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmModelPo; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto; | |||
| import com.xueyi.system.api.digitalmans.domain.merge.DmModelIconMerge; | |||
| import com.xueyi.system.digitalmans.domain.model.DmScreenIconConverter; | |||
| import com.xueyi.system.digitalmans.domain.po.DmManIconPo; | |||
| import com.xueyi.system.digitalmans.domain.query.DmModelQuery; | |||
| import com.xueyi.system.digitalmans.domain.model.DmModelConverter; | |||
| import com.xueyi.system.digitalmans.mapper.DmDigitalmanMapper; | |||
| import com.xueyi.system.digitalmans.mapper.DmModelIconMapper; | |||
| import com.xueyi.system.digitalmans.mapper.DmModelMapper; | |||
| import com.xueyi.system.digitalmans.mapper.*; | |||
| import com.xueyi.common.web.entity.manager.impl.BaseManagerImpl; | |||
| import com.xueyi.system.digitalmans.manager.IDmModelManager; | |||
| import com.xueyi.system.api.resource.domain.po.DmResourcesPo; | |||
| import com.xueyi.system.digitalmans.mapper.DmScreenIconMapper; | |||
| import com.xueyi.system.digitalmans.mapper.merge.DmModelIconMergeMapper; | |||
| import com.xueyi.system.resource.domain.po.DmBackgroundPo; | |||
| import com.xueyi.system.resource.domain.po.DmScreenOffPo; | |||
| @@ -37,6 +33,7 @@ import java.io.Serializable; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.List; | |||
| import java.util.stream.Collectors; | |||
| import static com.xueyi.system.api.digitalmans.domain.merge.MergeGroup.Model_DmModelIcon_GROUP; | |||
| @@ -71,6 +68,13 @@ public class DmModelManager extends BaseManagerImpl<DmModelQuery, DmModelDto, Dm | |||
| @Autowired | |||
| DmScreenIconMapper dmScreenIconMapper; | |||
| @Autowired | |||
| DmManIconMapper dmManIconMapper; | |||
| @Autowired | |||
| DmH5MenuMapper h5MenuMapper; | |||
| @Autowired | |||
| DmScreenIconConverter screenIconConverter; | |||
| @@ -128,21 +132,22 @@ public class DmModelManager extends BaseManagerImpl<DmModelQuery, DmModelDto, Dm | |||
| } | |||
| // 获取主界面icon | |||
| List<DmModelIconPo> modelIconList = dmModelIconMapper.selectModelIconListByModelId(modelDto.getId()); | |||
| log.info("主界面icon列表:{}", modelIconList); | |||
| if (modelIconList != null && modelIconList.size() > 0) { | |||
| List<DmScreenIconDto> screenIconDtos = new ArrayList<>(); | |||
| modelIconList.forEach(iconItem-> { | |||
| // 获取icon | |||
| DmScreenIconPo iconPo = dmScreenIconMapper.selectById(iconItem.getIconId()); | |||
| DmScreenIconDto temp = screenIconConverter.mapperDto(iconPo); | |||
| DmResourcesPo resourcesPo = dmResourcesMapper.selectById(iconPo.getResourceId()); | |||
| temp.setPos(iconItem.getPos()); | |||
| temp.setIconUrl(resourcesPo.getUrl()); | |||
| screenIconDtos.add(temp); | |||
| }); | |||
| modelDto.setDmScreenIconDtos(screenIconDtos); | |||
| } | |||
| modelDto.setDmScreenIconDtos(selectH5MenuList(modelDto.getManId())); | |||
| // List<DmModelIconPo> modelIconList = dmModelIconMapper.selectModelIconListByModelId(modelDto.getId()); | |||
| // log.info("主界面icon列表:{}", modelIconList); | |||
| // if (modelIconList != null && modelIconList.size() > 0) { | |||
| // List<DmScreenIconDto> screenIconDtos = new ArrayList<>(); | |||
| // modelIconList.forEach(iconItem-> { | |||
| // // 获取icon | |||
| // DmScreenIconPo iconPo = dmScreenIconMapper.selectById(iconItem.getIconId()); | |||
| // DmScreenIconDto temp = screenIconConverter.mapperDto(iconPo); | |||
| // DmResourcesPo resourcesPo = dmResourcesMapper.selectById(iconPo.getResourceId()); | |||
| // temp.setPos(iconItem.getPos()); | |||
| // temp.setIconUrl(resourcesPo.getUrl()); | |||
| // screenIconDtos.add(temp); | |||
| // }); | |||
| // modelDto.setDmScreenIconDtos(screenIconDtos); | |||
| // } | |||
| return modelDto; | |||
| } | |||
| @@ -192,31 +197,173 @@ public class DmModelManager extends BaseManagerImpl<DmModelQuery, DmModelDto, Dm | |||
| log.info("主界面icon列表:{}",dto.getDmScreenIconDtos()); | |||
| if (dto.getDmScreenIconDtos() != null && dto.getDmScreenIconDtos().size() > 0) { | |||
| // 新增icon | |||
| for (DmScreenIconDto screenIconDto : dto.getDmScreenIconDtos()) { | |||
| DmScreenIconPo screenIconPo = new DmScreenIconPo(); | |||
| if (screenIconDto.getId() != null && screenIconDto.getId().doubleValue() > 0) { | |||
| // 更新模型-主界面icon关系 | |||
| screenIconPo = dmScreenIconMapper.selectById(screenIconDto.getId()); | |||
| screenIconPo.setName(screenIconDto.getName()); | |||
| screenIconPo.setResourceId(screenIconDto.getResourceId()); | |||
| screenIconPo.setBroadcastId(screenIconDto.getBroadcastId()); | |||
| dmScreenIconMapper.updateById(screenIconPo); | |||
| } else { | |||
| screenIconPo = new DmScreenIconPo(); | |||
| screenIconPo.setName(screenIconDto.getName()); | |||
| screenIconPo.setResourceId(screenIconDto.getResourceId()); | |||
| screenIconPo.setBroadcastId(screenIconDto.getBroadcastId()); | |||
| dmScreenIconMapper.insert(screenIconPo); | |||
| } | |||
| // 新增模型-主界面icon关系 | |||
| DmModelIconPo iconPo = new DmModelIconPo(); | |||
| iconPo.setModelId(dto.getId()); | |||
| iconPo.setIconId(screenIconPo.getId()); | |||
| iconPo.setPos(screenIconDto.getPos()); | |||
| dmModelIconMapper.insertMerge(iconPo); | |||
| } | |||
| updateH5MenuList(dto.getManId(), dto.getDmScreenIconDtos()); | |||
| } | |||
| return super.update(dto); | |||
| } | |||
| @Override | |||
| public List<DmH5MenuDto> selectCustomH5MenuList() { | |||
| List <DmH5MenuPo> h5MenuPos = h5MenuMapper.selectList(null); | |||
| List<DmH5MenuDto> result = new ArrayList<>(); | |||
| for (DmH5MenuPo po : h5MenuPos) { | |||
| DmH5MenuDto dto = new DmH5MenuDto(); | |||
| dto.setId(po.getId()); | |||
| dto.setMenuType(po.getMenuType()); | |||
| dto.setTitle(po.getTitle()); | |||
| result.add(dto); | |||
| } | |||
| return result; | |||
| } | |||
| @Override | |||
| public List<DmScreenIconDto> selectH5MenuList(Long manId) { | |||
| // 获取菜单列表 | |||
| List<DmH5MenuPo> menuPos = h5MenuMapper.selectList(null); | |||
| List<DmScreenIconDto> result = new ArrayList<>(); | |||
| // 获取数字人所有位置id | |||
| List<DmScreenIconPo> screenIconPos = dmScreenIconMapper.selectList(Wrappers.<DmScreenIconPo>query().lambda().eq(DmScreenIconPo::getManId, manId)); | |||
| for (DmScreenIconPo po : screenIconPos) { | |||
| DmScreenIconDto dto = new DmScreenIconDto(); | |||
| dto.setId(po.getId()); | |||
| dto.setName(po.getName()); | |||
| dto.setType(po.getType()); | |||
| dto.setBroadcastId(po.getBroadcastId()); | |||
| dto.setPos(po.getPos()); | |||
| dto.setResourceId(po.getResourceId()); | |||
| DmResourcesPo resourcesPo = dmResourcesMapper.selectById(po.getResourceId()); | |||
| if (resourcesPo != null) { | |||
| dto.setIconUrl(resourcesPo.getUrl()); | |||
| } | |||
| dto.setManId(po.getManId()); | |||
| result.add(dto); | |||
| } | |||
| // | |||
| // dmScreenIconMapper.selectList(null); | |||
| // log.info("菜单列表:{}", menuPos); | |||
| // | |||
| // List<DmH5MenuDto> h5MenuDtos = new ArrayList<>(); | |||
| // List<DmH5MenuDto> usedH5MenuDtos = new ArrayList<>(); | |||
| // int level = 0; | |||
| // | |||
| // // 构建菜单树 | |||
| // do { | |||
| // int finalLevel = level; | |||
| // if (h5MenuDtos.size() == 0) { | |||
| // menuPos.stream().filter(item->item.getParentId() == 0L).forEach(item->{ | |||
| // | |||
| // DmH5MenuDto h5MenuDto = new DmH5MenuDto(); | |||
| // h5MenuDto.setId(item.getId()); | |||
| // h5MenuDto.setTitle(item.getTitle()); | |||
| // h5MenuDto.setChildren(new ArrayList<>()); | |||
| // h5MenuDto.setStatus(item.getStatus()); | |||
| // h5MenuDto.setLevel(finalLevel); | |||
| // h5MenuDto.setCreateTime(item.getCreateTime()); | |||
| // h5MenuDto.setUpdateTime(item.getUpdateTime()); | |||
| // h5MenuDto.setCreateBy(item.getCreateBy()); | |||
| // h5MenuDto.setMenuType(item.getMenuType()); | |||
| // h5MenuDtos.add(h5MenuDto); | |||
| // usedH5MenuDtos.add(h5MenuDto); | |||
| // }); | |||
| // | |||
| // } else { | |||
| // // 遍历h5MenuDtos,将子菜单加入到父菜单中 | |||
| // List<DmH5MenuDto> tmpList = new ArrayList<>(); | |||
| // for (DmH5MenuDto h5MenuDto : usedH5MenuDtos) { | |||
| // // 遍历menuPos,将parentId与h5MenuDto的id相同的菜单加入到h5MenuDto的children中 | |||
| // menuPos.stream().filter(item->item.getParentId().equals(h5MenuDto.getId())).forEach(item->{ | |||
| // log.info("add child: {}", item); | |||
| // DmH5MenuDto h5MenuDto1 = new DmH5MenuDto(); | |||
| // h5MenuDto1.setId(item.getId()); | |||
| // h5MenuDto1.setTitle(item.getTitle()); | |||
| // h5MenuDto1.setChildren(new ArrayList<>()); | |||
| // h5MenuDto1.setStatus(item.getStatus()); | |||
| // h5MenuDto1.setLevel(finalLevel); | |||
| // h5MenuDto1.setCreateTime(item.getCreateTime()); | |||
| // h5MenuDto1.setUpdateTime(item.getUpdateTime()); | |||
| // h5MenuDto1.setCreateBy(item.getCreateBy()); | |||
| // h5MenuDto1.setMenuType(item.getMenuType()); | |||
| // h5MenuDto.getChildren().add(h5MenuDto1); | |||
| // tmpList.add(h5MenuDto1); | |||
| // }); | |||
| // | |||
| // } | |||
| // usedH5MenuDtos.clear(); | |||
| // usedH5MenuDtos.addAll(tmpList); | |||
| // } | |||
| // level++; | |||
| // Integer tmp = usedH5MenuDtos.size(); | |||
| // | |||
| // for (DmH5MenuDto tmpDto : usedH5MenuDtos) { | |||
| // if (tmpDto.getMenuType().equals("F") && tmpDto.getStatus().equals("0")) { | |||
| // List<DmMenuIconPo> menuIconPos = dmMenuIconMapper.selectMenuIconListByMenuId(tmpDto.getId()); | |||
| // // 获取数字人与Icon关联关系 | |||
| // List<Long> u2 = manIconPos.stream().map(DmManIconPo::getIconId).collect(Collectors.toList()); | |||
| // // 获取菜单与Icon关联关系 | |||
| // List<Long> u1 = menuIconPos.stream().map(DmMenuIconPo::getIconId).collect(Collectors.toList()); | |||
| // // 获取交集 | |||
| // List<Long> iconIdResults = u1.stream().filter(p1->u2.stream().anyMatch(p2->p1.equals(p2))).collect(Collectors.toList()); | |||
| // if (menuIconPos != null && menuIconPos.size() > 0) { | |||
| // if (iconIdResults != null && iconIdResults.size() > 0) { | |||
| // // 获取icon集合 | |||
| // List<DmScreenIconPo> iconPos = dmScreenIconMapper.selectBatchIds(iconIdResults); | |||
| // List<DmScreenIconDto> tmpDtos = screenIconConverter.mapperDto(iconPos); | |||
| // tmpDtos.forEach(item2-> { | |||
| // for (DmMenuIconPo menuIconPo : menuIconPos) { | |||
| // if (item2.getId().equals(menuIconPo.getIconId())) { | |||
| // item2.setPos(menuIconPo.getPos()); | |||
| // // 获取icon 图片地址 | |||
| // DmResourcesPo resourcesPo = dmResourcesMapper.selectById(item2.getResourceId()); | |||
| // if (resourcesPo != null) { | |||
| // item2.setIconUrl(resourcesPo.getUrl()); | |||
| // } | |||
| // } | |||
| // } | |||
| // }); | |||
| // tmpDto.setDmScreenIconDto(tmpDtos); | |||
| // } | |||
| // } | |||
| // } | |||
| // | |||
| // } | |||
| // } while (level < 2); | |||
| return result; | |||
| } | |||
| public Integer updateH5MenuList(Long manId,List<DmScreenIconDto> menuList) { | |||
| log.info("menuList:{}",menuList); | |||
| int resultInt = 0; | |||
| // 获取数据库对应数字人的iconList | |||
| List<DmScreenIconPo> screenIconPos = dmScreenIconMapper.selectList(Wrappers.<DmScreenIconPo>query() | |||
| .lambda().eq(DmScreenIconPo::getManId, manId)); | |||
| // 筛选manIconPos与menuList的差集 | |||
| List<Long> u1 = screenIconPos.stream().map(DmScreenIconPo::getId).collect(Collectors.toList()); | |||
| List<Long> u2 = menuList.stream().map(DmScreenIconDto::getId).collect(Collectors.toList()); | |||
| // 获取差集 | |||
| List<Long> iconIdResults = u1.stream().filter(p1->u2.stream().noneMatch(p2->p1.equals(p2))).collect(Collectors.toList()); | |||
| // 删除差集 | |||
| if (iconIdResults != null && iconIdResults.size() > 0) { | |||
| dmScreenIconMapper.deleteBatchIds(iconIdResults); | |||
| resultInt+=iconIdResults.size(); | |||
| } | |||
| // 检索menuList | |||
| for (DmScreenIconDto dto : menuList) { | |||
| // 判断dto的id是否为空,如果为空,则新增 | |||
| if (dto.getId() == null) { | |||
| dto.setManId(manId); | |||
| dmScreenIconMapper.insert(screenIconConverter.mapperPo(dto)); | |||
| }else { | |||
| // 如果不为空,则更新 | |||
| DmScreenIconPo origin = dmScreenIconMapper.selectById(dto.getId()); | |||
| origin.setName(dto.getName()); | |||
| origin.setResourceId(dto.getResourceId()); | |||
| origin.setBroadcastId(dto.getBroadcastId()); | |||
| origin.setType(dto.getType()); | |||
| dmScreenIconMapper.updateById(screenIconConverter.mapperPo(dto)); | |||
| } | |||
| resultInt++; | |||
| } | |||
| // 获取数字人所有位置id | |||
| return resultInt; | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.xueyi.system.digitalmans.mapper; | |||
| import com.xueyi.common.datasource.annotation.Master; | |||
| import com.xueyi.common.web.entity.mapper.BaseMapper; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmInitSkillDto; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmH5MenuPo; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmInitSkillPo; | |||
| import com.xueyi.system.api.digitalmans.domain.query.DmH5MenuQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmInitSkillQuery; | |||
| /** | |||
| * 访客管理 数据层 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Master | |||
| public interface DmH5MenuMapper extends BaseMapper<DmH5MenuQuery, DmH5MenuDto, DmH5MenuPo> { | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| package com.xueyi.system.digitalmans.mapper; | |||
| import com.xueyi.common.datasource.annotation.Isolate; | |||
| import com.xueyi.common.web.entity.mapper.BaseMapper; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmBroadcastDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmManIconDto; | |||
| import com.xueyi.system.digitalmans.domain.po.DmBroadcastPo; | |||
| import com.xueyi.system.digitalmans.domain.po.DmManIconPo; | |||
| import com.xueyi.system.digitalmans.domain.query.DmBroadcastQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmManIconQuery; | |||
| /** | |||
| * 播报管理 数据层 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Isolate | |||
| public interface DmManIconMapper extends BaseMapper<DmManIconQuery, DmManIconDto, DmManIconPo> { | |||
| } | |||
| @@ -1,10 +1,14 @@ | |||
| package com.xueyi.system.digitalmans.service; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmModelUploadDto; | |||
| import com.xueyi.system.digitalmans.domain.query.DmModelQuery; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto; | |||
| import com.xueyi.common.web.entity.service.IBaseService; | |||
| import java.util.List; | |||
| /** | |||
| * 模型管理 服务层 | |||
| * | |||
| @@ -12,4 +16,8 @@ import com.xueyi.common.web.entity.service.IBaseService; | |||
| */ | |||
| public interface IDmModelService extends IBaseService<DmModelQuery, DmModelDto> { | |||
| int uploadResource(DmModelUploadDto dto); | |||
| List<DmH5MenuDto> selectCustomH5MenuList(); | |||
| List<DmScreenIconDto> selectH5MenuList(Long id); | |||
| } | |||
| @@ -1,6 +1,8 @@ | |||
| package com.xueyi.system.digitalmans.service.impl; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmH5MenuDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmModelDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmScreenIconDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmModelUploadDto; | |||
| import com.xueyi.system.digitalmans.domain.query.DmModelQuery; | |||
| import com.xueyi.system.digitalmans.service.IDmModelService; | |||
| @@ -41,4 +43,14 @@ public class DmModelServiceImpl extends BaseServiceImpl<DmModelQuery, DmModelDto | |||
| public int uploadResource(DmModelUploadDto dto) { | |||
| return modelManager.uploadResourceByResourceId(dto); | |||
| } | |||
| @Override | |||
| public List<DmH5MenuDto> selectCustomH5MenuList() { | |||
| return baseManager.selectCustomH5MenuList(); | |||
| } | |||
| @Override | |||
| public List<DmScreenIconDto> selectH5MenuList(Long id) { | |||
| return baseManager.selectH5MenuList(id); | |||
| } | |||
| } | |||