| @@ -13,4 +13,6 @@ public class DmIntentVo { | |||
| String preIntent; | |||
| String sign; | |||
| String requestId; | |||
| /** 模式类型 1:工作模式 2:接待模式 3:闲聊模式 */ | |||
| String mode; | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| package com.xueyi.nlt.api.nlt.domain.vo; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| @Data | |||
| @NoArgsConstructor | |||
| public class KnowledgeVo { | |||
| private String man_code; | |||
| private String question; | |||
| private Long tenant_id; | |||
| private String trace_id; | |||
| } | |||
| @@ -2,6 +2,7 @@ package com.xueyi.nlt.api.nlt.feign; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.KnowledgeVo; | |||
| import com.xueyi.nlt.api.nlt.feign.factory.RemoteQAFallbackFactory; | |||
| import com.xueyi.system.api.sms.domain.vo.SmsReqEntity; | |||
| import com.xueyi.system.api.sms.feign.factory.RemoteSmsFallbackFactory; | |||
| @@ -23,5 +24,7 @@ public interface RemoteQAService { | |||
| @GetMapping("/knowledge") | |||
| AjaxResult query(@RequestParam(value = "man_code") String manCode, @RequestParam(value = "question") String question, @RequestParam(value = "tenant_id") Long tenantId); | |||
| @PostMapping ("/knowledge") | |||
| AjaxResult query(@RequestBody KnowledgeVo vo); | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| package com.xueyi.nlt.api.nlt.feign.factory; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.KnowledgeVo; | |||
| import com.xueyi.nlt.api.nlt.feign.RemoteQAService; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.cloud.openfeign.FallbackFactory; | |||
| @@ -23,6 +24,11 @@ public class RemoteQAFallbackFactory implements FallbackFactory<RemoteQAService> | |||
| public AjaxResult query(String manCode, String question, Long tenantId) { | |||
| return AjaxResult.error("查询失败"); | |||
| } | |||
| @Override | |||
| public AjaxResult query(KnowledgeVo vo) { | |||
| return AjaxResult.error("查询失败"); | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| package com.xueyi.system.api.resource.feign; | |||
| import com.xueyi.common.core.constant.basic.ServiceConstants; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.system.api.resource.feign.factory.RemoteH5ConfigFallbackFactory; | |||
| import org.springframework.cloud.openfeign.FeignClient; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.ResponseBody; | |||
| @FeignClient(contextId = "remoteH5ConfigService", value = ServiceConstants.SYSTEM_SERVICE, fallbackFactory = RemoteH5ConfigFallbackFactory.class) | |||
| public interface RemoteH5ConfigService { | |||
| @PostMapping("/h5config/inner/syncH5Config") | |||
| R<String> syncH5Config(Long tId); | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.xueyi.system.api.resource.feign.factory; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.system.api.resource.feign.RemoteH5ConfigService; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.springframework.cloud.openfeign.FallbackFactory; | |||
| import org.springframework.stereotype.Component; | |||
| @Slf4j | |||
| @Component | |||
| public class RemoteH5ConfigFallbackFactory implements FallbackFactory<RemoteH5ConfigService> { | |||
| @Override | |||
| public RemoteH5ConfigService create(Throwable cause) { | |||
| return new RemoteH5ConfigService() { | |||
| @Override | |||
| public R<String> syncH5Config(Long tId) { | |||
| return R.fail("同步配置文件失败"); | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| @@ -8,3 +8,4 @@ com.xueyi.system.api.authority.feign.factory.RemoteAuthFallbackFactory | |||
| com.xueyi.system.api.dict.feign.factory.RemoteConfigFallbackFactory | |||
| com.xueyi.system.api.log.feign.factory.RemoteLogFallbackFactory | |||
| com.xueyi.system.api.meeting.feign.factory.RemoteMeetingFallbackFactory | |||
| com.xueyi.system.api.resource.feign.factory.RemoteH5ConfigFallbackFactory | |||
| @@ -16,6 +16,13 @@ public class MessageConstants { | |||
| /** 数字人同步 */ | |||
| public static final Long MODEL_SYNC = 2L; | |||
| public static final Long H5_CONFIG_SYNC = 4L; | |||
| /** 数字人场景 */ | |||
| public static final String MODE_WORK = "1"; // 工作模式 | |||
| public static final String MODE_RECEPTION = "2"; // 接待模式 | |||
| public static final String MODE_FREE_CHAT = "3"; // 闲聊模式 | |||
| /** 缓存数据头 */ | |||
| public static final String REDIS_GROUP_HEADER = "group:dgman:"; | |||
| public static final String REDIS_GROUP_DEVICE_HEADER = "group:dgman:device:"; | |||
| @@ -0,0 +1,6 @@ | |||
| package com.xueyi.common.core.constant.nacos; | |||
| public class NacosConstants { | |||
| public static final String DEFAULT_CONFIG_PATH = "config.json"; | |||
| public static final String DEFAULT_GROUP = "DEFAULT_GROUP"; | |||
| } | |||
| @@ -26,6 +26,7 @@ import com.xueyi.system.api.digitalmans.feign.RemoteReceptionService; | |||
| import com.xueyi.system.api.digitalmans.feign.RemoteSkillService; | |||
| import com.xueyi.system.api.model.Source; | |||
| import com.xueyi.system.api.organize.domain.dto.SysEnterpriseDto; | |||
| import com.xueyi.system.api.resource.feign.RemoteH5ConfigService; | |||
| import com.xueyi.system.api.staff.domain.vo.DmStaffFeature; | |||
| import com.xueyi.system.api.staff.feign.RemoteStaffService; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| @@ -78,6 +79,9 @@ public class ApiController { | |||
| @Autowired | |||
| MessageQueueServiceImpl messageQueueService; | |||
| @Autowired | |||
| RemoteH5ConfigService remoteH5ConfigService; | |||
| @RequestMapping(value = "/heartbeat", method = {RequestMethod.POST}) | |||
| @@ -114,6 +118,10 @@ public class ApiController { | |||
| if (timestamp != null && !timestamp.equalsIgnoreCase(vo.getTimestamp()) && Long.parseLong(timestamp) > Long.parseLong(vo.getTimestamp())) { | |||
| dex_res += 0x100; | |||
| } | |||
| timestamp = redisTemplate.opsForValue().get("group:dgman:" + enterpriseDto.getData().getId() + ":" + MessageConstants.H5_CONFIG_SYNC); | |||
| if (timestamp != null && !timestamp.equalsIgnoreCase(vo.getTimestamp()) && Long.parseLong(timestamp) > Long.parseLong(vo.getTimestamp())) { | |||
| dex_res += 0x10000; | |||
| } | |||
| // if (!timestamp.equalsIgnoreCase(vo.getTimestamp()) && Long.parseLong(timestamp) > Long.parseLong(vo.getTimestamp())) { | |||
| // dex_res += 0x10; | |||
| // } | |||
| @@ -189,6 +197,8 @@ public class ApiController { | |||
| if (receptionVo.isFail()){ | |||
| return AjaxResult.warn("接待模式任务获取失败,请检查"); | |||
| } | |||
| // JSONObject jsObject = new JSONObject(); | |||
| // jsObject.put("code",200); | |||
| // JSONObject data = new JSONObject(); | |||
| @@ -208,6 +218,12 @@ public class ApiController { | |||
| // jsObject.put("data",data); | |||
| // jsObject.put("msg","success"); | |||
| return AjaxResult.success(receptionVo.getData()); | |||
| case 4: | |||
| R<String> propertyR = remoteH5ConfigService.syncH5Config(manDeviceDtoR.getData().getTId()); | |||
| if (propertyR.isFail()) { | |||
| return AjaxResult.warn("配置同步失败,请检查"); | |||
| } | |||
| return AjaxResult.success(propertyR.getData()); | |||
| } | |||
| } | |||
| return AjaxResult.success(); | |||
| @@ -333,4 +349,16 @@ public class ApiController { | |||
| System.out.println(manDeviceDtR.getData().toString()); | |||
| return AjaxResult.success("true"); | |||
| } | |||
| @RequestMapping(value = "/get_config_info/{deviceId}", method = {RequestMethod.GET}) | |||
| @ResponseBody | |||
| public AjaxResult getConfigInfo(@PathVariable(value = "deviceId") String deviceId, HttpServletResponse response) { | |||
| // 根据设备id获取租户信息 | |||
| R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(deviceId); | |||
| R<String> propertyR = remoteH5ConfigService.syncH5Config(manDeviceDtoR.getData().getTId()); | |||
| if (propertyR.isFail()) { | |||
| return AjaxResult.warn("配置同步失败,请检查"); | |||
| } | |||
| return AjaxResult.success(propertyR.getData()); | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject; | |||
| import com.alibaba.nacos.shaded.com.google.gson.Gson; | |||
| import com.alibaba.nacos.shaded.com.google.gson.JsonArray; | |||
| import com.alibaba.nacos.shaded.com.google.gson.JsonObject; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| import com.xueyi.nlt.api.netty.domain.vo.DmWebSocketMessageVo; | |||
| import okhttp3.*; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| @@ -17,10 +18,7 @@ import javax.crypto.spec.SecretKeySpec; | |||
| import java.net.URL; | |||
| import java.nio.charset.Charset; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Base64; | |||
| import java.util.Date; | |||
| import java.util.Locale; | |||
| import java.util.TimeZone; | |||
| import java.util.*; | |||
| @Component | |||
| public class WebSocketClient extends WebSocketListener { | |||
| @@ -44,6 +42,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 List<String> questions = new ArrayList<>();//可以修改question 内容,来向模型提问 | |||
| public String answer = ""; | |||
| @PostConstruct | |||
| @@ -90,6 +89,23 @@ public class WebSocketClient extends WebSocketListener { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public void sendMsg(List<String> messages){ | |||
| questions = messages; | |||
| question = null; | |||
| try { | |||
| //构建鉴权httpurl | |||
| String authUrl = getAuthorizationUrl(hostUrl,APIKEY,APISecret); | |||
| OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); | |||
| String url = authUrl.replace("https://","wss://").replace("http://","ws://"); | |||
| Request request = new Request.Builder().url(url).build(); | |||
| webSocket = okHttpClient.newWebSocket(request,new WebSocketClient()); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| //鉴权url | |||
| public static String getAuthorizationUrl(String hostUrl , String apikey ,String apisecret) throws Exception { | |||
| //获取host | |||
| @@ -148,10 +164,27 @@ public class WebSocketClient extends WebSocketListener { | |||
| chat.addProperty("max_tokens",1024); | |||
| chat.addProperty("auditing","default"); | |||
| parameter.add("chat",chat); | |||
| //填充payload | |||
| text.addProperty("role","user"); | |||
| text.addProperty("content",question); | |||
| ja.add(text); | |||
| if (!StringUtils.isEmpty(question)) { | |||
| text = new JsonObject(); | |||
| //填充payload | |||
| text.addProperty("role","user"); | |||
| text.addProperty("content",question); | |||
| ja.add(text); | |||
| }else { | |||
| for (int i = 0;i < questions.size();i++) { | |||
| text = new JsonObject(); | |||
| if (i % 2 == 0) { | |||
| text.addProperty("role","user"); | |||
| } else { | |||
| text.addProperty("role","assistant"); | |||
| } | |||
| text.addProperty("content",questions.get(i)); | |||
| System.out.println(text.toString()); | |||
| ja.add(text); | |||
| } | |||
| } | |||
| // message.addProperty("text",ja.getAsString()); | |||
| message.add("text",ja); | |||
| payload.add("message",message); | |||
| @@ -6,6 +6,7 @@ import com.alibaba.fastjson2.JSONObject; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| import com.xueyi.common.cache.utils.SourceUtil; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.constant.digitalman.MessageConstants; | |||
| 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; | |||
| @@ -17,18 +18,16 @@ import com.xueyi.common.security.annotation.RequiresPermissions; | |||
| import com.xueyi.common.security.utils.SecurityUtils; | |||
| import com.xueyi.common.web.entity.controller.BaseController; | |||
| import com.xueyi.nlt.api.netty.domain.vo.DmWebSocketMessageVo; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.DmLandingLlmVo; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.DmRecognitionVo; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.*; | |||
| import com.xueyi.nlt.api.nlt.feign.RemoteIntentService; | |||
| import com.xueyi.nlt.api.nlt.feign.RemoteLandingLlmService; | |||
| import com.xueyi.nlt.api.nlt.feign.RemoteQAService; | |||
| import com.xueyi.nlt.netty.client.WebSocketClient; | |||
| import com.xueyi.nlt.nlt.domain.dto.DmIntentDto; | |||
| import com.xueyi.nlt.nlt.domain.query.DmIntentQuery; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.DmIntentVo; | |||
| import com.xueyi.nlt.nlt.domain.vo.IntentTemplateVo; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.TaskKnowledgeVo; | |||
| 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.system.api.digitalmans.domain.dto.DmManDeviceDto; | |||
| @@ -98,6 +97,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| @Autowired | |||
| private GenerativeKnowledgeTemplate generativeKnowledgeTemplate; | |||
| @Autowired | |||
| private FreeChatTemplate freeChatTemplate; | |||
| @Autowired | |||
| private RemoteQuestionanswersService questionanswersService; | |||
| @@ -135,7 +137,12 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| } else { | |||
| voResult.setTarget(0); | |||
| } | |||
| voResult.setFormat(jsonObjectR.getData()); | |||
| if (intent.getMode() != null && intent.getMode().equals(MessageConstants.MODE_FREE_CHAT)) { | |||
| voResult.setMsg(jsonObjectR.getData().get("msg").toString()); | |||
| } | |||
| else { | |||
| voResult.setFormat(jsonObjectR.getData()); | |||
| } | |||
| return AjaxResult.success(voResult); | |||
| } | |||
| @@ -197,7 +204,12 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(intent.getDevId()); | |||
| Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId()); | |||
| return remoteQAService.query(manDeviceDtoR.getData().getManCode(),intent.getContent(),manDeviceDtoR.getData().getTId()); | |||
| KnowledgeVo knowledgeVo = new KnowledgeVo(); | |||
| knowledgeVo.setMan_code(manDeviceDtoR.getData().getManCode()); | |||
| knowledgeVo.setTenant_id(manDeviceDtoR.getData().getTId()); | |||
| knowledgeVo.setQuestion(intent.getContent()); | |||
| // return remoteQAService.query(manDeviceDtoR.getData().getManCode(),intent.getContent(),manDeviceDtoR.getData().getTId()); | |||
| return remoteQAService.query(knowledgeVo); | |||
| } | |||
| @@ -241,6 +253,11 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| @ResponseBody | |||
| public R<JSONObject> conversationInner(@RequestBody DmIntentVo intent) { | |||
| JSONObject joResult = null; | |||
| if (intent.getMode() !=null && intent.getMode().equals(MessageConstants.MODE_FREE_CHAT)) { | |||
| // 闲聊 | |||
| joResult = freeChatTemplate.handle(intent.getDevId(),intent.getContent()); | |||
| return R.ok(joResult); | |||
| } | |||
| if (StringUtils.isEmpty(intent.getSkillCode())) { | |||
| // 调用知识库问答 | |||
| AjaxResult qaAjax = searchQA(intent); | |||
| @@ -0,0 +1,56 @@ | |||
| package com.xueyi.nlt.nlt.template; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.alibaba.fastjson2.JSONException; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| 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 java.util.List; | |||
| @Service("free-chat") | |||
| public class FreeChatTemplate implements BaseTemplate{ | |||
| private static final Logger log = LoggerFactory.getLogger(FreeChatTemplate.class); | |||
| @Autowired | |||
| WebSocketClient webSocketClient; | |||
| @Autowired | |||
| private RedisTemplate<String,String> redisTemplate; | |||
| @Override | |||
| public JSONObject handle(String devId, String content) { | |||
| // 根据content内容调用模版并返回结果 | |||
| synchronized (WebSocketClient.LOCK) { | |||
| // 通过redis获取数字人上下文信息 | |||
| Long size = redisTemplate.opsForList().size("group:device:" + devId); | |||
| if (size > 8) { | |||
| redisTemplate.opsForList().leftPop("group:device:" + devId,2); | |||
| } | |||
| redisTemplate.opsForList().rightPush("group:device:" + devId,content); | |||
| List<String> context = redisTemplate.opsForList().range("group:device:" + devId,0,size); | |||
| String prefix = "你的任务是[针对给定的文段提出" + (content.length() /100 + 1 ) + "个问题并回答]。文段为:[\""; | |||
| String suffix = "\"]。输出为一个JSON数组[{}],每个元素是一个JSON:{“question”:,”answer”:}。不要给出任何解释说明。"; | |||
| log.info(prefix + content + suffix); | |||
| // webSocketClient.sendMsg(prefix + content + suffix); | |||
| webSocketClient.sendMsg(context); | |||
| try { | |||
| WebSocketClient.LOCK.wait(); | |||
| String result = (String)redisTemplate.opsForValue().get("group:websocket:content"); | |||
| redisTemplate.opsForList().rightPush("group:device:" + devId,result); | |||
| JSONObject resultJson = new JSONObject(); | |||
| resultJson.put("msg",result); | |||
| return resultJson; | |||
| } catch (InterruptedException e) { | |||
| log.warn(e.getMessage()); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| @@ -9,6 +9,7 @@ import com.xueyi.system.api.digitalmans.domain.po.DmModelPo; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmSkillPo; | |||
| import com.xueyi.system.api.staff.domain.po.DmStaffPo; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmDigitalmanPo; | |||
| import com.xueyi.system.resource.domain.po.DmH5ConfigPo; | |||
| import org.apache.ibatis.binding.MapperMethod; | |||
| import org.apache.ibatis.executor.Executor; | |||
| import org.apache.ibatis.mapping.MappedStatement; | |||
| @@ -16,6 +17,8 @@ import org.apache.ibatis.plugin.Interceptor; | |||
| import org.apache.ibatis.plugin.Intercepts; | |||
| import org.apache.ibatis.plugin.Invocation; | |||
| import org.apache.ibatis.plugin.Signature; | |||
| import org.apache.ibatis.session.ResultHandler; | |||
| import org.apache.ibatis.session.RowBounds; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| @@ -35,7 +38,11 @@ import java.util.Date; | |||
| MappedStatement.class, | |||
| Object.class | |||
| }) | |||
| }) | |||
| , @Signature(method = "query", type = Executor.class, args = { | |||
| MappedStatement.class, Object.class, | |||
| RowBounds.class, ResultHandler.class | |||
| })} | |||
| ) | |||
| public class EntityInterceptor implements Interceptor { | |||
| private static final Logger LOGGER = LoggerFactory.getLogger(EntityInterceptor.class); | |||
| @Autowired | |||
| @@ -108,7 +115,10 @@ public class EntityInterceptor implements Interceptor { | |||
| if (null!=paramObject && paramObject instanceof DmDigitalmanWorktimePo) { | |||
| redisTemplate.opsForValue().set("group:dgman:" + enterpriseId +":" + MessageConstants.MODEL_SYNC,String.valueOf(currentTime)); | |||
| } | |||
| if (null!=paramObject && paramObject instanceof DmH5ConfigPo) { | |||
| DmH5ConfigPo po = (DmH5ConfigPo)paramObject; | |||
| redisTemplate.opsForValue().set("group:dgman:" + po.getEnterpriseId() +":" + MessageConstants.H5_CONFIG_SYNC,String.valueOf(currentTime)); | |||
| } | |||
| return invocation.proceed(); | |||
| } | |||
| @@ -0,0 +1,143 @@ | |||
| package com.xueyi.system.resource.controller; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| 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.Logical; | |||
| import com.xueyi.common.security.annotation.RequiresPermissions; | |||
| import com.xueyi.common.web.entity.controller.BaseController; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.system.resource.service.IDmH5ConfigService; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.validation.annotation.Validated; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.io.Serializable; | |||
| import java.util.List; | |||
| /** | |||
| * H5配置表管理 业务处理 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/h5config") | |||
| public class DmH5ConfigController extends BaseController<DmH5ConfigQuery, DmH5ConfigDto, IDmH5ConfigService> { | |||
| private static final Logger log = LoggerFactory.getLogger(DmH5ConfigController.class); | |||
| /** 定义节点名称 */ | |||
| @Override | |||
| protected String getNodeName() { | |||
| return "H5配置表" ; | |||
| } | |||
| @PostMapping("/inner/syncH5Config") | |||
| R<String> syncH5Config(Long tId) { | |||
| String result = baseService.syncH5Config(tId); | |||
| if (StringUtils.isNotEmpty(result)) { | |||
| return R.ok(result); | |||
| } | |||
| return R.fail("同步配置文件失败"); | |||
| } | |||
| /** | |||
| * 查询H5配置表列表 | |||
| */ | |||
| @Override | |||
| @GetMapping("/list") | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_LIST) | |||
| public AjaxResult list(DmH5ConfigQuery h5Config) { | |||
| return super.list(h5Config); | |||
| } | |||
| /** | |||
| * 查询H5配置表详细 | |||
| */ | |||
| @Override | |||
| @GetMapping(value = "/{id}") | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_SINGLE) | |||
| public AjaxResult getInfo(@PathVariable Serializable id) { | |||
| return super.getInfo(id); | |||
| } | |||
| /** | |||
| * H5配置表新增 | |||
| */ | |||
| @Override | |||
| @PostMapping | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_ADD) | |||
| @Log(title = "H5配置表管理", businessType = BusinessType.INSERT) | |||
| public AjaxResult add(@Validated({V_A.class}) @RequestBody DmH5ConfigDto h5Config) { | |||
| log.info("H5配置表新增:{}", h5Config); | |||
| log.info("租户:{}", h5Config.getEnterpriseId()); | |||
| return super.add(h5Config); | |||
| } | |||
| /** | |||
| * H5配置表修改 | |||
| */ | |||
| @Override | |||
| @PutMapping | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_EDIT) | |||
| @Log(title = "H5配置表管理", businessType = BusinessType.UPDATE) | |||
| public AjaxResult edit(@Validated({V_E.class}) @RequestBody DmH5ConfigDto h5Config) { | |||
| try { | |||
| JSONObject jsonObject = JSONObject.parseObject(h5Config.getProperty()); | |||
| } catch (Exception e) { | |||
| return AjaxResult.error("配置格式错误"); | |||
| } | |||
| return super.edit(h5Config); | |||
| } | |||
| /** | |||
| * H5配置表修改状态 | |||
| */ | |||
| @Override | |||
| @PutMapping("/status") | |||
| @RequiresPermissions(value = {Auth.DM_H5_CONFIG_EDIT, Auth.DM_H5_CONFIG_ES}, logical = Logical.OR) | |||
| @Log(title = "H5配置表管理", businessType = BusinessType.UPDATE_STATUS) | |||
| public AjaxResult editStatus(@RequestBody DmH5ConfigDto h5Config) { | |||
| return super.editStatus(h5Config); | |||
| } | |||
| /** | |||
| * H5配置表批量删除 | |||
| */ | |||
| @Override | |||
| @DeleteMapping("/batch/{idList}") | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_DEL) | |||
| @Log(title = "H5配置表管理", businessType = BusinessType.DELETE) | |||
| public AjaxResult batchRemove(@PathVariable List<Long> idList) { | |||
| return super.batchRemove(idList); | |||
| } | |||
| /** | |||
| * 获取H5配置表选择框列表 | |||
| */ | |||
| @Override | |||
| @GetMapping("/option") | |||
| public AjaxResult option() { | |||
| return super.option(); | |||
| } | |||
| interface Auth { | |||
| /** 系统 - H5配置表管理 - 列表 */ | |||
| String DM_H5_CONFIG_LIST = "resource:h5config:list"; | |||
| /** 系统 - H5配置表管理 - 详情 */ | |||
| String DM_H5_CONFIG_SINGLE = "resource:h5config:single"; | |||
| /** 系统 - H5配置表管理 - 新增 */ | |||
| String DM_H5_CONFIG_ADD = "resource:h5config:add"; | |||
| /** 系统 - H5配置表管理 - 修改 */ | |||
| String DM_H5_CONFIG_EDIT = "resource:h5config:edit"; | |||
| /** 系统 - H5配置表管理 - 修改状态 */ | |||
| String DM_H5_CONFIG_ES = "resource:h5config:es"; | |||
| /** 系统 - H5配置表管理 - 删除 */ | |||
| String DM_H5_CONFIG_DEL = "resource:h5config:delete"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| package com.xueyi.system.resource.domain.dto; | |||
| import com.xueyi.system.resource.domain.po.DmH5ConfigPo; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| /** | |||
| * H5配置表 数据传输对象 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmH5ConfigDto extends DmH5ConfigPo { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| /** 所属租户名称 */ | |||
| private String tenantName; | |||
| /** 属性值 */ | |||
| private String property; | |||
| } | |||
| @@ -0,0 +1,17 @@ | |||
| package com.xueyi.system.resource.domain.model; | |||
| import com.xueyi.common.core.web.entity.model.BaseConverter; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.po.DmH5ConfigPo; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import org.mapstruct.Mapper; | |||
| import org.mapstruct.MappingConstants; | |||
| /** | |||
| * H5配置表 对象映射器 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Mapper(componentModel = MappingConstants.ComponentModel.SPRING) | |||
| public interface DmH5ConfigConverter extends BaseConverter<DmH5ConfigQuery, DmH5ConfigDto, DmH5ConfigPo> { | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| package com.xueyi.system.resource.domain.po; | |||
| import com.xueyi.common.core.web.entity.base.BaseEntity; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.common.core.annotation.Excel; | |||
| import com.baomidou.mybatisplus.annotation.TableName; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| /** | |||
| * H5配置表 持久化对象 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| @TableName("dm_h5_config") | |||
| public class DmH5ConfigPo extends BaseEntity { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| /** 所属租户id */ | |||
| @Excel(name = "所属租户id") | |||
| protected Long enterpriseId; | |||
| /** 版本号 */ | |||
| @Excel(name = "版本号") | |||
| protected String version; | |||
| /** 状态(0:使用;1:停用) */ | |||
| @Excel(name = "状态", readConverterExp = "0=:使用;1:停用") | |||
| protected String status; | |||
| /** 备注 */ | |||
| @Excel(name = "备注") | |||
| protected String remark; | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| package com.xueyi.system.resource.domain.query; | |||
| import com.xueyi.system.resource.domain.po.DmH5ConfigPo; | |||
| import lombok.Data; | |||
| import lombok.EqualsAndHashCode; | |||
| import java.io.Serial; | |||
| /** | |||
| * H5配置表 数据查询对象 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Data | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmH5ConfigQuery extends DmH5ConfigPo { | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| } | |||
| @@ -0,0 +1,13 @@ | |||
| package com.xueyi.system.resource.manager; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.common.web.entity.manager.IBaseManager; | |||
| /** | |||
| * H5配置表管理 数据封装层 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| public interface IDmH5ConfigManager extends IBaseManager<DmH5ConfigQuery, DmH5ConfigDto> { | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| package com.xueyi.system.resource.manager.impl; | |||
| import com.alibaba.cloud.nacos.NacosConfigManager; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.xueyi.common.core.constant.nacos.NacosConstants; | |||
| import com.xueyi.system.resource.domain.po.DmH5ConfigPo; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.system.resource.domain.model.DmH5ConfigConverter; | |||
| import com.xueyi.system.resource.mapper.DmH5ConfigMapper; | |||
| import com.xueyi.common.web.entity.manager.impl.BaseManagerImpl; | |||
| import com.xueyi.system.resource.manager.IDmH5ConfigManager; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Component; | |||
| /** | |||
| * H5配置表管理 数据封装层处理 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Component | |||
| public class DmH5ConfigManager extends BaseManagerImpl<DmH5ConfigQuery, DmH5ConfigDto, DmH5ConfigPo, DmH5ConfigMapper, DmH5ConfigConverter> implements IDmH5ConfigManager { | |||
| private static final Logger log = LoggerFactory.getLogger(DmH5ConfigManager.class); | |||
| @Autowired | |||
| NacosConfigManager nacosConfigManager; | |||
| } | |||
| @@ -0,0 +1,16 @@ | |||
| package com.xueyi.system.resource.mapper; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.po.DmH5ConfigPo; | |||
| import com.xueyi.common.web.entity.mapper.BaseMapper; | |||
| import com.xueyi.common.datasource.annotation.Master; | |||
| /** | |||
| * H5配置表管理 数据层 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Master | |||
| public interface DmH5ConfigMapper extends BaseMapper<DmH5ConfigQuery, DmH5ConfigDto, DmH5ConfigPo> { | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.xueyi.system.resource.service; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.common.web.entity.service.IBaseService; | |||
| /** | |||
| * H5配置表管理 服务层 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| public interface IDmH5ConfigService extends IBaseService<DmH5ConfigQuery, DmH5ConfigDto> { | |||
| /** | |||
| * 同步H5配置表 | |||
| * | |||
| * @param tId 租户Id | |||
| * @return 结果 | |||
| */ | |||
| public String syncH5Config(Long tId); | |||
| } | |||
| @@ -0,0 +1,130 @@ | |||
| package com.xueyi.system.resource.service.impl; | |||
| import com.alibaba.cloud.nacos.NacosConfigManager; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.baomidou.dynamic.datasource.annotation.DSTransactional; | |||
| import com.xueyi.common.core.constant.nacos.NacosConstants; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmManDeviceDto; | |||
| import com.xueyi.system.digitalmans.domain.query.DmManDeviceQuery; | |||
| import com.xueyi.system.digitalmans.service.IDmManDeviceService; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.system.resource.manager.impl.DmH5ConfigManager; | |||
| import com.xueyi.system.resource.service.IDmH5ConfigService; | |||
| import com.xueyi.system.resource.manager.IDmH5ConfigManager; | |||
| import com.xueyi.common.web.entity.service.impl.BaseServiceImpl; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import java.io.Serializable; | |||
| import java.util.List; | |||
| /** | |||
| * H5配置表管理 服务层处理 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| @Service | |||
| public class DmH5ConfigServiceImpl extends BaseServiceImpl<DmH5ConfigQuery, DmH5ConfigDto, IDmH5ConfigManager> implements IDmH5ConfigService { | |||
| private static final Logger log = LoggerFactory.getLogger(DmH5ConfigManager.class); | |||
| @Autowired | |||
| NacosConfigManager nacosConfigManager; | |||
| @Autowired | |||
| IDmManDeviceService dmManDeviceService; | |||
| /** | |||
| * 查询H5配置表对象列表 | 数据权限 | |||
| * | |||
| * @param h5Config H5配置表对象 | |||
| * @return H5配置表对象集合 | |||
| */ | |||
| @Override | |||
| //@DataScope(userAlias = "createBy", mapperScope = {"DmH5ConfigMapper"}) | |||
| public List<DmH5ConfigDto> selectListScope(DmH5ConfigQuery h5Config) { | |||
| List<DmH5ConfigDto> list = baseManager.selectList(h5Config); | |||
| list.forEach(item-> { | |||
| DmManDeviceQuery query = new DmManDeviceQuery(); | |||
| query.setTId(item.getEnterpriseId()); | |||
| DmManDeviceDto manDeviceDto = dmManDeviceService.selectList(query).stream().filter(device -> device.getTId().equals(item.getEnterpriseId())).findFirst().get(); | |||
| if (manDeviceDto != null) { | |||
| item.setTenantName(manDeviceDto.getTenantName()); | |||
| } | |||
| }); | |||
| return list; | |||
| } | |||
| @Override | |||
| public int insert(DmH5ConfigDto dto) { | |||
| // 获取基础配置文件 | |||
| try { | |||
| String property = nacosConfigManager.getConfigService().getConfig(NacosConstants.DEFAULT_CONFIG_PATH, NacosConstants.DEFAULT_GROUP, 5000); | |||
| // 设置新增配置文件名 | |||
| String[] strs = NacosConstants.DEFAULT_CONFIG_PATH.split("\\."); | |||
| dto.setName(strs[0] + "_" + dto.getEnterpriseId() + "." + strs[1]); | |||
| // 新增配置文件 | |||
| nacosConfigManager.getConfigService().publishConfig(dto.getName(), NacosConstants.DEFAULT_GROUP,property); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表上传nacos-新增配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| return super.insert(dto); | |||
| } | |||
| @Override | |||
| public int update(DmH5ConfigDto dto) { | |||
| try { | |||
| // 获取文件名 | |||
| nacosConfigManager.getConfigService().publishConfig(dto.getName(), NacosConstants.DEFAULT_GROUP,dto.getProperty()); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表上传nacos-修改配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| return super.update(dto); | |||
| } | |||
| @Override | |||
| public DmH5ConfigDto selectById(Serializable id) { | |||
| DmH5ConfigDto dto = super.selectById(id); | |||
| try { | |||
| dto.setProperty(nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000)); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表nacos-获取配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| return dto; | |||
| } | |||
| @Override | |||
| public String syncH5Config(Long tId) { | |||
| DmH5ConfigQuery query = new DmH5ConfigQuery(); | |||
| query.setEnterpriseId(tId); | |||
| List<DmH5ConfigDto> list = baseManager.selectList(query).stream().filter(item -> item.getEnterpriseId().equals(tId)).collect(java.util.stream.Collectors.toList()); | |||
| if (list != null && list.size() > 0) { | |||
| DmH5ConfigDto dto = list.get(0); | |||
| if (dto != null) { | |||
| try { | |||
| return nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| } catch (NacosException ne) { | |||
| log.error("H5同步-获取配置文件失败:{}", ne.getMessage()); | |||
| try { | |||
| return nacosConfigManager.getConfigService().getConfig(NacosConstants.DEFAULT_CONFIG_PATH, NacosConstants.DEFAULT_GROUP, 5000); | |||
| } catch (NacosException e) { | |||
| log.error("H5同步-获取默认配置文件失败:{}", e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| try { | |||
| return nacosConfigManager.getConfigService().getConfig(NacosConstants.DEFAULT_CONFIG_PATH, NacosConstants.DEFAULT_GROUP, 5000); | |||
| } catch (NacosException e) { | |||
| log.error("H5同步-获取默认配置文件失败:{}", e.getMessage()); | |||
| } | |||
| } | |||
| return ""; | |||
| } | |||
| } | |||