# Conflicts: # xueyi-modules/xueyi-nlt/src/main/java/com/xueyi/nlt/nlt/controller/DmIntentController.javatags/B.2.1.3_20231017_alpha
| @@ -0,0 +1,68 @@ | |||
| package com.xueyi.file.api.domain; | |||
| /** | |||
| * @author yk | |||
| * @description | |||
| * @date 2023-10-07 15:43 | |||
| */ | |||
| import org.springframework.web.multipart.MultipartFile; | |||
| import java.io.ByteArrayInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| public class ByteArrayMultipartFile implements MultipartFile { | |||
| private final byte[] content; | |||
| private final String name; | |||
| private final String originalFilename; | |||
| private final String contentType; | |||
| public ByteArrayMultipartFile(byte[] content) { | |||
| this.content = content; | |||
| this.name = "file"; // 默认字段名 | |||
| this.originalFilename = "file"; // 默认文件名 | |||
| this.contentType = "application/octet-stream"; // 默认内容类型 | |||
| } | |||
| @Override | |||
| public String getName() { | |||
| return name; | |||
| } | |||
| @Override | |||
| public String getOriginalFilename() { | |||
| return originalFilename; | |||
| } | |||
| @Override | |||
| public String getContentType() { | |||
| return contentType; | |||
| } | |||
| @Override | |||
| public boolean isEmpty() { | |||
| return content == null || content.length == 0; | |||
| } | |||
| @Override | |||
| public long getSize() { | |||
| return content.length; | |||
| } | |||
| @Override | |||
| public byte[] getBytes() throws IOException { | |||
| return content; | |||
| } | |||
| @Override | |||
| public InputStream getInputStream() throws IOException { | |||
| return new ByteArrayInputStream(content); | |||
| } | |||
| @Override | |||
| public void transferTo(java.io.File dest) throws IOException, IllegalStateException { | |||
| // 实现此方法根据需要 | |||
| } | |||
| } | |||
| @@ -6,9 +6,11 @@ import com.xueyi.file.api.domain.SysFile; | |||
| import com.xueyi.file.api.feign.factory.RemoteFileFallbackFactory; | |||
| import org.springframework.cloud.openfeign.FeignClient; | |||
| import org.springframework.http.MediaType; | |||
| import org.springframework.scheduling.annotation.Async; | |||
| import org.springframework.web.bind.annotation.DeleteMapping; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestParam; | |||
| import org.springframework.web.bind.annotation.RequestPart; | |||
| import org.springframework.web.multipart.MultipartFile; | |||
| @@ -29,7 +31,14 @@ public interface RemoteFileService { | |||
| * @return 结果 | |||
| */ | |||
| @PostMapping(value = "/inner/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | |||
| R<SysFile> upload(@RequestPart(value = "file") MultipartFile file); | |||
| @Async | |||
| R<SysFile> upload(@RequestPart(value = "file") MultipartFile file, @RequestParam (value = "extension") String extension, @RequestParam (value = "fileUuid") String fileUuid); | |||
| @PostMapping(value = "/inner/uploadNoAsync", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | |||
| R<SysFile> uploadNoAsync(@RequestPart(value = "file") MultipartFile file, @RequestParam (value = "extension") String extension, @RequestParam (value = "fileUuid") String fileUuid); | |||
| @PostMapping(value = "/inner/uploadFace", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | |||
| R<SysFile> uploadFace(@RequestPart(value = "file") MultipartFile file); | |||
| @PostMapping(value = "/inner/upload-temp", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | |||
| R<SysFile> uploadTemp(@RequestPart(value = "file") MultipartFile file); | |||
| @@ -41,7 +50,8 @@ public interface RemoteFileService { | |||
| * @return 结果 | |||
| */ | |||
| @PostMapping(value = "/inner/uploadpdf", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | |||
| R<List<SysFile>> uploadPdf(@RequestPart(value = "file") MultipartFile file); | |||
| @Async | |||
| R<List<SysFile>> uploadPdf(@RequestPart(value = "file") MultipartFile file, @RequestParam (value = "fileUuid") String fileUuid); | |||
| /** | |||
| * 删除文件 | |||
| @@ -24,17 +24,27 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ | |||
| log.error("文件服务调用失败:{}", throwable.getMessage()); | |||
| return new RemoteFileService() { | |||
| @Override | |||
| public R<SysFile> upload(MultipartFile file) { | |||
| public R<SysFile> upload(MultipartFile file, String extension, String uuid) { | |||
| return R.fail("上传文件失败:" + throwable.getMessage()); | |||
| } | |||
| @Override | |||
| public R<SysFile> uploadNoAsync(MultipartFile file, String extension, String fileUuid) { | |||
| return null; | |||
| } | |||
| @Override | |||
| public R<SysFile> uploadFace(MultipartFile file) { | |||
| return R.fail("上传文件失败:" + throwable.getMessage() ); | |||
| } | |||
| @Override | |||
| public R<SysFile> uploadTemp(MultipartFile file) { | |||
| return null; | |||
| } | |||
| @Override | |||
| public R<List<SysFile>> uploadPdf(MultipartFile file) { | |||
| public R<List<SysFile>> uploadPdf(MultipartFile file, String uuid) { | |||
| return R.fail("上传文件失败:" + throwable.getMessage() ); | |||
| } | |||
| @@ -64,4 +64,7 @@ public class DmManDevicePo extends BaseEntity { | |||
| @Excel(name = "apk版本") | |||
| protected String apkVersion; | |||
| /* 推流地址 */ | |||
| @Excel(name = "推流地址") | |||
| protected String streamUrl; | |||
| } | |||
| @@ -54,4 +54,6 @@ public class DmSkillPo extends TBaseEntity { | |||
| protected String auth; | |||
| protected String welcomByMeetingTime; | |||
| } | |||
| @@ -66,4 +66,7 @@ public interface RemoteMeetingService { | |||
| @GetMapping(value = "/meeting/inner-api/enableOrder/{roomId}/{dateStr}/{startTime}") | |||
| JSONObject queryExist(@PathVariable(name = "roomId") Long roomId, @PathVariable(name = "dateStr") String dateStr, @PathVariable(name = "startTime") String startTime, @RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); | |||
| @GetMapping(value = "/meeting/inner-api/enableOrder/{roomId}/{dateStr}/{startTime}/{duration}") | |||
| JSONObject queryExistOrder(@PathVariable(name = "roomId") Long roomId, @PathVariable(name = "dateStr") String dateStr, @PathVariable(name = "startTime") String startTime, @PathVariable(name = "duration") Integer duration, @RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); | |||
| } | |||
| @@ -91,6 +91,11 @@ public class RemoteMeetingFallbackFactory implements FallbackFactory<RemoteMeeti | |||
| public JSONObject queryExist(Long roomId, String dateStr, String startTime, Long enterpriseId, String sourceName, String source) { | |||
| return null; | |||
| } | |||
| @Override | |||
| public JSONObject queryExistOrder(Long roomId, String dateStr, String startTime, Integer duration, Long enterpriseId, String sourceName, String source) { | |||
| return null; | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| @@ -11,4 +11,7 @@ public interface RemoteH5ConfigService { | |||
| @GetMapping("/h5config/inner/syncH5Config") | |||
| R<String> syncH5Config(@RequestParam(value = "tId",required = false) String tId); | |||
| @GetMapping("/h5config/inner/syncH5Config") | |||
| public R<String> syncH5Config(@RequestParam(value = "tId", required = false) String tId, @RequestParam(value = "manCode", required = false) String manCode); | |||
| } | |||
| @@ -16,6 +16,10 @@ public class RemoteH5ConfigFallbackFactory implements FallbackFactory<RemoteH5Co | |||
| public R<String> syncH5Config(String tId) { | |||
| return R.fail("同步配置文件失败"); | |||
| } | |||
| public R<String> syncH5Config(String tId, String manCode) { | |||
| return R.fail("同步配置文件失败"); | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| @@ -40,4 +40,10 @@ public interface RemoteStaffService { | |||
| @PostMapping(value = "/staff/inner-api/new-staff") | |||
| @ResponseBody | |||
| public com.alibaba.fastjson2.JSONObject addStaff(@RequestBody DmStaffCommonDto commonDto,@RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); | |||
| @GetMapping("/staff/api/broadcast-staff-count") | |||
| JSONObject queryStaffCount(@RequestHeader(SecurityConstants.ENTERPRISE_ID) Long enterpriseId, @RequestHeader(SecurityConstants.SOURCE_NAME) String sourceName, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); | |||
| @GetMapping("/staff/api/staff-count") | |||
| JSONObject staffCount(); | |||
| } | |||
| @@ -2,10 +2,18 @@ package com.xueyi.common.core.utils.file; | |||
| import com.xueyi.common.core.utils.core.StrUtil; | |||
| import org.apache.commons.lang3.ArrayUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import java.io.*; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.FileOutputStream; | |||
| import java.io.IOException; | |||
| import java.io.OutputStream; | |||
| import java.io.UnsupportedEncodingException; | |||
| import java.net.URLEncoder; | |||
| import java.nio.charset.StandardCharsets; | |||
| @@ -16,6 +24,7 @@ import java.nio.charset.StandardCharsets; | |||
| */ | |||
| public class FileUtil extends cn.hutool.core.io.FileUtil { | |||
| private static Logger logger = LoggerFactory.getLogger(FileUtil.class); | |||
| /** | |||
| * 字符常量:斜杠 {@code '/'} | |||
| */ | |||
| @@ -210,4 +219,53 @@ public class FileUtil extends cn.hutool.core.io.FileUtil { | |||
| String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); | |||
| return encode.replaceAll("\\+", "%20"); | |||
| } | |||
| public static void mergeFile(File[] files, File destFile) { | |||
| if (files == null || files.length == 0) { | |||
| return; | |||
| } | |||
| if (destFile == null) { | |||
| destFile = new File(""); | |||
| } | |||
| if (destFile.exists()) { | |||
| destFile.delete(); | |||
| } | |||
| //将文件合并 | |||
| try (FileOutputStream fos = new FileOutputStream(destFile)) { | |||
| for (File file : files) { | |||
| logger.info("merge file:{},fileSize:{}", file.getAbsolutePath(),FileUtil.size(file)); | |||
| try (FileInputStream fis = new FileInputStream(file);){ | |||
| byte[] bytes = new byte[1024]; | |||
| int len = 0; | |||
| while ((len = fis.read(bytes)) != -1) { | |||
| fos.write(bytes, 0, len); | |||
| } | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| public static String getFileNameNoExt(String fileName) { | |||
| if (fileName == null) { | |||
| return null; | |||
| } | |||
| int point = fileName.lastIndexOf('.'); | |||
| return fileName.substring(0, point); | |||
| } | |||
| public static String getFileExt(String fileName) { | |||
| if (fileName == null) { | |||
| return null; | |||
| } | |||
| int point = fileName.lastIndexOf('.'); | |||
| return fileName.substring(point + 1); | |||
| } | |||
| } | |||
| @@ -37,10 +37,64 @@ public class RedisUtil { | |||
| } | |||
| public static List<JSONObject> getJsonList(String key) { | |||
| return redisTemplate.opsForList().range(key, 0, -1).stream().map(json-> JSONObject.parseObject(json.toString())).collect(Collectors.toList()); | |||
| List<Serializable> lists = redisTemplate.opsForList().range(key, 0, 10); | |||
| if (lists == null || lists.size() == 0) { | |||
| return null; | |||
| } | |||
| return lists.stream().map(json-> JSONObject.parseObject(json.toString())).collect(Collectors.toList()); | |||
| } | |||
| public static List<Serializable> getList(String key) { | |||
| return redisTemplate.opsForList().range(key, 0, -1); | |||
| } | |||
| public static List<Object> getObjectList(String key) { | |||
| return redisTemplate.opsForHash().values(key); | |||
| } | |||
| public static Long getListCount(String key) { | |||
| return redisTemplate.opsForList().size(key); | |||
| } | |||
| public static Boolean existed(String key){ | |||
| return redisTemplate.hasKey(key); | |||
| } | |||
| public static void setVal(String key, Serializable value) { | |||
| redisTemplate.opsForValue().set(key, value); | |||
| } | |||
| public static void setVal(String key, Serializable value, int seconds) { | |||
| redisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS); | |||
| } | |||
| public static Serializable getVal(String key) { | |||
| return redisTemplate.opsForValue().get(key); | |||
| } | |||
| public static void increment(String key){ | |||
| increment(key, 1L); | |||
| } | |||
| public static void increment(String key, long increment){ | |||
| redisTemplate | |||
| .opsForValue() | |||
| .increment(key, increment); | |||
| } | |||
| public static void decrement(String key){ | |||
| decrement(key, 1L); | |||
| } | |||
| public static void decrement(String key, long decrement){ | |||
| redisTemplate | |||
| .opsForValue() | |||
| .decrement(key, decrement); | |||
| } | |||
| public static Object getHashChildItem(String key, String childKey){ | |||
| return redisTemplate.opsForHash().get(key, childKey); | |||
| } | |||
| } | |||
| @@ -1,12 +1,17 @@ | |||
| package com.xueyi.file.controller; | |||
| import cn.hutool.core.text.CharSequenceUtil; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.utils.core.IdUtil; | |||
| import com.xueyi.common.core.utils.file.FileTypeUtil; | |||
| import com.xueyi.common.core.utils.file.FileUtil; | |||
| import com.xueyi.common.core.utils.file.MimeTypeUtil; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.common.redis.utils.RedisUtil; | |||
| import com.xueyi.file.api.domain.DigitalmanLogFile; | |||
| import com.xueyi.file.api.domain.SysFile; | |||
| import com.xueyi.file.api.feign.RemoteFileManageService; | |||
| @@ -56,9 +61,84 @@ public class SysFileController { | |||
| * 文件上传 | 内部调用 | |||
| */ | |||
| @PostMapping("/inner/upload") | |||
| public R<SysFile> uploadInner(MultipartFile file) { | |||
| public R<SysFile> uploadInner(MultipartFile file, String extension, String fileUuid) { | |||
| try { | |||
| log.info("文件上传开始:名:{}, 类型:{}, uuid:{}" , file.getName(), extension, fileUuid); | |||
| // 上传并返回访问地址 | |||
| String url = sysFileService.uploadExactFile(file, extension); | |||
| SysFile sysFile = new SysFile(); | |||
| sysFile.setUrl(url); | |||
| log.info("文件大小:{}", file.getSize()); | |||
| sysFile.setSize(file.getSize()); | |||
| sysFile.setName(FileUtil.getName(url)); | |||
| sysFile.setNick(sysFile.getName()); | |||
| remoteFileManageService.saveFileLog(sysFile, SecurityConstants.INNER); | |||
| JSONArray ja = new JSONArray(); | |||
| Long size = sysFile.getSize(); | |||
| JSONObject jo = new JSONObject(); | |||
| jo.put("url", url); | |||
| jo.put("size", size); | |||
| ja.add(jo); | |||
| RedisUtil.setVal("saas:upload:result:"+fileUuid, ja.toJSONString()); | |||
| RedisUtil.setVal("saas:upload:filename:"+fileUuid, file.getOriginalFilename()); | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| RedisUtil.setVal("saas:upload:fileType:"+fileUuid, 1); | |||
| } | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.VIDEO_EXTENSION)) { | |||
| RedisUtil.setVal("saas:upload:fileType:"+fileUuid, 2); | |||
| } | |||
| return R.ok(sysFile); | |||
| } catch (Exception e) { | |||
| log.error("上传文件失败", e); | |||
| return R.fail(e.getMessage()); | |||
| } | |||
| } | |||
| @PostMapping("/inner/uploadNoAsync") | |||
| public R<SysFile> uploadNoAsyncInner(MultipartFile file, String extension, String fileUuid) { | |||
| try { | |||
| log.info("文件上传开始:名:{}, 类型:{}, uuid:{}" , file.getName(), extension, fileUuid); | |||
| // 上传并返回访问地址 | |||
| String url = sysFileService.uploadExactFile(file, extension); | |||
| SysFile sysFile = new SysFile(); | |||
| sysFile.setUrl(url); | |||
| log.info("文件大小:{}", file.getSize()); | |||
| sysFile.setSize(file.getSize()); | |||
| sysFile.setName(FileUtil.getName(url)); | |||
| sysFile.setNick(sysFile.getName()); | |||
| remoteFileManageService.saveFileLog(sysFile, SecurityConstants.INNER); | |||
| JSONArray ja = new JSONArray(); | |||
| Long size = sysFile.getSize(); | |||
| JSONObject jo = new JSONObject(); | |||
| jo.put("url", url); | |||
| jo.put("size", size); | |||
| ja.add(jo); | |||
| RedisUtil.setVal("saas:upload:result:"+fileUuid, ja.toJSONString()); | |||
| RedisUtil.setVal("saas:upload:filename:"+fileUuid, file.getOriginalFilename()); | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| RedisUtil.setVal("saas:upload:fileType:"+fileUuid, 1); | |||
| } | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.VIDEO_EXTENSION)) { | |||
| RedisUtil.setVal("saas:upload:fileType:"+fileUuid, 2); | |||
| } | |||
| return R.ok(sysFile); | |||
| } catch (Exception e) { | |||
| log.error("上传文件失败", e); | |||
| return R.fail(e.getMessage()); | |||
| } | |||
| } | |||
| @PostMapping("/inner/uploadFace") | |||
| public R<SysFile> uploadFaceInner(MultipartFile file) { | |||
| try { | |||
| log.info("文件上传开始:{}" , file.getName()); | |||
| log.info("文件大小:{}" , file.getSize()); | |||
| // 上传并返回访问地址 | |||
| String url = sysFileService.uploadFile(file); | |||
| SysFile sysFile = new SysFile(); | |||
| @@ -99,7 +179,7 @@ public class SysFileController { | |||
| * 文件上传 | 内部调用 | |||
| */ | |||
| @PostMapping("/inner/uploadpdf") | |||
| public R<List<SysFile>> uploadPdfInner(MultipartFile file) { | |||
| public R<List<SysFile>> uploadPdfInner(MultipartFile file, String fileUuid) { | |||
| try { | |||
| Long startTs = System.currentTimeMillis(); | |||
| log.info("文件上传开始:{}; start ts:{}", file.getName(), startTs); | |||
| @@ -130,8 +210,22 @@ public class SysFileController { | |||
| log.info("上传第 {} 张图片完成。。。",(num-1)); | |||
| }; | |||
| long endTs = System.currentTimeMillis(); | |||
| log.info("上传图片结束。。。,用时:{} ms", (endTs-pdfTs)); | |||
| log.info("上传图片结束。。。,图片上传用时:{} ms,总用时:{} ms", (endTs-pdfTs), (endTs-startTs)); | |||
| JSONArray ja = new JSONArray(); | |||
| for (SysFile sf : results) { | |||
| String url = sf.getUrl(); | |||
| Long size = sf.getSize(); | |||
| JSONObject jo = new JSONObject(); | |||
| jo.put("url", url); | |||
| jo.put("size", size); | |||
| ja.add(jo); | |||
| } | |||
| RedisUtil.setVal("saas:upload:result:"+fileUuid, ja.toJSONString()); | |||
| RedisUtil.setVal("saas:upload:filename:"+fileUuid, file.getOriginalFilename()); | |||
| RedisUtil.setVal("saas:upload:fileType:"+fileUuid, 1); | |||
| return R.ok(results); | |||
| } catch (Exception e) { | |||
| log.error("上传文件失败", e); | |||
| @@ -176,7 +270,7 @@ public class SysFileController { | |||
| */ | |||
| @PostMapping("/upload") | |||
| public AjaxResult upload(MultipartFile file) { | |||
| R<SysFile> R = uploadInner(file); | |||
| R<SysFile> R = uploadInner(file, FileTypeUtil.getExtension(file), IdUtil.randomUUID()); | |||
| return R.isOk() | |||
| ? AjaxResult.success("上传成功!", R.getData().getUrl()) | |||
| : AjaxResult.error("上传失败!"); | |||
| @@ -186,7 +280,7 @@ public class SysFileController { | |||
| */ | |||
| @PostMapping("/uploadpdf") | |||
| public AjaxResult uploadPdf(MultipartFile file) { | |||
| R<List<SysFile>> R = uploadPdfInner(file); | |||
| R<List<SysFile>> R = uploadPdfInner(file, IdUtil.randomUUID()); | |||
| return R.isOk() | |||
| ? AjaxResult.success("上传成功!", R.getData()) | |||
| : AjaxResult.error("上传失败!"); | |||
| @@ -41,6 +41,11 @@ public class FastDfsSysFileServiceImpl implements ISysFileService { | |||
| return domain + "/" + storePath.getFullPath(); | |||
| } | |||
| @Override | |||
| public String uploadExactFile(MultipartFile file, String extension) throws Exception { | |||
| return null; | |||
| } | |||
| @Override | |||
| public String uploadTempFile(MultipartFile file) throws Exception { | |||
| return null; | |||
| @@ -18,6 +18,7 @@ public interface ISysFileService { | |||
| * @return 访问地址 | |||
| */ | |||
| String uploadFile(MultipartFile file) throws Exception; | |||
| String uploadExactFile(MultipartFile file, String extension) throws Exception; | |||
| String uploadTempFile(MultipartFile file) throws Exception; | |||
| String uploadFile(String fileName, File file) throws Exception; | |||
| @@ -40,6 +40,11 @@ public class LocalSysFileServiceImpl implements ISysFileService { | |||
| return domain + localFilePrefix + name; | |||
| } | |||
| @Override | |||
| public String uploadExactFile(MultipartFile file, String extension) throws Exception { | |||
| return null; | |||
| } | |||
| @Override | |||
| public String uploadTempFile(MultipartFile file) throws Exception { | |||
| return null; | |||
| @@ -5,6 +5,8 @@ import com.xueyi.file.utils.FileUploadUtils; | |||
| import io.minio.MinioClient; | |||
| import io.minio.PutObjectArgs; | |||
| import io.minio.RemoveObjectArgs; | |||
| import io.minio.messages.Retention; | |||
| import io.minio.messages.RetentionMode; | |||
| import org.apache.commons.io.FileUtils; | |||
| import org.apache.commons.io.IOUtils; | |||
| import org.slf4j.Logger; | |||
| @@ -19,6 +21,7 @@ import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.InputStream; | |||
| import java.net.URLEncoder; | |||
| import java.time.ZonedDateTime; | |||
| /** | |||
| * Minio 文件存储 | |||
| @@ -63,6 +66,31 @@ public class MinioSysFileServiceImpl implements ISysFileService { | |||
| return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName; | |||
| } | |||
| @Override | |||
| public String uploadExactFile(MultipartFile file, String extension) throws Exception { | |||
| String fileName = FileUploadUtils.extractFilename(file).replaceAll(extension, ""); | |||
| if (fileName.charAt(fileName.length() - 1) == '.') { | |||
| fileName += extension; | |||
| } else { | |||
| fileName += "." + extension; | |||
| } | |||
| //fileName = URLEncoder.encode(fileName, "UTF-8"); | |||
| log.info("Minio filename: {}" , fileName); | |||
| PutObjectArgs args = PutObjectArgs.builder() | |||
| .bucket(minioConfig.getBucketName()) | |||
| .object(fileName) | |||
| .stream(file.getInputStream(), file.getSize(), -1) | |||
| .contentType(file.getContentType()) | |||
| .build(); | |||
| client.putObject(args); | |||
| log.info("Minio 文件上传成功"); | |||
| // 获取fileName的最后一个'/'的位置的字符串,并用URLEncoder进行UTF-8编码后,再拼接到fileName中 | |||
| String splitStr = fileName.substring(fileName.lastIndexOf("/") + 1); | |||
| splitStr = URLEncoder.encode(splitStr, "UTF-8"); | |||
| fileName = fileName.substring(0, fileName.lastIndexOf("/") + 1) + splitStr; | |||
| return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName; | |||
| } | |||
| @Override | |||
| public String uploadTempFile(MultipartFile file) throws Exception { | |||
| return null; | |||
| @@ -131,12 +159,14 @@ public class MinioSysFileServiceImpl implements ISysFileService { | |||
| String fileName = file.getName(); | |||
| // 获取fileName的最后一个'/'的位置的字符串,并用URLEncoder进行UTF-8编码后,再拼接到fileName中 | |||
| // 使用PutObjectArgs上传文件到MinIO | |||
| ZonedDateTime end = ZonedDateTime.now().plusDays(90); // Set the end time to 90 days from now | |||
| client.putObject( | |||
| PutObjectArgs.builder() | |||
| .bucket(minioConfig.getBucketName()) | |||
| .object(fileName) | |||
| .stream(new FileInputStream(file), file.length(), -1) | |||
| .contentType("application/octet-stream") | |||
| .retention(new Retention(RetentionMode.COMPLIANCE, end)) | |||
| .build() | |||
| ); | |||
| @@ -94,6 +94,9 @@ public class PdfToImageUtil { | |||
| */ | |||
| private static File generateFile(MultipartFile pdfFile) throws Exception { | |||
| String fileName = pdfFile.getOriginalFilename(); | |||
| if (fileName == null || fileName.isEmpty()) { | |||
| return null; | |||
| } | |||
| String directoryName = fileName.substring(0, fileName.lastIndexOf(".")); | |||
| File zipFile = new File(directoryName + "." + ZIP_SUFFIX); | |||
| @@ -1,6 +1,7 @@ | |||
| package com.xueyi.message.transfer.controller; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.common.cache.utils.SourceUtil; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| @@ -8,6 +9,8 @@ import com.xueyi.common.core.constant.digitalman.InitConstants; | |||
| 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.redis.utils.RedisUtil; | |||
| import com.xueyi.common.web.utils.DateUtils; | |||
| import com.xueyi.message.api.transfer.domain.vo.DmActiveVo; | |||
| import com.xueyi.message.api.transfer.domain.vo.DmDeviceVo; | |||
| import com.xueyi.message.transfer.service.impl.MessageQueueServiceImpl; | |||
| @@ -29,6 +32,8 @@ 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.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.data.redis.core.StringRedisTemplate; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| @@ -39,7 +44,9 @@ import org.springframework.web.bind.annotation.RequestParam; | |||
| import org.springframework.web.bind.annotation.ResponseBody; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| @@ -49,6 +56,8 @@ import java.util.stream.Collectors; | |||
| @RequestMapping("api") | |||
| public class ApiController { | |||
| private static final Logger log = LoggerFactory.getLogger(ApiController.class); | |||
| @Autowired | |||
| RemoteStaffService remoteStaffService; | |||
| @@ -83,12 +92,11 @@ public class ApiController { | |||
| RemoteH5ConfigService remoteH5ConfigService; | |||
| @RequestMapping(value = "/heartbeat", method = {RequestMethod.POST}) | |||
| @ResponseBody | |||
| public AjaxResult heartbeat(@RequestBody DmDeviceVo vo, HttpServletResponse response) { | |||
| Long sysTime = System.currentTimeMillis(); | |||
| System.out.println("heartbeat: device: " + vo.getDevId() + " timestamp: " + sysTime); | |||
| log.info("heartbeat: device: {} timestamp: {} ",vo.getDevId(), sysTime); | |||
| Integer dex_res = 0; | |||
| // 根据设备id获取租户信息 | |||
| R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(vo.getDevId()); | |||
| @@ -102,7 +110,7 @@ public class ApiController { | |||
| } | |||
| // 更新心跳 | |||
| redisTemplate.opsForValue().set("group:dgman:" + vo.getDevId() + ":" + MessageConstants.HEART_BEAT_SYNC,String.valueOf(sysTime)); | |||
| redisTemplate.opsForValue().set("group:dgman:" + vo.getDevId() + ":" + MessageConstants.HEART_BEAT_SYNC, String.valueOf(sysTime)); | |||
| String timestamp = redisTemplate.opsForValue().get("group:dgman:" + manDeviceDtoR.getData().getTId() + ":" + MessageConstants.STAFF_SYNC); | |||
| @@ -147,15 +155,14 @@ public class ApiController { | |||
| @RequestMapping(value = "/update", method = {RequestMethod.POST}) | |||
| @ResponseBody | |||
| public AjaxResult update(@RequestBody DmDeviceVo vo, HttpServletResponse response) { | |||
| System.out.println(vo.toString()); | |||
| String timestamp = vo.getTimestamp(); | |||
| // 根据设备id获取租户信息 | |||
| R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(vo.getDevId()); | |||
| if (manDeviceDtoR.isFail() || manDeviceDtoR.getData() == null ) { | |||
| if (manDeviceDtoR.isFail() || manDeviceDtoR.getData() == null) { | |||
| return AjaxResult.warn("设备号获取失败,请检查"); | |||
| } | |||
| Source source = SourceUtil.getSourceCache(manDeviceDtoR.getData().getStrategyId()); | |||
| if (vo.getType() !=null) { | |||
| if (vo.getType() != null) { | |||
| switch (vo.getType()) { | |||
| // 人员信息 | |||
| case 0: | |||
| @@ -176,7 +183,7 @@ public class ApiController { | |||
| }); | |||
| return AjaxResult.success(staffFeatureList.getData()).put("timestamp", timestamp); | |||
| case 1: | |||
| System.out.println("=========租户号:" + manDeviceDtoR.getData().getTId() + ", 数据源: " + source.getMaster() + " 设备号:" + vo.getDevId()); | |||
| log.info("=========租户号:{},数据源:{}, 设备号:{}",manDeviceDtoR.getData().getTId(), source.getMaster(), vo.getDevId()); | |||
| R<List<DmSkillDto>> skillList = remoteSkillService.skilllistInner(vo.getDevId(), vo.getTimestamp(), manDeviceDtoR.getData().getTId(), source.getMaster(), SecurityConstants.INNER); | |||
| if (skillList.isFail()) | |||
| return AjaxResult.warn("新增失败,请检查"); | |||
| @@ -194,7 +201,7 @@ public class ApiController { | |||
| return AjaxResult.success(syncDmDto.getData()).put("timestamp", timestamp); | |||
| case 3: | |||
| R<DmReceptionVo> receptionVo = remoteReceptionService.getReceptionTaskInner(manDeviceDtoR.getData().getManCode(), manDeviceDtoR.getData().getTId(), source.getMaster(), SecurityConstants.INNER); | |||
| if (receptionVo.isFail()){ | |||
| if (receptionVo.isFail()) { | |||
| return AjaxResult.warn("接待模式任务获取失败,请检查"); | |||
| } | |||
| @@ -219,7 +226,7 @@ public class ApiController { | |||
| // jsObject.put("msg","success"); | |||
| return AjaxResult.success(receptionVo.getData()); | |||
| case 4: | |||
| R<String> propertyR = remoteH5ConfigService.syncH5Config(manDeviceDtoR.getData().getTId().toString()); | |||
| R<String> propertyR = remoteH5ConfigService.syncH5Config(manDeviceDtoR.getData().getTId().toString(), manDeviceDtoR.getData().getManCode().toString()); | |||
| if (propertyR.isFail()) { | |||
| return AjaxResult.warn("配置同步失败,请检查"); | |||
| } | |||
| @@ -238,7 +245,7 @@ public class ApiController { | |||
| } | |||
| // 根据密钥获取账户信息 | |||
| R<DeviceTenantSourceMergeVo> deviceTenantSourceMergeVoR = deviceTenantMergeServicel.selectDeviceSNTenantSourceMerge(vo.getSncode(),vo.getSecret()); | |||
| R<DeviceTenantSourceMergeVo> deviceTenantSourceMergeVoR = deviceTenantMergeServicel.selectDeviceSNTenantSourceMerge(vo.getSncode(), vo.getSecret()); | |||
| if (deviceTenantSourceMergeVoR.isFail()) { | |||
| return AjaxResult.warn(deviceTenantSourceMergeVoR.getMsg()); | |||
| } | |||
| @@ -253,13 +260,13 @@ public class ApiController { | |||
| return AjaxResult.warn("更新设备信息失败,请查询log"); | |||
| } | |||
| // 调用初始化处理(数字人,数字人设备,形象,技能) | |||
| R<Integer> initResult = remoteDigitalmanService.initInner(vo.getSecret(),deviceTenantSourceMergeVoR.getData().getTenantId(),deviceTenantSourceMergeVoR.getData().getSourceSlave(),SecurityConstants.INNER); | |||
| R<Integer> initResult = remoteDigitalmanService.initInner(vo.getSecret(), deviceTenantSourceMergeVoR.getData().getTenantId(), deviceTenantSourceMergeVoR.getData().getSourceSlave(), SecurityConstants.INNER); | |||
| // 根据状态返回结果 | |||
| if (initResult.isFail()) { | |||
| return AjaxResult.warn("绑定数字人失败,请联系后台人员"); | |||
| } | |||
| // 更新心跳状态 | |||
| redisTemplate.opsForValue().set("group:dgman:" + vo.getSncode() + ":" + MessageConstants.HEART_BEAT_SYNC,String.valueOf(System.currentTimeMillis())); | |||
| redisTemplate.opsForValue().set("group:dgman:" + vo.getSncode() + ":" + MessageConstants.HEART_BEAT_SYNC, String.valueOf(System.currentTimeMillis())); | |||
| //redisTemplate.opsForHash().(MessageConstants.REDIS_GROUP_DEVICE_HEADER,devId,dto); | |||
| //redisTemplate. | |||
| return AjaxResult.success(); | |||
| @@ -267,12 +274,10 @@ public class ApiController { | |||
| /** | |||
| * 获取设备在线状态 | |||
| * | |||
| * | |||
| */ | |||
| @RequestMapping(value = "/device_online_status/{devId}", method = {RequestMethod.GET}) | |||
| @ResponseBody | |||
| public AjaxResult getDeviceOnlineStatus(@RequestParam(value = "devId") String devId, HttpServletResponse response){ | |||
| public AjaxResult getDeviceOnlineStatus(@RequestParam(value = "devId") String devId, HttpServletResponse response) { | |||
| // 获取设备心跳状态 | |||
| String timestamp = redisTemplate.opsForValue().get("group:dgman:" + devId + ":" + MessageConstants.HEART_BEAT_SYNC); | |||
| @@ -286,53 +291,121 @@ public class ApiController { | |||
| return AjaxResult.success(InitConstants.DEVICE_ACTIVATE_STATUS_OFFLINE); | |||
| } | |||
| // 设备存在缓存时判断是否超过10min | |||
| return AjaxResult.success(System.currentTimeMillis() - Long.parseLong(timestamp) >10 * 60 * 1000 ? InitConstants.DEVICE_ACTIVATE_STATUS_OFFLINE : InitConstants.DEVICE_ACTIVATE_STATUS_ONLINE); | |||
| return AjaxResult.success(System.currentTimeMillis() - Long.parseLong(timestamp) > 10 * 60 * 1000 ? InitConstants.DEVICE_ACTIVATE_STATUS_OFFLINE : InitConstants.DEVICE_ACTIVATE_STATUS_ONLINE); | |||
| } | |||
| @RequestMapping(value = "/test", method = {RequestMethod.GET} ) | |||
| @ResponseBody | |||
| public R<JSONObject> test(HttpServletRequest request) { | |||
| return mansInfo(); | |||
| } | |||
| public R<JSONObject> mansInfo() { | |||
| Long serviceTimeCount = 0L; | |||
| Integer meetingServiceCount = RedisUtil.getNumberVal("dashboard:meeting"); | |||
| Integer serverTimes = RedisUtil.getNumberVal("dashboard:server"); | |||
| Integer recognition = RedisUtil.getNumberVal("dashboard:recognition"); | |||
| Integer receptionCount = RedisUtil.getNumberVal("dashboard:create_visitor_info"); | |||
| Integer visitorCount = RedisUtil.getNumberVal("dashboard:register_visitor"); | |||
| Integer attendanceCount = RedisUtil.getNumberVal("dashboard:attendance"); | |||
| Integer openDoorCount = RedisUtil.getNumberVal("dashboard:open_door"); | |||
| Integer conversationDuration = RedisUtil.getNumberVal("dashboard:conversation-duration"); | |||
| Integer conversationTimes = RedisUtil.getNumberVal("dashboard:conversation-times"); | |||
| Integer broadcastCount = RedisUtil.getNumberVal("dashboard:broadcast_display"); | |||
| List<JSONObject> knowledgeList = new ArrayList<>(); | |||
| if (RedisUtil.existed("dashboard:knowledge-consume")) { | |||
| knowledgeList = RedisUtil.getJsonList("dashboard:knowledge-consume"); | |||
| //取值后清除缓存list,5秒后过期 | |||
| // RedisUtil.expire("dashboard:knowledge-consume", 5); | |||
| } | |||
| if (RedisUtil.existed("dashboard:service-time-count")) { | |||
| serviceTimeCount = RedisUtil.getNumberVal("dashboard:service-time-count").longValue(); | |||
| //取值后清除缓存list,5秒后过期 | |||
| // RedisUtil.expire("dashboard:knowledge-consume", 5); | |||
| } | |||
| List<JSONObject> skillList = new ArrayList<>(); | |||
| if (RedisUtil.existed("dashboard:skill-consume")) { | |||
| skillList = RedisUtil.getJsonList("dashboard:skill-consume"); | |||
| //取值后清除缓存list,5秒后过期 | |||
| // RedisUtil.expire("dashboard:skill-consume", 5); | |||
| } | |||
| Long onlineCount = 0L; | |||
| if (RedisUtil.existed(MessageConstants.REDIS_GROUP_DEVICE_HEADER)) { | |||
| List<Object> hashVals = RedisUtil.getObjectList(MessageConstants.REDIS_GROUP_DEVICE_HEADER); | |||
| List<DmManDeviceDto> dtos = hashVals.stream().map(item->(DmManDeviceDto)item).collect(Collectors.toList()); | |||
| onlineCount = dtos.stream().filter(item->(!item.getOnlineStatus().isEmpty()) && | |||
| item.getOnlineStatus().equalsIgnoreCase("1")).count(); | |||
| List<DmManDeviceDto> dtos2 = dtos.stream().filter(item->item.getActivateTime() != null).collect(Collectors.toList()); | |||
| for(DmManDeviceDto item:dtos2) { | |||
| serviceTimeCount += (System.currentTimeMillis() - item.getActivateTime().getTime())/3600000; | |||
| } | |||
| log.info("devs:{}, onlineCount:{}",dtos.size(), onlineCount); | |||
| } | |||
| JSONArray jsonArray = new JSONArray(); | |||
| // 最近三十天的数据,服务人次,知识库增量 | |||
| for (int i = 0; i < 30; i++) { | |||
| Date date = DateUtils.addDays(new Date(), -i); | |||
| String dateStr2 = DateUtils.formatDate(date, "yyyy-MM-dd"); | |||
| JSONObject json2 = new JSONObject(); | |||
| json2.put("date", dateStr2); | |||
| json2.put("serviceTimes", RedisUtil.getNumberVal("dashboard:server-chart:"+dateStr2)); | |||
| json2.put("knowledgeNums", RedisUtil.getNumberVal("dashboard:server-chart:"+dateStr2)); | |||
| jsonArray.add(json2); | |||
| } | |||
| JSONObject json = new JSONObject(); | |||
| json.put("manCount",5);//数字人数 | |||
| json.put("manOnlineCount",onlineCount);//数字人数 | |||
| json.put("recognizedPersonCount", recognition);//注册人员总数 | |||
| json.put("serviceTimeCount",serviceTimeCount);//总服务时间 | |||
| json.put("staffTotalCount",remoteStaffService.staffCount().getLongValue("data"));//总服务时间 | |||
| json.put("chatTimes",conversationTimes);//对话次数 | |||
| json.put("chatDurationCount",conversationDuration);//对话时长 | |||
| json.put("servicePerCount",serverTimes);//用户使用频次?改成服务人次 | |||
| json.put("serviceTotal",meetingServiceCount+receptionCount+visitorCount+attendanceCount+openDoorCount+broadcastCount); | |||
| json.put("meetingServiceCount", meetingServiceCount);//会议 | |||
| json.put("receptionCount",receptionCount);//接待 | |||
| json.put("visitorCount",visitorCount);//访客 | |||
| json.put("attendanceCount",attendanceCount);//考勤 | |||
| json.put("openDoorCount",openDoorCount);//门禁 | |||
| json.put("broadcastCount",broadcastCount);//播报 | |||
| json.put("knowledgeConsume",knowledgeList);//实时知识库调用 | |||
| json.put("skillConsume",skillList);//实时技能调用 | |||
| json.put("serverCharts",jsonArray);// | |||
| log.info(json.toJSONString()); | |||
| return R.ok(json); | |||
| } | |||
| /** | |||
| * @Author yangkai | |||
| * @Description //TODO | |||
| * @Date 2023/8/11 | |||
| * @Param | |||
| * @return | |||
| * | |||
| * | |||
| * manCount | |||
| * serviceTimeCount | |||
| * chatTimes | |||
| * chatDurationCount | |||
| * skillExecuteTimes | |||
| * | |||
| * recognizedPersonCount | |||
| * servicePerCount | |||
| * | |||
| * receptionServiceCount | |||
| * meetingServiceCount | |||
| * visitServiceCount | |||
| * largeModelKnowledgeBaseGroupChangeNum | |||
| * largeModelKnowledgeBaseChangeNum | |||
| * @Date 2023/8/11 | |||
| * @Param | |||
| **/ | |||
| @RequestMapping(value = "/broadcast", method = {RequestMethod.GET}) | |||
| @ResponseBody | |||
| public R broadcast(@RequestParam(value = "channel") String channel){ | |||
| public R broadcast(@RequestParam(value = "channel") String channel) { | |||
| try { | |||
| JSONObject json = new JSONObject(); | |||
| /*json.put("chatTimes", 865531); | |||
| json.put("chatDurationCount", 10068); | |||
| // json.put("skillExecuteTimes", 10); | |||
| json.put("recognizedPersonCount", 13899); | |||
| json.put("receptionServiceCount", 1824); | |||
| json.put("meetingServiceCount", 1762); | |||
| json.put("visitServiceCount", 523);*/ | |||
| R<JSONObject> objectR = remoteDigitalmanService.mansInfo(); | |||
| JSONObject jsonObj = objectR.getData(); | |||
| jsonObj.keySet().forEach(key -> json.put(key, jsonObj.get(key))); | |||
| String str = json.toJSONString(); | |||
| messageQueueService.broadcast(channel, str); | |||
| log.info("broadcast----exec"); | |||
| JSONObject json = new JSONObject(); | |||
| R<JSONObject> objectR = mansInfo(); | |||
| log.info("mansInfo:{}", objectR.getData()); | |||
| JSONObject jsonObj = objectR.getData(); | |||
| jsonObj.keySet().forEach(key -> json.put(key, jsonObj.get(key))); | |||
| String str = json.toJSONString(); | |||
| log.info("broadcast:{}", str); | |||
| messageQueueService.broadcast(channel, str); | |||
| return R.ok(str); | |||
| }catch (Exception e){ | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| return R.fail(e.getMessage()); | |||
| } | |||
| @@ -346,7 +419,7 @@ public class ApiController { | |||
| return AjaxResult.success("false"); | |||
| } | |||
| System.out.println(manDeviceDtR.getData().toString()); | |||
| log.info(manDeviceDtR.getData().toString()); | |||
| return AjaxResult.success("true"); | |||
| } | |||
| @@ -356,10 +429,12 @@ public class ApiController { | |||
| // 根据设备id获取租户信息 | |||
| R<DmManDeviceDto> manDeviceDtoR = manDeviceService.manDeviceInfoInner(deviceId); | |||
| String tenantId = null; | |||
| String manCode = null; | |||
| if (manDeviceDtoR.isOk() && manDeviceDtoR.getData() != null) { | |||
| tenantId = manDeviceDtoR.getData().getTId().toString(); | |||
| manCode = manDeviceDtoR.getData().getManCode().toString(); | |||
| } | |||
| R<String> propertyR = remoteH5ConfigService.syncH5Config(tenantId); | |||
| R<String> propertyR = remoteH5ConfigService.syncH5Config(tenantId, manCode); | |||
| if (propertyR.isFail()) { | |||
| return AjaxResult.warn("配置同步失败,请检查"); | |||
| } | |||
| @@ -100,7 +100,8 @@ public class MessageQueueServiceImpl implements IMessageQueueService { | |||
| }; | |||
| try { | |||
| System.out.println("启动"); | |||
| config.setHostname(InetAddressUtils.getLocalHostLANAddress().getHostAddress()); | |||
| // config.setHostname(InetAddressUtils.getLocalHostLANAddress().getHostAddress()); | |||
| config.setHostname("0.0.0.0"); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| @@ -75,7 +75,6 @@ public class NettyClient { | |||
| public void connect() { | |||
| EventLoopGroup workerGroup = new NioEventLoopGroup(); | |||
| try { | |||
| HttpUrl authUrl = getAuthorizationUrl(hostUrl, APIKEY, APISecret); | |||
| @@ -144,10 +143,11 @@ public class NettyClient { | |||
| } | |||
| channel.writeAndFlush("介绍下自己"); | |||
| // mChannelFuture.channel().closeFuture().sync(); | |||
| }catch (InterruptedException ie) { | |||
| ie.printStackTrace(); | |||
| Thread.currentThread().interrupt(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } finally { | |||
| workerGroup.shutdownGracefully(); | |||
| } | |||
| } | |||
| @@ -78,6 +78,9 @@ public class WebSocketClient extends WebSocketListener { | |||
| WebSocket webSocket = okHttpClient.newWebSocket(request,new WebSocketClient()); | |||
| LOCK.wait(); | |||
| System.out.println("查询完成"); | |||
| } catch (InterruptedException ie) { | |||
| ie.printStackTrace(); | |||
| Thread.currentThread().interrupt(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| @@ -260,7 +263,7 @@ public class WebSocketClient extends WebSocketListener { | |||
| if (INSTANCE.redisTemplate.hasKey("gpt:websocket:1")) { | |||
| DmWebSocketMessageVo message = (DmWebSocketMessageVo) INSTANCE.redisTemplate.opsForValue().get("gpt:websocket:1"); | |||
| if (StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("birthday")) { | |||
| if (message != null && StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("birthday")) { | |||
| JSONObject birthdayJo = new JSONObject(); | |||
| birthdayJo.put("content", answer); | |||
| birthdayJo.put("timestamp", message.getFormat().get("timestamp")); | |||
| @@ -268,7 +271,7 @@ public class WebSocketClient extends WebSocketListener { | |||
| INSTANCE.redisTemplate.delete("gpt:websocket:1"); | |||
| return; | |||
| } | |||
| if (StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("hireDate")) { | |||
| if (message!= null && StringUtils.isNotEmpty(message.getTemplate()) && message.getTemplate().equals("hireDate")) { | |||
| JSONObject birthdayJo = new JSONObject(); | |||
| birthdayJo.put("content", answer); | |||
| birthdayJo.put("timestamp", message.getFormat().get("timestamp")); | |||
| @@ -276,11 +279,14 @@ public class WebSocketClient extends WebSocketListener { | |||
| INSTANCE.redisTemplate.delete("gpt:websocket:1"); | |||
| return; | |||
| } | |||
| JSONObject preWebsocketJo = message.getFormat(); | |||
| JSONObject meetingJo = new JSONObject(); | |||
| meetingJo.put("timestamp",preWebsocketJo.get("timestamp")); | |||
| meetingJo.put("content",answer); | |||
| INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + preWebsocketJo.getString("orderId"), "meeting", meetingJo.toString()); | |||
| if (message != null) { | |||
| JSONObject preWebsocketJo = message.getFormat(); | |||
| JSONObject meetingJo = new JSONObject(); | |||
| meetingJo.put("timestamp",preWebsocketJo.get("timestamp")); | |||
| meetingJo.put("content",answer); | |||
| INSTANCE.stringRedisTemplate.opsForHash().put("group:nlp" + ":" + preWebsocketJo.getString("orderId"), "meeting", meetingJo.toString()); | |||
| } | |||
| INSTANCE.redisTemplate.delete("gpt:websocket:1"); | |||
| }else { | |||
| @@ -0,0 +1,46 @@ | |||
| package com.xueyi.nlt.nlt.context; | |||
| import com.xueyi.common.core.utils.core.ConvertUtil; | |||
| import com.xueyi.common.core.utils.core.StrUtil; | |||
| import java.util.Map; | |||
| import java.util.concurrent.ConcurrentHashMap; | |||
| public class TerminalSecurityContextHolder { | |||
| private static final ThreadLocal<Map<String,Object>> THREAD_LOCAL = new ThreadLocal<>(); | |||
| public static Long getOperatorId() { | |||
| return ConvertUtil.toLong(get("operatorId"), -1L); | |||
| } | |||
| public static void setOperatorId(String operatorId) { | |||
| set("operatorId", operatorId); | |||
| } | |||
| public static void set(String key, Object value) { | |||
| Map<String, Object> map = getLocalMap(); | |||
| map.put(key, value == null ? StrUtil.EMPTY : value); | |||
| } | |||
| public static String get(String key) { | |||
| Map<String, Object> map = getLocalMap(); | |||
| return ConvertUtil.toStr(map.getOrDefault(key, StrUtil.EMPTY)); | |||
| } | |||
| public static <T> T get(String key, Class<T> clazz) { | |||
| Map<String, Object> map = getLocalMap(); | |||
| return ConvertUtil.convert(clazz, map.getOrDefault(key, null)); | |||
| } | |||
| public static Map<String, Object> getLocalMap() { | |||
| Map<String, Object> map = THREAD_LOCAL.get(); | |||
| if (map == null) { | |||
| map = new ConcurrentHashMap<>(); | |||
| THREAD_LOCAL.set(map); | |||
| } | |||
| return map; | |||
| } | |||
| public static void remove() { | |||
| THREAD_LOCAL.remove(); | |||
| } | |||
| } | |||
| @@ -28,6 +28,7 @@ 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.context.TerminalSecurityContextHolder; | |||
| import com.xueyi.nlt.nlt.domain.dto.DmIntentDto; | |||
| import com.xueyi.nlt.nlt.domain.query.DmIntentQuery; | |||
| import com.xueyi.nlt.nlt.domain.vo.IntentTemplateVo; | |||
| @@ -142,6 +143,7 @@ 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()); | |||
| redisTemplate.opsForValue().increment("dashboard:server", 1); | |||
| @@ -382,10 +384,12 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| if (StringUtils.isEmpty(intent.getSkillCode())) { | |||
| // 调用知识库问答 | |||
| AjaxResult qaAjax = searchQA(intent); | |||
| JSONObject qajson = qaAjax.toJson(); | |||
| String content = ""; | |||
| if (qaAjax.toJson().containsKey("data") && StringUtils.isNotEmpty(qaAjax.toJson().getJSONObject("data").getJSONObject("format").getString("result"))) { | |||
| log.info("知识库问答返回结果:{}",qaAjax.toString()); | |||
| if (qajson.containsKey("data") && qajson.getJSONObject("data").containsKey("result") && qajson.getJSONObject("data").size() > 0) { | |||
| content = qaAjax.toJson().getJSONObject("data").getJSONObject("format").getJSONArray("result").getJSONObject(0).getJSONObject("knowledge_lib").toString(); | |||
| content = qajson.getJSONObject("data").getJSONArray("result").getJSONObject(0).getString("knowledge_lib"); | |||
| } | |||
| pushIntoDashboardRedis(enterpriseName,content,"knowledge"); | |||
| return R.ok(JSONObject.from(qaAjax.get("data"))); | |||
| @@ -33,6 +33,7 @@ public class SparkServiceImpl implements ISysLlmService { | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| Thread.currentThread().interrupt(); | |||
| } | |||
| String result = redisTemplate.opsForValue().get("group:websocket:content"); | |||
| LlmResponse response = new LlmResponse(); | |||
| @@ -1,9 +1,12 @@ | |||
| package com.xueyi.nlt.nlt.template; | |||
| import com.alibaba.druid.util.StringUtils; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.alibaba.fastjson2.JSONException; | |||
| 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 org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| @@ -25,33 +28,68 @@ public class FreeChatTemplate implements BaseTemplate{ | |||
| @Override | |||
| public JSONObject handle(String devId, String content) { | |||
| Long operatorId = TerminalSecurityContextHolder.getOperatorId(); | |||
| String redisKey = "group:nlp:" + SecurityContextHolder.getLocalMap().get("enterprise_id") + ":" + operatorId; | |||
| // 根据content内容调用模版并返回结果 | |||
| synchronized (WebSocketClient.LOCK) { | |||
| // 通过redis获取数字人上下文信息 | |||
| Long size = redisTemplate.opsForList().size("group:device:" + devId); | |||
| Long size = redisTemplate.opsForList().size(redisKey); | |||
| if (size > 8) { | |||
| redisTemplate.opsForList().leftPop("group:device:" + devId,2); | |||
| redisTemplate.opsForList().leftPop(redisKey,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); | |||
| size = redisTemplate.opsForList().size(redisKey); | |||
| List<String> context = redisTemplate.opsForList().range(redisKey,size-6,size); | |||
| context.add(content); | |||
| String result = null; | |||
| 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; | |||
| 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; | |||
| } | |||
| } | |||
| 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(); | |||
| } | |||
| } | |||
| blockedWord = new String[]{"科大讯飞", "认知模型", "抱歉", "认知智能模型","你的话","上下文","您的输入","你的输入","您提到的"}; | |||
| for(String a :blockedWord){ | |||
| if(resultFinal != null && resultFinal.contains(a)){ | |||
| resultFinal = ""; | |||
| break; | |||
| } | |||
| } | |||
| if(!StringUtils.isEmpty(resultFinal)){ | |||
| redisTemplate.opsForList().rightPush(redisKey,content); | |||
| redisTemplate.opsForList().rightPush(redisKey,resultFinal); | |||
| } | |||
| JSONObject resultJson = new JSONObject(); | |||
| resultJson.put("msg",resultFinal); | |||
| return resultJson; | |||
| } | |||
| return null; | |||
| } | |||
| @Override | |||
| @@ -47,6 +47,7 @@ public class GenerativeKnowledgeTemplate implements BaseTemplate{ | |||
| } catch (InterruptedException e) { | |||
| log.warn(e.getMessage()); | |||
| Thread.currentThread().interrupt(); | |||
| } | |||
| } | |||
| return new JSONObject(); | |||
| @@ -46,6 +46,7 @@ import java.time.LocalDateTime; | |||
| import java.time.format.DateTimeFormatter; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Comparator; | |||
| import java.util.List; | |||
| import java.util.concurrent.TimeUnit; | |||
| import java.util.regex.Matcher; | |||
| @@ -81,8 +82,6 @@ public class MeetingOrderTemplate implements BaseTemplate { | |||
| @Autowired | |||
| NacosConfigManager nacosConfigManager; | |||
| @Autowired | |||
| private ISysLlmService sysLlmService; | |||
| private static final List<MeetingParamVo> MEETING_PARAMS = new ArrayList<>(); | |||
| @@ -148,11 +147,7 @@ public class MeetingOrderTemplate implements BaseTemplate { | |||
| @Override | |||
| public JSONObject handle(String devId, String content,Long tenantId) { | |||
| LocalDateTime date = LocalDateTime.now(); | |||
| DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); | |||
| DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00"); | |||
| DateTimeFormatter scheduleFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); | |||
| DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); | |||
| R<SysEnterpriseDto> enterpriseDtoR = enterpriseService.getInfo(tenantId); | |||
| Source source = SourceUtil.getSourceCache(enterpriseDtoR.getData().getStrategyId()); | |||
| R<DmDigitalmanExtPo> extR = digitalmanService.selectExtByDeviceId(devId,tenantId,source.getMaster(), SecurityConstants.INNER); | |||
| @@ -161,7 +156,6 @@ public class MeetingOrderTemplate implements BaseTemplate { | |||
| extPo = extR.getData(); | |||
| } | |||
| // 获取房间号 | |||
| R<List<DmMeetingRoomsDto>> roomListR = remoteMeetingService.roomListInner(extPo.getDeptId(),tenantId,source.getMaster(), SecurityConstants.INNER); | |||
| // 缓存获取会议室session信息 | |||
| @@ -173,70 +167,87 @@ public class MeetingOrderTemplate implements BaseTemplate { | |||
| session.getFormat().put("skillCode",SkillConstants.SkillType.BOOK_MEETING_ROOM.getCode()); | |||
| } | |||
| String prefix = "当前时间是"+ dateFormatter.format(date)+ " 00:00。我将提供一些用户输入的信息,请提取输入的内容进行结构化转换并输出对应 json 格式的代码。下面是结构的描述:date(格式为YYYY-MM-DD);start_time(格式HH:MM);location; 下面是用户的输入信息:开个会"; | |||
| String suffix = "\"。请开始信息提取,你回复的内容必须是一个json结构,如果没提取到的信息赋值为null,我不需要代码。"; | |||
| log.info(prefix + content + suffix); | |||
| LlmParam param = new LlmParam(); | |||
| LlmContext context = new LlmContext(prefix + content + suffix); | |||
| LlmResponse response = sysLlmService.chat(context,param); | |||
| String result = response.getContent(); | |||
| try { | |||
| //对result进行解析,获取字符串第一个与'{'和最后一个'}'之间的字符串,即为json字符串 | |||
| if (!result.contains("{") || !result.contains("}")) { | |||
| // 生成内容无效 | |||
| return session.getFormat(); | |||
| } | |||
| result = result.substring(result.indexOf("{"), result.lastIndexOf("}") + 1); | |||
| System.out.println(result); | |||
| JSONObject jo = JSONObject.parseObject(result); | |||
| String dateStr = jo.getString("date"); | |||
| String timeStr = jo.getString("start_time"); | |||
| String locationStr = jo.getString("location"); | |||
| if (StringUtils.isNotEmpty(locationStr)) { | |||
| roomListR.getData().forEach(item -> { | |||
| if(item.getName().equals(jo.get("location"))){ | |||
| jo.put("locationId",item.getId()); | |||
| } | |||
| }); | |||
| if (jo.get("locationId") != null) { | |||
| session.getFormat().put("location",locationStr); | |||
| session.getFormat().put("locationId",jo.get("locationId")); | |||
| } | |||
| } | |||
| //设置时间参数 | |||
| if (StringUtils.isNotEmpty(dateStr) && dateStr.split(":").length == 3) { | |||
| if (!jo.containsKey("locationId") || !session.getFormat().containsKey("date")) { | |||
| session.getFormat().put("date",dateStr); | |||
| } | |||
| } | |||
| if (StringUtils.isNotEmpty(timeStr) && !timeStr.equals("00:00")) { | |||
| //判断timeStr的格式是否是HH:mm | |||
| if (timeStr.split(":").length == 2) { | |||
| session.getFormat().put("start_time",timeStr); | |||
| //遍历roomListR.getData(),判断content中是否包含item.getName(),如果包含,则将item.getId()赋值给locationId | |||
| List<DmMeetingRoomsDto> aaa = roomListR.getData().stream().sorted((x,y)->y.getName().length() - x.getName().length()).collect(Collectors.toList()); | |||
| for (DmMeetingRoomsDto roomsDto : aaa) { | |||
| if (content.contains(roomsDto.getName())) { | |||
| // 更新session中的locationId与location | |||
| session.getFormat().put("location",roomsDto.getName()); | |||
| session.getFormat().put("locationId",roomsDto.getId()); | |||
| content = content.replace(roomsDto.getName(), "啊啊啊"); | |||
| break; | |||
| } | |||
| } | |||
| // 判断内容是否击中es | |||
| // CoversationSessionVo dateSession = processEsDate(content,session); | |||
| // 判断内容是否击中正则 | |||
| CoversationSessionVo dateSession = processRegexDatetime(content,session); | |||
| if (dateSession != null ){ | |||
| session = dateSession; | |||
| } | |||
| //判断会议室是否冲突,如果冲突,删除时间 | |||
| //判断是否击中持续时间的正则 | |||
| boolean flag = false; | |||
| String[] chinese = {"一","两","三","四","五","六","七","八"}; | |||
| for(int i=1;i<=8;i++){ | |||
| if(flag){ | |||
| break; | |||
| } | |||
| String a = String.format("%d小时", i); | |||
| String b = String.format("%s个小时", chinese[i-1]); | |||
| if(content.contains(a)||content.contains(b)){ | |||
| session.getFormat().put("duration", i * 60); | |||
| content = content.replace(a, "啊啊啊"); | |||
| content = content.replace(b, "啊啊啊"); | |||
| flag = true; | |||
| break; | |||
| } | |||
| } | |||
| for(int i=1;i<8;i++){ | |||
| if(flag){ | |||
| break; | |||
| } | |||
| if(content.contains(String.format("%s个半小时", chinese[i-1]))){ | |||
| session.getFormat().put("duration", i * 60 +30); | |||
| content = content.replace(String.format("%s个半小时", chinese[i-1]), "啊啊啊"); | |||
| flag = true; | |||
| break; | |||
| } | |||
| } | |||
| if(!flag && (content.contains("半小时")||content.contains("半个小时"))){ | |||
| session.getFormat().put("duration",30); | |||
| } | |||
| String[] intentList = {"例会","访客接待","面试","其他"}; | |||
| for(String a: intentList){ | |||
| if(content.contains(a)){ | |||
| session.getFormat().put("meetingIntent", a); | |||
| break; | |||
| } | |||
| } | |||
| //判断会议室是否冲突,如果冲突则回传有冲突 | |||
| JSONObject checkObject = session.getFormat(); | |||
| if (checkObject.containsKey("date") && checkObject.containsKey("time") && checkObject.containsKey("location")) { | |||
| JSONObject ret = remoteMeetingService.queryExist(checkObject.getLong("locationId"), checkObject.getString("date"), checkObject.getString("time"),tenantId,source.getMaster(), SecurityConstants.INNER); | |||
| if (checkObject.containsKey("date") && checkObject.containsKey("start_time") && checkObject.containsKey("location") && checkObject.containsKey("duration")) { | |||
| JSONObject ret= remoteMeetingService.queryExistOrder(checkObject.getLong("locationId"), checkObject.getString("date"), checkObject.getString("start_time"),checkObject.getInteger("duration"),tenantId,source.getMaster(), SecurityConstants.INNER); | |||
| if (StringUtils.isNotEmpty(ret.getString("err"))) { | |||
| // 会议室冲突,删除时间 | |||
| session.getFormat().remove("time"); | |||
| session.getFormat().put("conflict",1); | |||
| } | |||
| else{ | |||
| session.getFormat().put("conflict",0); | |||
| } | |||
| } | |||
| //判断是否为确认或取消指令 | |||
| checkObject = session.getFormat(); | |||
| if(checkObject.containsKey("date") && checkObject.containsKey("start_time") && checkObject.containsKey("location") && checkObject.containsKey("duration") && content.contains("确认")){ | |||
| if(checkObject.containsKey("conflict")){ | |||
| if(checkObject.getInteger("conflict") == 0){ | |||
| session.getFormat().put("confirm", 1); | |||
| } | |||
| } | |||
| } | |||
| if(content.contains("取消")){ | |||
| session.getFormat().put("confirm", 0); | |||
| } | |||
| // redis缓存更新session | |||
| objectRedisTemplate.opsForValue().set("group:device" + ":" + devId + ":" +"session", session, 1,TimeUnit.MINUTES); | |||
| session.getFormat().put("skillCode", SkillConstants.SkillType.BOOK_MEETING_ROOM.getCode()); | |||
| @@ -1,6 +1,5 @@ | |||
| package com.xueyi.system.digitalmans.controller; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
| @@ -12,10 +11,8 @@ 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.datasource.annotation.Master; | |||
| import com.xueyi.common.log.annotation.Log; | |||
| import com.xueyi.common.log.enums.BusinessType; | |||
| import com.xueyi.common.redis.utils.RedisUtil; | |||
| import com.xueyi.common.security.annotation.InnerAuth; | |||
| import com.xueyi.common.security.annotation.RequiresPermissions; | |||
| import com.xueyi.common.web.entity.controller.BaseController; | |||
| @@ -35,7 +32,6 @@ import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanExtDto; | |||
| import com.xueyi.system.digitalmans.domain.model.DmDigitalmanExtConverter; | |||
| import com.xueyi.system.digitalmans.domain.query.DmDigitalmanExtQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmDigitalmanQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmManDeviceQuery; | |||
| import com.xueyi.system.digitalmans.mapper.DmManDeviceMapper; | |||
| import com.xueyi.system.digitalmans.service.IDmDigitalmanExtService; | |||
| import com.xueyi.system.digitalmans.service.IDmDigitalmanService; | |||
| @@ -67,10 +63,7 @@ import org.springframework.web.bind.annotation.RestController; | |||
| import java.io.Serializable; | |||
| import java.text.ParseException; | |||
| import java.time.Duration; | |||
| import java.util.ArrayList; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.stream.Collectors; | |||
| /** | |||
| * 数字人基础管理 业务处理 | |||
| @@ -395,80 +388,6 @@ public class DmDigitalmanController extends BaseController<DmDigitalmanQuery, Dm | |||
| DmManDeviceServiceImpl dmManDeviceService; | |||
| @GetMapping("/api/mansInfo") | |||
| @Master | |||
| public R<JSONObject> mansInfo() { | |||
| List<DmManDeviceDto> dtos = dmManDeviceService.selectList(new DmManDeviceQuery()); | |||
| List<DmManDeviceDto> dtos2 = dtos.stream().filter(dto -> StringUtils.isNotEmpty(dto.getDeviceId())).collect(Collectors.toList());; | |||
| Long serviceTimeCount = 0L; | |||
| //当前时间和activateTime时间的差值,activateTime类型是Date,差值返回的单位是小时 | |||
| for (DmManDeviceDto dto : dtos2) { | |||
| serviceTimeCount += (System.currentTimeMillis() - dto.getActivateTime().getTime())/3600000; | |||
| } | |||
| Integer meetingServiceCount = RedisUtil.getNumberVal("dashboard:meeting"); | |||
| Integer serverTimes = RedisUtil.getNumberVal("dashboard:server"); | |||
| Integer recognition = RedisUtil.getNumberVal("dashboard:recognition"); | |||
| Integer receptionCount = RedisUtil.getNumberVal("dashboard:create_visitor_info"); | |||
| Integer visitorCount = RedisUtil.getNumberVal("dashboard:register_visitor"); | |||
| Integer attendanceCount = RedisUtil.getNumberVal("dashboard:attendance"); | |||
| Integer openDoorCount = RedisUtil.getNumberVal("dashboard:open_door"); | |||
| Integer conversationDuration = RedisUtil.getNumberVal("dashboard:conversation-duration"); | |||
| Integer conversationTimes = RedisUtil.getNumberVal("dashboard:conversation-times"); | |||
| Integer broadcastCount = RedisUtil.getNumberVal("dashboard:broadcast-count"); | |||
| List<JSONObject> knowledgeList = new ArrayList<>(); | |||
| if (RedisUtil.existed("dashboard:knowledge-consume")) { | |||
| knowledgeList = RedisUtil.getJsonList("dashboard:knowledge-consume"); | |||
| //取值后清除缓存list,5秒后过期 | |||
| RedisUtil.expire("dashboard:knowledge-consume", 5); | |||
| } | |||
| List<JSONObject> skillList = new ArrayList<>(); | |||
| if (RedisUtil.existed("dashboard:skill-consume")) { | |||
| skillList = RedisUtil.getJsonList("dashboard:skill-consume"); | |||
| //取值后清除缓存list,5秒后过期 | |||
| RedisUtil.expire("dashboard:skill-consume", 5); | |||
| } | |||
| JSONArray jsonArray = new JSONArray(); | |||
| // 最近三十天的数据,服务人次,知识库增量 | |||
| for (int i = 0; i < 30; i++) { | |||
| Date date = DateUtils.addDays(new Date(), -i); | |||
| String dateStr2 = DateUtils.formatDate(date, "yyyy-MM-dd"); | |||
| JSONObject json2 = new JSONObject(); | |||
| json2.put("date", dateStr2); | |||
| json2.put("serviceTimes", RedisUtil.getNumberVal("dashboard:server-chart:"+dateStr2)); | |||
| json2.put("knowledgeNums", RedisUtil.getNumberVal("dashboard:server-chart:"+dateStr2)); | |||
| jsonArray.add(json2); | |||
| } | |||
| JSONObject json = new JSONObject(); | |||
| json.put("manCount",dtos2.size());//数字人数 | |||
| json.put("recognizedPersonCount", recognition);//注册人员总数 | |||
| json.put("serviceTimeCount",serviceTimeCount);//总服务时间 | |||
| json.put("chatTimes",conversationTimes);//对话次数 | |||
| json.put("chatDurationCount",conversationDuration);//对话时长 | |||
| json.put("servicePerCount",serverTimes);//用户使用频次?改成服务人次 | |||
| json.put("serviceTotal",meetingServiceCount+receptionCount+visitorCount+attendanceCount+openDoorCount+broadcastCount); | |||
| json.put("meetingServiceCount", meetingServiceCount);//会议 | |||
| json.put("receptionCount",receptionCount);//接待 | |||
| json.put("visitorCount",visitorCount);//访客 | |||
| json.put("attendanceCount",attendanceCount);//考勤 | |||
| json.put("openDoorCount",openDoorCount);//门禁 | |||
| json.put("broadcastCount",broadcastCount);//播报 | |||
| json.put("knowledgeConsume",knowledgeList);//实时知识库调用 | |||
| json.put("skillConsume",skillList);//实时技能调用 | |||
| json.put("serverCharts",jsonArray);// | |||
| log.info(json.toJSONString()); | |||
| return R.ok(json); | |||
| } | |||
| @GetMapping("/api/devInfo/{devId}") | |||
| public R<DmDigitalmanExtPo> devInfo(@PathVariable(required = true) String devId) { | |||
| if (StringUtils.isNotEmpty(devId)){ | |||
| @@ -13,4 +13,6 @@ import java.util.List; | |||
| */ | |||
| public interface IDmDigitalmanExtManager extends IBaseManager<DmDigitalmanExtQuery, DmDigitalmanExtDto> { | |||
| public List<DmDigitalmanExtDto> selectByDeviceId(DmDigitalmanExtQuery query); | |||
| } | |||
| @@ -28,4 +28,5 @@ public class DmDigitalmanExtManager extends BaseManagerImpl<DmDigitalmanExtQuery | |||
| .eq(DmDigitalmanExtPo::getDeviceId,query.getDeviceId())); | |||
| return mapperDto(list); | |||
| } | |||
| } | |||
| @@ -21,6 +21,7 @@ import com.xueyi.system.digitalmans.mapper.DmDigitalmanWorktimeMapper; | |||
| import com.xueyi.system.digitalmans.mapper.DmModelMapper; | |||
| import com.xueyi.system.organize.mapper.SysDeptExtMapper; | |||
| import com.xueyi.system.resource.mapper.DmResourcesMapper; | |||
| import org.apache.commons.lang.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Component; | |||
| @@ -93,7 +94,7 @@ public class DmDigitalmanManager extends BaseManagerImpl<DmDigitalmanQuery, DmDi | |||
| .lambda().eq(DmDigitalmanExtPo::getManCode,dto.getManCode())); | |||
| po.setDeptId(dto.getDeptId()); | |||
| if (dto.getSetSpace() != null && dto.getSetSpace() != "") { | |||
| if (StringUtils.isNotEmpty(dto.getSetSpace())) { | |||
| po.setSetSpace(dto.getSetSpace()); | |||
| } | |||
| digitalmanExtMapper.updateById(po); | |||
| @@ -201,4 +201,12 @@ public class DmMeetingApiController extends BaseApiController { | |||
| return remoteMeetingService.queryExist(roomId, dateStr, startTime, vo.getTenantId(),vo.getSourceSlave(), SecurityConstants.INNER); | |||
| } | |||
| @ResponseBody | |||
| @GetMapping(value = "/enableOrderMeeting/{devId}") | |||
| public JSONObject queryAbleExist(@PathVariable(value = "devId") String devId, Long roomId, String dateStr, String startTime, Integer duration) { | |||
| DeviceTenantSourceMergeVo vo = super.getDeviceTenantSourceMergeVo(devId); | |||
| return remoteMeetingService.queryExistOrder(roomId, dateStr, startTime, duration, vo.getTenantId(),vo.getSourceSlave(), SecurityConstants.INNER); | |||
| } | |||
| } | |||
| @@ -188,6 +188,9 @@ public class DmMeetingInnerApiController extends BaseApiController { | |||
| String mms2 = mms.substring(0, mms.length() - 1) + "于" + meetingRoom.getName(); | |||
| DmStaffPo dmStaffPo = dmStaffMapper.selectById(order.getOrderBy()); | |||
| if (dmStaffPo == null) { | |||
| return output(ResponseCode.DATA_NOT_EXISTS, "预定人").toJSON(); | |||
| } | |||
| SmsReqEntity send = new SmsReqEntity(); | |||
| try { | |||
| @@ -266,6 +269,33 @@ public class DmMeetingInnerApiController extends BaseApiController { | |||
| return outputSuccess().toJSON(); | |||
| } | |||
| @InnerAuth | |||
| @GetMapping(value = "/enableOrder/{roomId}/{dateStr}/{startTime}/{duration}") | |||
| public JSONObject queryExistOrder(@PathVariable(name = "roomId") Long roomId, @PathVariable(name = "dateStr") String dateStr, @PathVariable(name = "startTime") String startTime, @PathVariable(name = "duration") Integer duration) { | |||
| log.info("dateStr:{}", dateStr); | |||
| log.info("startTime:{}", startTime); | |||
| DmMeetingRoomsPo room = dmMeetingRoomsMapper.findById(roomId); | |||
| if (null == room) { | |||
| return output(ResponseCode.DATA_NOT_EXISTS, "会议室").toJSON(); | |||
| } | |||
| if (DateUtils.formatDate(new Date(), "yyyy-MM-dd").compareTo(dateStr) > 0) { | |||
| return output(ResponseCode.MEETING_ORDER_TIME_ERROR).toJSON(); | |||
| } | |||
| if (StringUtils.isEmpty(startTime)) { | |||
| return output(ResponseCode.MEETING_ORDER_TIME_ERROR).toJSON(); | |||
| } | |||
| String sTime = startTime,eTime = ""; | |||
| Date end = DateUtils.addMinutes(DateUtils.parseStrToDate(dateStr + " " + startTime, "yyyy-MM-dd HH:mm"), 30); | |||
| end = DateUtils.addMinutes(end, duration); | |||
| eTime = DateUtils.formatDate(end, "HH:mm"); | |||
| List<DmMeetingOrdersPo> lists = dmMeetingOrdersMapper.queryByOrder(roomId, dateStr, sTime, eTime); | |||
| if (lists.size() > 0) { | |||
| return output(ResponseCode.MEETING_ORDER_TIME_ERROR).toJSON(); | |||
| } | |||
| return outputSuccess().toJSON(); | |||
| } | |||
| @InnerAuth | |||
| @PostMapping(value = "/quit") | |||
| public JSONObject quitInner(@RequestParam("id") Long id) { | |||
| @@ -326,6 +356,9 @@ public class DmMeetingInnerApiController extends BaseApiController { | |||
| @InnerAuth | |||
| @PostMapping(value = "/date-lists") | |||
| public JSONObject listByDate(@RequestParam("dateStr") String dateStr) { | |||
| if (StringUtils.isEmpty(dateStr) || dateStr.length() < 9) { | |||
| return output(ResponseCode.ILLEGAL_PARAMETER, "日期格式不正确").toJSON(); | |||
| } | |||
| List<DmMeetingOrdersPo> list = dmMeetingOrdersMapper.findListByDateStr(dateStr); | |||
| List<DmMeetingOrdersDto> res = new ArrayList<>(); | |||
| list.forEach(item -> { | |||
| @@ -344,6 +377,9 @@ public class DmMeetingInnerApiController extends BaseApiController { | |||
| @InnerAuth | |||
| @PostMapping(value = "/lists") | |||
| public JSONObject listInner(@RequestParam("dateStr") String dateStr, @RequestParam("spaceId") Long spaceId) { | |||
| if (StringUtils.isEmpty(dateStr) || dateStr.length() < 9) { | |||
| return output(ResponseCode.ILLEGAL_PARAMETER, "日期格式不正确").toJSON(); | |||
| } | |||
| List<DmMeetingOrdersPo> list = dmMeetingOrdersMapper.findListByDate(dateStr, spaceId); | |||
| List<DmMeetingOrdersDto> res = new ArrayList<>(); | |||
| list.forEach(item -> { | |||
| @@ -357,6 +393,9 @@ public class DmMeetingInnerApiController extends BaseApiController { | |||
| @InnerAuth | |||
| @PostMapping(value = "/lists-all") | |||
| public JSONObject listAllInner(@RequestParam("dateStr") String dateStr, @RequestParam("spaceId") Long spaceId) { | |||
| if (StringUtils.isEmpty(dateStr) || dateStr.length() < 10) { | |||
| return output(ResponseCode.ILLEGAL_PARAMETER, "日期格式不正确").toJSON(); | |||
| } | |||
| String date = dateStr.substring(0, 10); | |||
| String time = dateStr.substring(11); | |||
| System.err.println("date:"+date+"; time:"+time+";spaceId:"+spaceId); | |||
| @@ -163,7 +163,7 @@ public class SysProfileController extends BasisController { | |||
| if (!StrUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.IMAGE_EXTENSION) + "格式"); | |||
| } | |||
| R<SysFile> fileResult = remoteFileService.upload(file); | |||
| R<SysFile> fileResult = remoteFileService.uploadFace(file); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -111,7 +111,7 @@ public class DmRecognizedRecordsInnerApiController extends BaseApiController { | |||
| } | |||
| if (StringUtils.isNotEmpty(imgBase64)) { | |||
| R<SysFile> fileResult = fileService.upload(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| R<SysFile> fileResult = fileService.uploadFace(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return output(ResponseCode.FILE_SERVICE_ERROR).toJSON(); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -163,7 +163,7 @@ public class DmRecognizedRecordsInnerApiController extends BaseApiController { | |||
| } | |||
| } | |||
| if (StringUtils.isNotEmpty(imgBase64)) { | |||
| R<SysFile> fileResult = fileService.upload(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| R<SysFile> fileResult = fileService.uploadFace(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return output(ResponseCode.FILE_SERVICE_ERROR).toJSON(); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -38,12 +38,17 @@ public class DmH5ConfigController extends BaseController<DmH5ConfigQuery, DmH5Co | |||
| } | |||
| @GetMapping("/inner/syncH5Config") | |||
| R<String> syncH5Config(@RequestParam(value = "tId",required = false) String tId) { | |||
| R<String> syncH5Config(@RequestParam(value = "tId",required = false) String tId, | |||
| @RequestParam(value = "manCode",required = false) String manCode) { | |||
| Long tenantId = null; | |||
| if (StringUtils.isNotEmpty(tId)) { | |||
| tenantId = Long.parseLong(tId); | |||
| } | |||
| String result = baseService.syncH5Config(tenantId); | |||
| String dmCode = null; | |||
| if (StringUtils.isNotEmpty(manCode)) { | |||
| dmCode = manCode; | |||
| } | |||
| String result = baseService.syncH5Config(tenantId, dmCode); | |||
| if (StringUtils.isNotEmpty(result)) { | |||
| return R.ok(result); | |||
| } | |||
| @@ -70,6 +75,14 @@ public class DmH5ConfigController extends BaseController<DmH5ConfigQuery, DmH5Co | |||
| return super.getInfo(id); | |||
| } | |||
| @GetMapping(value = "/{id}/{mancode}") | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_SINGLE) | |||
| public AjaxResult getInfo(@PathVariable("id") Serializable id,@PathVariable("mancode") String mancode) { | |||
| DmH5ConfigDto dto = baseService.selectbyIdCode(id, mancode); | |||
| return AjaxResult.success(dto); | |||
| } | |||
| /** | |||
| * H5配置表新增 | |||
| */ | |||
| @@ -121,6 +134,17 @@ public class DmH5ConfigController extends BaseController<DmH5ConfigQuery, DmH5Co | |||
| return super.batchRemove(idList); | |||
| } | |||
| /** | |||
| * H5配置表按照数字人与id删除 | |||
| */ | |||
| @DeleteMapping(value = "/{id}/{mancode}") | |||
| @RequiresPermissions(Auth.DM_H5_CONFIG_DEL) | |||
| @Log(title = "H5配置表管理", businessType = BusinessType.DELETE) | |||
| public AjaxResult batchRemove(@PathVariable("id") Serializable id,@PathVariable("mancode") String manCode) { | |||
| int result = baseService.deleteByIdCode(id, manCode); | |||
| return AjaxResult.success(result); | |||
| } | |||
| /** | |||
| * 获取H5配置表选择框列表 | |||
| */ | |||
| @@ -144,4 +168,4 @@ public class DmH5ConfigController extends BaseController<DmH5ConfigQuery, DmH5Co | |||
| /** 系统 - H5配置表管理 - 删除 */ | |||
| String DM_H5_CONFIG_DEL = "resource:h5config:delete"; | |||
| } | |||
| } | |||
| } | |||
| @@ -4,15 +4,19 @@ import cn.hutool.core.text.CharSequenceUtil; | |||
| import cn.hutool.core.util.ObjectUtil; | |||
| import com.alibaba.fastjson.JSONArray; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.xueyi.common.core.utils.core.IdUtil; | |||
| import com.xueyi.common.core.utils.file.FileTypeUtil; | |||
| import com.xueyi.common.core.utils.file.FileUtil; | |||
| import com.xueyi.common.core.utils.file.MimeTypeUtil; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.common.core.web.result.R; | |||
| 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.redis.utils.RedisUtil; | |||
| import com.xueyi.common.security.annotation.RequiresPermissions; | |||
| import com.xueyi.common.web.entity.controller.BaseController; | |||
| import com.xueyi.file.api.domain.ByteArrayMultipartFile; | |||
| import com.xueyi.file.api.domain.SysFile; | |||
| import com.xueyi.file.api.feign.RemoteFileService; | |||
| import com.xueyi.system.api.resource.domain.po.DmResourcesPo; | |||
| @@ -23,6 +27,7 @@ import com.xueyi.system.resource.service.IDmResourcesService; | |||
| import com.xueyi.system.resource.service.impl.FaceServiceImpl; | |||
| import com.xueyi.system.utils.common.ImageUtil; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.mock.web.MockMultipartFile; | |||
| import org.springframework.validation.annotation.Validated; | |||
| import org.springframework.web.bind.annotation.DeleteMapping; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| @@ -35,10 +40,14 @@ import org.springframework.web.bind.annotation.RequestParam; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import org.springframework.web.multipart.MultipartFile; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.Serializable; | |||
| import java.util.Arrays; | |||
| import java.util.List; | |||
| import java.util.stream.Collectors; | |||
| /** | |||
| * 静态资源管理 业务处理 | |||
| @@ -140,22 +149,196 @@ public class DmResourcesController extends BaseController<DmResourcesQuery, DmRe | |||
| private static final String PARAM_URL = "url"; | |||
| private static final String PARAM_TYPE = "type"; | |||
| @PostMapping("/chunkUpload") | |||
| public AjaxResult uploadChunk( | |||
| @RequestParam("file") MultipartFile file, | |||
| @RequestParam("chunkIndex") int chunk, | |||
| @RequestParam("chunkCount") int chunks, | |||
| @RequestParam("uploadUuid") String uuid | |||
| ) throws IOException { | |||
| String folder = "/home/xueyi/upload/temp/"; | |||
| String key = "saas:upload:chunk:"+uuid; | |||
| File dir = new File(folder); | |||
| if (!dir.exists()) { | |||
| dir.mkdirs(); | |||
| } | |||
| String fileName = FileUtil.getFileNameNoExt(file.getOriginalFilename()); | |||
| if (RedisUtil.existed(key+":fileName")) { | |||
| fileName = (String) RedisUtil.getVal(key+":fileName"); | |||
| } else { | |||
| RedisUtil.setVal(key+":fileName",fileName); | |||
| } | |||
| logger.info("chunkIndex:{},chunkTotal:{},fileName:{},fileOriginName:{}",chunk,chunks,file.getName(),fileName); | |||
| logger.info("upload 第{}/{} 块",chunk+1,chunks); | |||
| String path = folder + fileName + "_" + chunk + ".part"; | |||
| try { | |||
| file.transferTo(new File(path)); | |||
| RedisUtil.increment(key,1); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| return AjaxResult.error("文件保存失败"); | |||
| } | |||
| if (((Integer) RedisUtil.getVal(key)).longValue() == chunks) { | |||
| // 合并所有分片 | |||
| File[] content = new File[chunks]; | |||
| for (int i = 0; i < chunks; i++) { | |||
| content[i] = new File(folder + fileName + "_" + i + ".part"); | |||
| } | |||
| File destFile = new File(folder + fileName); | |||
| logger.info("合并文件:{},文件数:{}",destFile.getAbsolutePath(), content.length); | |||
| FileUtil.mergeFile(content, destFile); | |||
| // 删除分片文件 | |||
| for (int i = 0; i < chunks; i++) { | |||
| new File(folder + fileName + "_" + i + ".part").delete(); | |||
| } | |||
| MultipartFile multipartFile = new MockMultipartFile(fileName, new FileInputStream(destFile)); | |||
| RedisUtil.expire(key, 5); | |||
| return executeUpload(multipartFile, FileTypeUtil.getExtension(file), uuid); | |||
| } | |||
| return AjaxResult.success("上传文件成功!"); | |||
| } | |||
| private MultipartFile mergeChunks(List<byte[]> byteArrays) { | |||
| // 合并所有分片的byte数组为一个byte数组 | |||
| int totalSize = byteArrays.stream().mapToInt(byteArray -> byteArray.length).sum(); | |||
| byte[] mergedBytes = new byte[totalSize]; | |||
| int currentIndex = 0; | |||
| //byteArrays 顺序颠倒 | |||
| for (int i = byteArrays.size()-1; i >= 0; i--) { | |||
| byte[] bytes = byteArrays.get(i); | |||
| System.arraycopy(bytes, 0, mergedBytes, currentIndex, bytes.length); | |||
| currentIndex += bytes.length; | |||
| } | |||
| /*for (byte[] bytes : byteArrays) { | |||
| System.arraycopy(bytes, 0, mergedBytes, currentIndex, bytes.length); | |||
| currentIndex += bytes.length; | |||
| }*/ | |||
| logger.info("mergeChunks count:{}", byteArrays.size()); | |||
| logger.info("mergeChunks currentIndex:{}", currentIndex); | |||
| // 创建一个新的MultipartFile对象,代表合并后的文件 | |||
| return new ByteArrayMultipartFile(mergedBytes); | |||
| } | |||
| /** | |||
| * 头像上传 | |||
| */ | |||
| @PostMapping("/upload") | |||
| @Log(title = "资源管理 - 上传资源", businessType = BusinessType.UPDATE) | |||
| public AjaxResult upload(@RequestParam("file") MultipartFile file) { | |||
| logger.info("file contentType:{}, size:{}, name:{}, empty:{}",file.getContentType() ,file.getSize(), file.getOriginalFilename(), file.isEmpty()); | |||
| String extension = FileTypeUtil.getExtension(file); | |||
| String uploadUuid = IdUtil.randomUUID(); | |||
| if (!file.isEmpty()) { | |||
| String extension = FileTypeUtil.getExtension(file); | |||
| logger.info("文件类型:" + extension+",上传开始..."); | |||
| logger.info("文件类型:" + extension + ",上传到MINIO开始..."); | |||
| if (!CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.EXCEPT_ALLOWED_EXTENSION)) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.EXCEPT_ALLOWED_EXTENSION) + "格式"); | |||
| } | |||
| if(MimeTypeUtil.PDF_EXTENSION.equalsIgnoreCase(extension)) { | |||
| R<List<SysFile>> fileResult = remoteFileService.uploadPdf(file); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| R<SysFile> fileResult = remoteFileService.uploadNoAsync(file, extension, uploadUuid); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| String url = fileResult.getData().getUrl(); | |||
| DmResourcesDto dto = new DmResourcesDto(); | |||
| dto.setName(file.getOriginalFilename()); | |||
| dto.setUrl(url); | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| dto.setType(DmResourcesPo.TYPE_PIC); | |||
| } | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.VIDEO_EXTENSION)) { | |||
| dto.setType(DmResourcesPo.TYPE_VIDEO); | |||
| } | |||
| dto.setFileSize(fileResult.getData().getSize()); | |||
| dto.setFeature(""); | |||
| iDmResourcesService.addOne(dto); | |||
| JSONObject jo = new JSONObject(); | |||
| jo.put(PARAM_RESOURCE_ID, dto.getId()); | |||
| jo.put(PARAM_URL, url); | |||
| jo.put(PARAM_TYPE, dto.getType()); | |||
| AjaxResult ajax = success(); | |||
| ajax.put(AjaxResult.RESULT_TAG, jo); | |||
| logger.info("上传文件成功,返回数据:" + ajax.toJson().toJSONString()); | |||
| return ajax; | |||
| } | |||
| return error("上传文件异常,请联系管理员!"); | |||
| } | |||
| @GetMapping("/uploadCallback") | |||
| @Log(title = "资源管理 - 上传资源回调", businessType = BusinessType.UPDATE) | |||
| public AjaxResult pdfUploadCallback(@RequestParam("uploadUuid") String uploadUuid) { | |||
| if (!RedisUtil.existed("saas:upload:result:"+uploadUuid)) { | |||
| return AjaxResult.error("上传操作可能尚未完成,请等待..."); | |||
| } | |||
| String result = (String) RedisUtil.getVal("saas:upload:result:"+uploadUuid); | |||
| String fileName = (String) RedisUtil.getVal("saas:upload:filename:"+uploadUuid); | |||
| Integer fileType = (Integer) RedisUtil.getVal("saas:upload:fileType:"+uploadUuid); | |||
| JSONArray res = JSONArray.parseArray(result); | |||
| List<JSONObject> jsons = res.stream().map(sf -> (JSONObject) sf).collect(Collectors.toList()); | |||
| if (RedisUtil.existed("saas:upload:callbackExec:"+uploadUuid)) { | |||
| JSONArray _res = JSONArray.parseArray((String) RedisUtil.getVal("saas:upload:callbackExec:"+uploadUuid)); | |||
| return AjaxResult.success(_res); | |||
| } | |||
| JSONArray ja = new JSONArray(); | |||
| for (JSONObject sf : jsons) { | |||
| String url = (String) sf.get("url"); | |||
| DmResourcesDto dto = new DmResourcesDto(); | |||
| dto.setName(fileName); | |||
| dto.setUrl(url); | |||
| dto.setType(fileType); | |||
| dto.setFileSize(((Integer) sf.get("size")).longValue()); | |||
| dto.setFeature(""); | |||
| iDmResourcesService.addOne(dto); | |||
| JSONObject jo = new JSONObject(); | |||
| jo.put(PARAM_RESOURCE_ID, dto.getId()); | |||
| jo.put(PARAM_URL, url); | |||
| jo.put(PARAM_TYPE, dto.getType()); | |||
| ja.add(jo); | |||
| } | |||
| AjaxResult ajax = success(); | |||
| ajax.put(AjaxResult.RESULT_TAG, ja); | |||
| RedisUtil.setVal("saas:upload:callbackExec:"+uploadUuid, ja.toJSONString()); | |||
| logger.info("上传文件成功,返回数据:" + ajax.toJson().toJSONString()); | |||
| return ajax; | |||
| } | |||
| public AjaxResult executeUpload(MultipartFile file, String extension, String uploadUuid) { | |||
| logger.info("file contentType:{}, size:{}, name:{}, empty:{}",file.getContentType() ,file.getSize(), file.getOriginalFilename(), file.isEmpty()); | |||
| if (!file.isEmpty()) { | |||
| logger.info("文件类型:" + extension + ",上传到MINIO开始..."); | |||
| if (!CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.EXCEPT_ALLOWED_EXTENSION)) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.EXCEPT_ALLOWED_EXTENSION) + "格式"); | |||
| } | |||
| if (MimeTypeUtil.PDF_EXTENSION.equalsIgnoreCase(extension)) { | |||
| remoteFileService.uploadPdf(file, uploadUuid); | |||
| /*if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| JSONArray ja = new JSONArray(); | |||
| for (SysFile sf : fileResult.getData()) { | |||
| @@ -165,6 +348,7 @@ public class DmResourcesController extends BaseController<DmResourcesQuery, DmRe | |||
| dto.setUrl(url); | |||
| dto.setType(DmResourcesPo.TYPE_PIC); | |||
| dto.setFileSize(sf.getSize()); | |||
| dto.setFeature(""); | |||
| iDmResourcesService.addOne(dto); | |||
| JSONObject jo = new JSONObject(); | |||
| @@ -172,26 +356,36 @@ public class DmResourcesController extends BaseController<DmResourcesQuery, DmRe | |||
| jo.put(PARAM_URL, url); | |||
| jo.put(PARAM_TYPE, dto.getType()); | |||
| ja.add(jo); | |||
| } | |||
| }*/ | |||
| AjaxResult ajax = success(); | |||
| ajax.put(AjaxResult.RESULT_TAG, ja); | |||
| logger.info("上传文件成功,返回数据:" + ajax.toJson().toJSONString()); | |||
| ajax.put(AjaxResult.MSG_TAG, "文件后台上传处理中..."); | |||
| ajax.put("uploadUuid", uploadUuid); | |||
| logger.info("异步上传文件..."); | |||
| return ajax; | |||
| } else { | |||
| R<SysFile> fileResult = remoteFileService.upload(file); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| remoteFileService.upload(file, extension, uploadUuid); | |||
| AjaxResult ajax = success(); | |||
| ajax.put(AjaxResult.MSG_TAG, "文件后台上传处理中..."); | |||
| ajax.put("uploadUuid", uploadUuid); | |||
| logger.info("异步上传文件..."); | |||
| return ajax; | |||
| /*if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| String url = fileResult.getData().getUrl(); | |||
| DmResourcesDto dto = new DmResourcesDto(); | |||
| String url = fileResult.getData().getUrl();*/ | |||
| /*DmResourcesDto dto = new DmResourcesDto(); | |||
| dto.setName(file.getOriginalFilename()); | |||
| dto.setUrl(url); | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION) ) { | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| dto.setType(DmResourcesPo.TYPE_PIC); | |||
| } | |||
| if (CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.VIDEO_EXTENSION)) { | |||
| dto.setType(DmResourcesPo.TYPE_VIDEO); | |||
| } | |||
| dto.setFileSize(fileResult.getData().getSize()); | |||
| dto.setFeature(""); | |||
| iDmResourcesService.addOne(dto); | |||
| JSONObject jo = new JSONObject(); | |||
| @@ -202,9 +396,8 @@ public class DmResourcesController extends BaseController<DmResourcesQuery, DmRe | |||
| AjaxResult ajax = success(); | |||
| ajax.put(AjaxResult.RESULT_TAG, jo); | |||
| logger.info("上传文件成功,返回数据:" + ajax.toJson().toJSONString()); | |||
| return ajax; | |||
| return ajax;*/ | |||
| } | |||
| } | |||
| return error("上传文件异常,请联系管理员!"); | |||
| } | |||
| @@ -221,7 +414,7 @@ public class DmResourcesController extends BaseController<DmResourcesQuery, DmRe | |||
| ) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.IMAGE_EXTENSION) + Arrays.toString(MimeTypeUtil.IMAGE_EXTENSION) + "格式"); | |||
| } | |||
| R<List<SysFile>> fileResult = remoteFileService.uploadPdf(file); | |||
| R<List<SysFile>> fileResult = remoteFileService.uploadPdf(file, IdUtil.randomUUID()); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| JSONArray ja = new JSONArray(); | |||
| @@ -270,7 +463,7 @@ public class DmResourcesController extends BaseController<DmResourcesQuery, DmRe | |||
| if (!CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.IMAGE_EXTENSION) + "格式"); | |||
| } | |||
| R<SysFile> fileResult = remoteFileService.upload(file); | |||
| R<SysFile> fileResult = remoteFileService.uploadFace(file); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -23,4 +23,6 @@ public class DmH5ConfigDto extends DmH5ConfigPo { | |||
| /** 属性值 */ | |||
| private String property; | |||
| private String manCode; | |||
| } | |||
| @@ -15,6 +15,10 @@ import java.io.Serial; | |||
| @EqualsAndHashCode(callSuper = true) | |||
| public class DmResourcesDto extends DmResourcesPo { | |||
| public DmResourcesDto() { | |||
| this.setFeature(""); | |||
| } | |||
| @Serial | |||
| private static final long serialVersionUID = 1L; | |||
| @@ -4,6 +4,8 @@ import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.common.web.entity.service.IBaseService; | |||
| import java.io.Serializable; | |||
| /** | |||
| * H5配置表管理 服务层 | |||
| * | |||
| @@ -17,5 +19,9 @@ public interface IDmH5ConfigService extends IBaseService<DmH5ConfigQuery, DmH5Co | |||
| * @param tId 租户Id | |||
| * @return 结果 | |||
| */ | |||
| public String syncH5Config(Long tId); | |||
| public String syncH5Config(Long tId, String manCode); | |||
| public DmH5ConfigDto selectbyIdCode(Serializable id, String manCode); | |||
| public int deleteByIdCode(Serializable id, String manCode); | |||
| } | |||
| @@ -1,11 +1,19 @@ | |||
| package com.xueyi.system.resource.service.impl; | |||
| import com.alibaba.cloud.nacos.NacosConfigManager; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.alibaba.nacos.api.exception.NacosException; | |||
| import com.aliyun.tea.utils.StringUtils; | |||
| 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.dto.DmDigitalmanDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanExtDto; | |||
| import com.xueyi.system.digitalmans.domain.query.DmDigitalmanExtQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmManDeviceQuery; | |||
| import com.xueyi.system.digitalmans.manager.IDmDigitalmanExtManager; | |||
| import com.xueyi.system.digitalmans.manager.IDmManDeviceManager; | |||
| import com.xueyi.system.digitalmans.service.IDmManDeviceService; | |||
| import com.xueyi.system.resource.domain.dto.DmH5ConfigDto; | |||
| import com.xueyi.system.resource.domain.query.DmH5ConfigQuery; | |||
| @@ -19,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import java.io.Serializable; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| import java.util.Objects; | |||
| import java.util.stream.Collectors; | |||
| @@ -39,6 +48,8 @@ public class DmH5ConfigServiceImpl extends BaseServiceImpl<DmH5ConfigQuery, DmH5 | |||
| @Autowired | |||
| IDmManDeviceService dmManDeviceService; | |||
| @Autowired | |||
| IDmManDeviceManager dmManDeviceManager; | |||
| /** | |||
| @@ -50,43 +61,135 @@ public class DmH5ConfigServiceImpl extends BaseServiceImpl<DmH5ConfigQuery, DmH5 | |||
| @Override | |||
| //@DataScope(userAlias = "createBy", mapperScope = {"DmH5ConfigMapper"}) | |||
| public List<DmH5ConfigDto> selectListScope(DmH5ConfigQuery h5Config) { | |||
| List<DmH5ConfigDto> resultlist = new ArrayList<>(); | |||
| List<DmH5ConfigDto> list = baseManager.selectList(h5Config); | |||
| list.forEach(item-> { | |||
| 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()); | |||
| List<DmManDeviceDto> manDeviceDtos = dmManDeviceService.selectList(query).stream().filter(device -> device.getTId().equals(item.getEnterpriseId())).collect(Collectors.toList()); | |||
| if (!manDeviceDtos.isEmpty()) { | |||
| for (int i = 0; i < manDeviceDtos.size(); i++) { | |||
| DmManDeviceDto items = manDeviceDtos.get(i); | |||
| String streamUrl = items.getStreamUrl(); | |||
| if (!StringUtils.isEmpty(streamUrl)) { | |||
| DmH5ConfigDto temp = new DmH5ConfigDto(); | |||
| temp.setTenantName(items.getTenantName()); | |||
| temp.setManCode(items.getManCode()); | |||
| try { | |||
| String property = nacosConfigManager.getConfigService().getConfig(item.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| JSONObject jo = JSON.parseObject(property); | |||
| if (jo != null && jo.containsKey("system")) { | |||
| JSONObject sys = jo.getJSONObject("system"); | |||
| if (sys != null && sys.containsKey("H5")) { | |||
| JSONObject H5 = sys.getJSONObject("H5"); | |||
| H5.put("streamUrl", streamUrl); | |||
| } | |||
| } | |||
| temp.setProperty(jo.toString()); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表上传nacos-获取配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| temp.setEnterpriseId(item.getEnterpriseId()); | |||
| temp.setName(item.getName()); | |||
| temp.setId(item.getId()); | |||
| temp.setRemark(item.getRemark()); | |||
| temp.setStatus(item.getStatus()); | |||
| temp.setVersion(item.getVersion()); | |||
| temp.setCreateBy(item.getCreateBy()); | |||
| temp.setCreateTime(item.getCreateTime()); | |||
| temp.setUpdateBy(item.getUpdateBy()); | |||
| temp.setUpdateName(item.getUpdateName()); | |||
| temp.setUpdateTime(item.getUpdateTime()); | |||
| temp.setSourceName(item.getSourceName()); | |||
| temp.setSort(item.getSort()); | |||
| temp.setDelFlag(item.getDelFlag()); | |||
| temp.setParams(item.getParams()); | |||
| temp.setOperate(item.getOperate()); | |||
| temp.setCreateName(item.getCreateName()); | |||
| resultlist.add(temp); | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| return list; | |||
| return resultlist; | |||
| } | |||
| @Override | |||
| public int insert(DmH5ConfigDto dto) { | |||
| int row = 1; | |||
| // 设置新增配置文件名 | |||
| String[] strs = NacosConstants.DEFAULT_CONFIG_PATH.split("\\."); | |||
| dto.setName(strs[0] + "_" + dto.getEnterpriseId() + "." + strs[1]); | |||
| // 获取基础配置文件 | |||
| 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); | |||
| DmH5ConfigQuery query = new DmH5ConfigQuery(); | |||
| query.setEnterpriseId(dto.getEnterpriseId()); | |||
| List<DmH5ConfigDto> result = baseManager.selectList(query); | |||
| if (result.isEmpty()) { | |||
| String property = nacosConfigManager.getConfigService().getConfig(NacosConstants.DEFAULT_CONFIG_PATH, NacosConstants.DEFAULT_GROUP, 5000); | |||
| // 新增配置文件 | |||
| nacosConfigManager.getConfigService().publishConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, property); | |||
| row = super.insert(dto); | |||
| } | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表上传nacos-新增配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| return super.insert(dto); | |||
| strs = NacosConstants.DEFAULT_CONFIG_PATH.split("\\."); | |||
| dto.setName(strs[0] + "_" + dto.getEnterpriseId() + "." + strs[1]); | |||
| DmManDeviceQuery query = new DmManDeviceQuery(); | |||
| query.setManCode(dto.getManCode()); | |||
| List<DmManDeviceDto> mdList = dmManDeviceManager.selectList(query); | |||
| if (mdList != null && mdList.size() > 0) { | |||
| DmManDeviceDto target = mdList.get(0); | |||
| try { | |||
| String property = nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| JSONObject jo = JSON.parseObject(property); | |||
| if (jo != null && jo.containsKey("system")) { | |||
| JSONObject sys = jo.getJSONObject("system"); | |||
| if (sys != null && sys.containsKey("H5")) { | |||
| JSONObject H5 = sys.getJSONObject("H5"); | |||
| String streamUrl = H5.getString("streamUrl"); | |||
| target.setStreamUrl(streamUrl); | |||
| dmManDeviceManager.update(target); | |||
| } | |||
| } | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表上传nacos-新增配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| } | |||
| return row; | |||
| } | |||
| @Override | |||
| public int update(DmH5ConfigDto dto) { | |||
| String[] strs = NacosConstants.DEFAULT_CONFIG_PATH.split("\\."); | |||
| dto.setName(strs[0] + "_" + dto.getEnterpriseId() + "." + strs[1]); | |||
| try { | |||
| // 获取文件名 | |||
| nacosConfigManager.getConfigService().publishConfig(dto.getName(), NacosConstants.DEFAULT_GROUP,dto.getProperty()); | |||
| nacosConfigManager.getConfigService().publishConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, dto.getProperty()); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表上传nacos-修改配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| if (StringUtils.isEmpty(dto.getManCode())) { | |||
| return super.update(dto); | |||
| } | |||
| DmManDeviceQuery query = new DmManDeviceQuery(); | |||
| query.setManCode(dto.getManCode()); | |||
| List<DmManDeviceDto> mdList = dmManDeviceManager.selectList(query); | |||
| if (mdList != null && mdList.size() > 0) { | |||
| DmManDeviceDto target = mdList.get(0); | |||
| String property = dto.getProperty(); | |||
| JSONObject jo = JSON.parseObject(property); | |||
| if (jo != null && jo.containsKey("system")) { | |||
| JSONObject sys = jo.getJSONObject("system"); | |||
| if (sys != null && sys.containsKey("H5")) { | |||
| JSONObject H5 = sys.getJSONObject("H5"); | |||
| String streamUrl = H5.getString("streamUrl"); | |||
| target.setStreamUrl(streamUrl); | |||
| dmManDeviceManager.update(target); | |||
| } | |||
| } | |||
| } | |||
| return super.update(dto); | |||
| } | |||
| @@ -101,9 +204,40 @@ public class DmH5ConfigServiceImpl extends BaseServiceImpl<DmH5ConfigQuery, DmH5 | |||
| return dto; | |||
| } | |||
| public DmH5ConfigDto selectbyIdCode(Serializable id, String manCode) { | |||
| DmH5ConfigDto dto = super.selectById(id); | |||
| dto.setManCode(manCode); | |||
| String result = null; | |||
| try { | |||
| result = nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表nacos-获取配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| DmManDeviceQuery query = new DmManDeviceQuery(); | |||
| query.setManCode(manCode); | |||
| List<DmManDeviceDto> mdList = dmManDeviceManager.selectList(query); | |||
| if (mdList != null && mdList.size() > 0) { | |||
| String streamUrl = mdList.get(0).getStreamUrl(); | |||
| if (StringUtils.isEmpty(streamUrl)) { | |||
| return null; | |||
| } | |||
| JSONObject jo = JSON.parseObject(result); | |||
| if (jo != null && jo.containsKey("system")) { | |||
| JSONObject sys = jo.getJSONObject("system"); | |||
| if (sys != null && sys.containsKey("H5")) { | |||
| JSONObject H5 = sys.getJSONObject("H5"); | |||
| H5.put("streamUrl", streamUrl); | |||
| } | |||
| } | |||
| result = jo.toString(); | |||
| dto.setProperty(result); | |||
| } | |||
| return dto; | |||
| } | |||
| @Override | |||
| public String syncH5Config(Long tId) { | |||
| log.info("tenant_id:{}",tId); | |||
| public String syncH5Config(Long tId, String manCode) { | |||
| log.info("tenant_id:{}", tId); | |||
| if (tId == null) { | |||
| try { | |||
| return nacosConfigManager.getConfigService().getConfig(NacosConstants.DEFAULT_CONFIG_PATH, NacosConstants.DEFAULT_GROUP, 5000); | |||
| @@ -118,7 +252,32 @@ public class DmH5ConfigServiceImpl extends BaseServiceImpl<DmH5ConfigQuery, DmH5 | |||
| DmH5ConfigDto dto = list.get(0); | |||
| if (dto != null) { | |||
| try { | |||
| return nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| String result = ""; | |||
| result = nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| if (StringUtils.isEmpty(manCode)) { | |||
| return result; | |||
| } else { | |||
| DmManDeviceQuery query2 = new DmManDeviceQuery(); | |||
| query2.setManCode(manCode); | |||
| List<DmManDeviceDto> extList = dmManDeviceManager.selectList(query2); | |||
| if (extList != null && extList.size() > 0) { | |||
| String streamUrl = extList.get(0).getStreamUrl(); | |||
| if (!StringUtils.isEmpty(streamUrl)) { | |||
| JSONObject jo = JSON.parseObject(result); | |||
| if (jo != null && jo.containsKey("system")) { | |||
| JSONObject sys = jo.getJSONObject("system"); | |||
| if (sys != null && sys.containsKey("H5")) { | |||
| JSONObject H5 = sys.getJSONObject("H5"); | |||
| H5.put("streamUrl", streamUrl); | |||
| } | |||
| } | |||
| result = jo.toString(); | |||
| return result; | |||
| } else { | |||
| return result; | |||
| } | |||
| } | |||
| } | |||
| } catch (NacosException ne) { | |||
| log.error("H5同步-获取配置文件失败:{}", ne.getMessage()); | |||
| try { | |||
| @@ -137,4 +296,24 @@ public class DmH5ConfigServiceImpl extends BaseServiceImpl<DmH5ConfigQuery, DmH5 | |||
| } | |||
| return ""; | |||
| } | |||
| public int deleteByIdCode(Serializable id, String manCode) { | |||
| DmH5ConfigDto dto = super.selectById(id); | |||
| if (dto != null) { | |||
| try { | |||
| String result = nacosConfigManager.getConfigService().getConfig(dto.getName(), NacosConstants.DEFAULT_GROUP, 5000); | |||
| } catch (NacosException ne) { | |||
| log.error("H5配置表nacos-删除配置文件失败:{}", ne.getMessage()); | |||
| } | |||
| } | |||
| DmManDeviceQuery query = new DmManDeviceQuery(); | |||
| query.setManCode(manCode); | |||
| List<DmManDeviceDto> mdList = dmManDeviceManager.selectList(query); | |||
| if (mdList != null && mdList.size() > 0) { | |||
| DmManDeviceDto target = mdList.get(0); | |||
| target.setStreamUrl(""); | |||
| dmManDeviceManager.update(target); | |||
| } | |||
| return 1; | |||
| } | |||
| } | |||
| @@ -66,7 +66,7 @@ public class DmResourcesServiceImpl extends BaseServiceImpl<DmResourcesQuery, Dm | |||
| DmResourcesDto dmResourcesDto = new DmResourcesDto(); | |||
| if (StringUtils.isNotEmpty(base64Img)) { | |||
| String imgBase64 = base64Img; | |||
| R<SysFile> fileResult = fileService.upload(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| R<SysFile> fileResult = fileService.uploadFace(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return R.fail(fileResult.getMsg()); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -247,7 +247,7 @@ public class DmStaffController extends BaseController<DmStaffQuery, DmStaffDto, | |||
| if (!StrUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.IMAGE_EXTENSION) + "格式"); | |||
| } | |||
| R<SysFile> fileResult = remoteFileService.upload(file); | |||
| R<SysFile> fileResult = remoteFileService.uploadFace(file); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -137,7 +137,7 @@ public class DmVisitorsController extends BaseController<DmVisitorsQuery, DmVisi | |||
| if (!CharSequenceUtil.equalsAnyIgnoreCase(extension, MimeTypeUtil.IMAGE_EXTENSION)) { | |||
| return error("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtil.IMAGE_EXTENSION) + "格式"); | |||
| } | |||
| R<SysFile> fileResult = remoteFileService.upload(file); | |||
| R<SysFile> fileResult = remoteFileService.uploadFace(file); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return error("文件服务异常,请联系管理员!"); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -1,11 +1,22 @@ | |||
| package com.xueyi.system.staff.controller.api; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.common.cache.utils.SourceUtil; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.context.SecurityContextHolder; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.common.redis.utils.RedisUtil; | |||
| import com.xueyi.common.web.annotation.TenantIgnore; | |||
| import com.xueyi.system.api.device.domain.vo.DeviceTenantSourceMergeVo; | |||
| import com.xueyi.system.api.model.Source; | |||
| import com.xueyi.system.api.staff.domain.dto.DmStaffCommonDto; | |||
| import com.xueyi.system.api.staff.feign.RemoteStaffService; | |||
| import com.xueyi.system.resource.controller.api.BaseApiController; | |||
| import com.xueyi.system.staff.service.impl.DmStaffServiceImpl; | |||
| import com.xueyi.tenant.api.tenant.domain.dto.TeTenantDto; | |||
| import com.xueyi.tenant.api.tenant.feign.RemoteTenantService; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| @@ -15,6 +26,8 @@ import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.ResponseBody; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import java.util.List; | |||
| /** | |||
| * 员工管理 API业务处理 | |||
| * | |||
| @@ -24,9 +37,17 @@ import org.springframework.web.bind.annotation.RestController; | |||
| @RequestMapping("/staff/api") | |||
| public class DmStaffApiController extends BaseApiController { | |||
| private static final Logger log = LoggerFactory.getLogger(DmStaffApiController.class); | |||
| @Autowired | |||
| private RemoteStaffService staffService; | |||
| @Autowired | |||
| private DmStaffServiceImpl dmStaffService; | |||
| @Autowired | |||
| private RemoteTenantService tenantService; | |||
| @GetMapping(value = "fetchOne/{devId}/{staffId}") | |||
| @ResponseBody | |||
| public JSONObject fetchStaff(@PathVariable("devId") String devId, @PathVariable("staffId") String staffId){ | |||
| @@ -41,4 +62,40 @@ public class DmStaffApiController extends BaseApiController { | |||
| DeviceTenantSourceMergeVo vo = super.getDeviceTenantSourceMergeVo(commonDto.getDevId()); | |||
| return staffService.addStaff(commonDto, vo.getTenantId(), vo.getSourceSlave(), SecurityConstants.INNER); | |||
| } | |||
| @GetMapping(value = "broadcast-staff-count") | |||
| @ResponseBody | |||
| @TenantIgnore(tenantLine = true) | |||
| public JSONObject queryStaff(){ | |||
| SecurityContextHolder.set("sourceName", "slave"); | |||
| Long count = dmStaffService.selectStaffAndVisitorCount(); | |||
| return outputSuccess(count).toJSON(); | |||
| } | |||
| @GetMapping(value = "staff-count") | |||
| @ResponseBody | |||
| public JSONObject staffCount(){ | |||
| if (RedisUtil.existed("saas:staff:totalCountAndVisitor")){ | |||
| String str = RedisUtil.getVal("saas:staff:totalCountAndVisitor").toString(); | |||
| log.info("staff-count res:{}", str); | |||
| return JSONObject.parse(str); | |||
| } | |||
| R<List<TeTenantDto>> listR = tenantService.tenantList(); | |||
| if (listR.isFail()) { | |||
| System.out.println("租户列表获取失败"); | |||
| return null; | |||
| } | |||
| List<TeTenantDto> res = listR.getData(); | |||
| TeTenantDto teTenantDto = res.get(0); | |||
| if (teTenantDto != null) { | |||
| Source source = SourceUtil.getSourceCache(teTenantDto.getStrategyId()); | |||
| JSONObject countJson = staffService.queryStaffCount(teTenantDto.getId(), source.getMaster(), SecurityConstants.INNER); | |||
| RedisUtil.setVal("saas:staff:totalCountAndVisitor", countJson.toJSONString(), 60); | |||
| return countJson; | |||
| } | |||
| return outputSuccess().toJSON(); | |||
| } | |||
| } | |||
| @@ -18,6 +18,7 @@ import com.xueyi.system.resource.service.impl.DmResourcesServiceImpl; | |||
| import com.xueyi.system.resource.service.impl.FaceServiceImpl; | |||
| import com.xueyi.system.staff.mapper.DmStaffMapper; | |||
| import com.xueyi.system.staff.mapper.DmVisitorsMapper; | |||
| import com.xueyi.system.staff.service.impl.DmStaffServiceImpl; | |||
| import com.xueyi.system.utils.common.ImageUtil; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| @@ -58,6 +59,9 @@ public class DmStaffInnerApiController extends BaseApiController { | |||
| @Autowired | |||
| private DmStaffMapper staffMapper; | |||
| @Autowired | |||
| private DmStaffServiceImpl dmStaffService; | |||
| @InnerAuth | |||
| @GetMapping(value = "selectOne/{staffId}") | |||
| @ResponseBody | |||
| @@ -120,4 +124,12 @@ public class DmStaffInnerApiController extends BaseApiController { | |||
| return outputSuccess().toJSON(); | |||
| } | |||
| @InnerAuth | |||
| @GetMapping(value = "broadcast-staff-count") | |||
| @ResponseBody | |||
| public JSONObject queryStaff(){ | |||
| Long count = dmStaffService.selectStaffAndVisitorCount(); | |||
| return outputSuccess(count).toJSON(); | |||
| } | |||
| } | |||
| @@ -179,7 +179,7 @@ public class DmVisitorInnerApiController extends BaseApiController { | |||
| //兼容熟人介绍生人,传递访客照片 | |||
| if (StringUtils.isNotEmpty(commonDto.getVisitorBase64Img())) { | |||
| String imgBase64 = commonDto.getVisitorBase64Img(); | |||
| R<SysFile> fileResult = fileService.upload(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| R<SysFile> fileResult = fileService.uploadFace(imageUtil.base64ToMultipartFile(imgBase64)); | |||
| if (ObjectUtil.isNull(fileResult) || ObjectUtil.isNull(fileResult.getData())) | |||
| return output(ResponseCode.FILE_SERVICE_ERROR).toJSON(); | |||
| String url = fileResult.getData().getUrl(); | |||
| @@ -1,11 +1,11 @@ | |||
| package com.xueyi.system.staff.mapper; | |||
| import com.xueyi.common.datasource.annotation.Isolate; | |||
| import com.xueyi.common.web.entity.mapper.BaseMapper; | |||
| import com.xueyi.system.api.staff.domain.dto.DmStaffDto; | |||
| import com.xueyi.system.api.staff.domain.po.DmStaffPo; | |||
| import com.xueyi.system.staff.domain.query.DmStaffQuery; | |||
| import com.xueyi.common.web.entity.mapper.BaseMapper; | |||
| import com.xueyi.common.datasource.annotation.Isolate; | |||
| import com.xueyi.system.api.staff.domain.vo.DmStaffFeature; | |||
| import com.xueyi.system.staff.domain.query.DmStaffQuery; | |||
| import org.apache.ibatis.annotations.Param; | |||
| import java.util.List; | |||
| @@ -21,4 +21,8 @@ public interface DmStaffMapper extends BaseMapper<DmStaffQuery, DmStaffDto, DmSt | |||
| public List<DmStaffFeature> selectStaffFeaturesList(@Param("devId")String devId,@Param("timestamp") String timestamp); | |||
| public List<DmStaffFeature> selectVisitorFeaturesList(@Param("devId")String devId,@Param("timestamp") String timestamp); | |||
| public Integer getStaffCount(); | |||
| public Integer getVisitorCount(); | |||
| } | |||
| @@ -20,4 +20,6 @@ public interface IDmStaffService extends IBaseService<DmStaffQuery, DmStaffDto> | |||
| Long selectTenantId(DmStaffPo staff); | |||
| List<DmStaffFeature> selectStaffListByTimestamp(String devId,String tempstamp); | |||
| Long selectStaffAndVisitorCount(); | |||
| } | |||
| @@ -3,18 +3,18 @@ package com.xueyi.system.staff.service.impl; | |||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| import com.xueyi.common.web.annotation.TenantIgnore; | |||
| import com.xueyi.common.web.entity.service.impl.BaseServiceImpl; | |||
| import com.xueyi.common.web.utils.DateUtils; | |||
| import com.xueyi.system.api.pass.domain.po.DmRecognizedRecordsPo; | |||
| import com.xueyi.system.api.staff.domain.dto.DmStaffDto; | |||
| import com.xueyi.system.api.staff.domain.po.DmStaffPo; | |||
| import com.xueyi.system.api.staff.domain.vo.DmStaffFeature; | |||
| import com.xueyi.system.staff.domain.po.DmEmpAttendancePo; | |||
| import com.xueyi.system.staff.mapper.DmEmpAttendanceMapper; | |||
| import com.xueyi.system.staff.domain.query.DmStaffQuery; | |||
| import com.xueyi.system.api.staff.domain.vo.DmStaffFeature; | |||
| import com.xueyi.system.staff.manager.IDmStaffManager; | |||
| import com.xueyi.system.staff.mapper.DmEmpAttendanceMapper; | |||
| import com.xueyi.system.staff.mapper.DmStaffMapper; | |||
| import com.xueyi.system.staff.service.IDmStaffService; | |||
| import com.xueyi.common.web.entity.service.impl.BaseServiceImpl; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| @@ -49,6 +49,8 @@ public class DmStaffServiceImpl extends BaseServiceImpl<DmStaffQuery, DmStaffDto | |||
| return baseManager.selectList(dmStaff); | |||
| } | |||
| @Override | |||
| @TenantIgnore(tenantLine = true) | |||
| public List<DmStaffPo> selectStaffList(DmStaffPo staff) { | |||
| @@ -76,6 +78,16 @@ public class DmStaffServiceImpl extends BaseServiceImpl<DmStaffQuery, DmStaffDto | |||
| return staffFeatures; | |||
| } | |||
| @Override | |||
| @TenantIgnore(tenantLine = true) | |||
| public Long selectStaffAndVisitorCount() { | |||
| Integer staffCount = staffMapper.getStaffCount(); | |||
| Integer visitorCount = staffMapper.getStaffCount(); | |||
| Integer totalCount = staffCount + visitorCount; | |||
| return totalCount.longValue(); | |||
| } | |||
| public void updateOrInsertAttendance(DmRecognizedRecordsPo checkRecords) { | |||
| if (null == checkRecords.getUserId()) { | |||
| @@ -43,7 +43,6 @@ public class DmVisitRecordsServiceImpl extends BaseServiceImpl<DmVisitRecordsQue | |||
| e.printStackTrace(); | |||
| }*/ | |||
| String timeStr = String.valueOf(System.currentTimeMillis()); | |||
| timeStr.substring(timeStr.length() - 4 ); | |||
| return timeStr.substring(timeStr.length() - 4 ); | |||
| } | |||
| @@ -33,4 +33,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
| select s.id, s.name ,s.type as user_type, s.update_time,s.nickname as nick_name, s.del_flag, r.feature from dm_visitors s left join dm_resources as r on s.resource_id = r.id | |||
| where (UNIX_TIMESTAMP(s.update_time) * 1000 > #{timestamp} or UNIX_TIMESTAMP(s.create_time) * 1000 > #{timestamp} )and r.feature is not null | |||
| </select> | |||
| <select id="getStaffCount" resultType="java.lang.Integer"> | |||
| select count(*) from dm_staff where del_flag = 0 | |||
| </select> | |||
| <select id="getVisitorCount" resultType="java.lang.Integer"> | |||
| select count(*) from dm_visitors where del_flag = 0 | |||
| </select> | |||
| </mapper> | |||