Quellcode durchsuchen

fix 修复了一些bug

A17404李放 vor 3 Jahren
Ursprung
Commit
81a7aa161e
22 geänderte Dateien mit 858 neuen und 19 gelöschten Zeilen
  1. 7 6
      coffee-admin/src/main/java/com/coffee/admin/controller/common/CommonController.java
  2. 4 4
      coffee-admin/src/main/resources/application-dev.yml
  3. 38 0
      coffee-admin/src/test/java/com/coffee/admin/FileUploadTest.java
  4. 412 0
      coffee-common/src/main/java/com/coffee/common/util/FileUtil.java
  5. 1 1
      coffee-common/src/main/java/com/coffee/common/util/MinioUtil.java
  6. 4 0
      coffee-common/src/main/java/com/coffee/common/util/SecurityUtil.java
  7. 2 0
      coffee-framework/src/main/java/com/coffee/framework/config/SaTokenConfig.java
  8. 2 1
      coffee-oss/src/main/java/com/coffee/oss/strategy/FileStorageStrategy.java
  9. 2 1
      coffee-oss/src/main/java/com/coffee/oss/strategy/impl/AliyunStorageStrategy.java
  10. 25 3
      coffee-oss/src/main/java/com/coffee/oss/strategy/impl/MinioStorageStrategy.java
  11. 30 0
      coffee-oss/src/main/java/com/coffee/oss/strategy/storage/LocalSysStorageService.java
  12. 76 0
      coffee-oss/src/main/java/com/coffee/oss/strategy/storage/SysStorage.java
  13. 16 0
      coffee-oss/src/main/java/com/coffee/oss/strategy/storage/mapper/SysLocalStorageMapper.java
  14. 72 0
      coffee-system/src/main/java/com/coffee/bus/controller/BusAppController.java
  15. 3 0
      coffee-system/src/main/java/com/coffee/bus/controller/BusHospitalController.java
  16. 74 0
      coffee-system/src/main/java/com/coffee/bus/entity/BusAppConfig.java
  17. 31 0
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusAppConfigService.java
  18. 9 0
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusEvaluationService.java
  19. 31 0
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusHospitalService.java
  20. 2 2
      coffee-system/src/main/java/com/coffee/bus/service/LocalBusInfusionHistoryService.java
  21. 16 0
      coffee-system/src/main/java/com/coffee/system/mapper/SysAppConfigMapper.java
  22. 1 1
      coffee-system/src/main/resources/mapper/bus/BusInfusionHistoryMapper.xml

+ 7 - 6
coffee-admin/src/main/java/com/coffee/admin/controller/common/CommonController.java

@@ -8,6 +8,7 @@ import com.coffee.common.result.R;
 import com.coffee.common.result.ResultCode;
 import com.coffee.oss.strategy.FileStorageStrategy;
 import com.coffee.oss.strategy.context.FileStorageContext;
+import com.coffee.oss.strategy.storage.SysStorage;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
@@ -70,19 +71,19 @@ public class CommonController {
 
     @PostMapping("/upload")
     @SneakyThrows
-    public R upload(MultipartFile file, HttpServletRequest request) {
-        String bizPath = request.getParameter("bizPath");
+    public R<SysStorage> upload(@RequestParam("file") MultipartFile file, @RequestParam("file") String bizPath) {
         if (StrUtil.isBlank(bizPath)) {
-            throw new CustomException(ResultCode.PARAM_MISS.getMessage());
+            throw new CustomException(ResultCode.PARAM_TYPE_ERROR.getMessage());
         }
         if (Objects.isNull(file)) {
-            throw new CustomException(ResultCode.PARAM_MISS.getMessage());
+            throw new CustomException(ResultCode.PARAM_TYPE_ERROR.getMessage());
         }
         FileStorageStrategy fileStorageStrategy = fileStorageContext.getContext();
-        String url = fileStorageStrategy.upload(file, bizPath);
-        return R.success(url);
+        SysStorage storage = fileStorageStrategy.upload(file, bizPath);
+        return R.success(storage);
     }
 
+
     @GetMapping("/download")
     @SneakyThrows
     public void download(@RequestParam String filepath, HttpServletResponse response) {

+ 4 - 4
coffee-admin/src/main/resources/application-dev.yml

@@ -1,7 +1,7 @@
 # 项目相关配置
 app:
   # 项目名称
-  name: coffee
+  name: nbnetpump
   # 实例演示开关
   demoEnabled: false
   # 获取ip地址开关
@@ -15,9 +15,9 @@ app:
 
 # MinIO相关配置
 minio:
-  endpoint: http://127.0.0.1:9000
-  accessKey: minioadmin
-  secretKey: minioadmin
+  endpoint: http://192.168.100.32:7001
+  accessKey: nbnetpump
+  secretKey: tuoren123
   bucketName: ${app.name}-${profiles.active}-bucket
 
 # 数据源配置

+ 38 - 0
coffee-admin/src/test/java/com/coffee/admin/FileUploadTest.java

@@ -0,0 +1,38 @@
+package com.coffee.admin;
+
+import cn.hutool.core.io.FileUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.coffee.bus.entity.BusDeviceEntity;
+import com.coffee.bus.entity.BusDeviceRunningEntity;
+import com.coffee.bus.entity.BusInfusionHistoryEntity;
+import com.coffee.bus.listener.event.bean.DeviceInfoEvent;
+import com.coffee.bus.service.LocalBusDeviceService;
+import com.coffee.bus.service.LocalBusInfusionHistoryService;
+import com.coffee.common.util.MinioUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+/**
+ * @Author longsanlang
+ * @Date 2022-04-06 17:55:44
+ * @Version 1.0
+ * @Description XXX
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = AdminApplication.class)
+public class FileUploadTest {
+    @Autowired
+    MinioUtil minioUtil;
+
+    @Test
+    public void upload(){
+        String s = minioUtil.uploadObject(FileUtil.getInputStream(FileUtil.file("C:\\Users\\JR\\Desktop\\新疆患者数据.xls")), "/docker-compose.yml");
+        System.out.println(s);
+    }
+}

+ 412 - 0
coffee-common/src/main/java/com/coffee/common/util/FileUtil.java

@@ -0,0 +1,412 @@
+/*
+ *  Copyright 2019-2020 Zheng Jie
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.coffee.common.util;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.poi.excel.BigExcelWriter;
+import cn.hutool.poi.excel.ExcelUtil;
+import cn.hutool.poi.excel.ExcelWriter;
+import com.coffee.common.exception.CustomException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.util.IOUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.security.MessageDigest;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * File工具类,扩展 hutool 工具包
+ * @author Zheng Jie
+ * @date 2018-12-27
+ */
+@Slf4j
+public class FileUtil extends cn.hutool.core.io.FileUtil {
+
+    /**
+     * 定义GB的计算常量
+     */
+    private static final int GB = 1024 * 1024 * 1024;
+    /**
+     * 定义MB的计算常量
+     */
+    private static final int MB = 1024 * 1024;
+    /**
+     * 定义KB的计算常量
+     */
+    private static final int KB = 1024;
+
+    /**
+     * 格式化小数
+     */
+    private static final DecimalFormat DF = new DecimalFormat("0.00");
+
+    /**
+     * MultipartFile转File
+     */
+    public static File toFile(MultipartFile multipartFile){
+        return toFile(multipartFile,"");
+    }
+
+    /**
+     * MultipartFile转File
+     */
+    public static File toFile(MultipartFile multipartFile, String prefixName){
+        // 获取文件名
+        String fileName = multipartFile.getOriginalFilename();
+        // 获取文件后缀
+        String suffix="."+getExtensionName(fileName);
+        File file = null;
+        try {
+            // 用uuid作为文件名,防止生成的临时文件重复
+            file = FileUtil.file(prefixName+ IdUtil.simpleUUID()+suffix);
+            // MultipartFile to File
+            multipartFile.transferTo(file);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return file;
+    }
+
+    /**
+     * 获取文件扩展名,不带 .
+     */
+    public static String getExtensionName(String filename) {
+        if ((filename != null) && (filename.length() > 0)) {
+            int dot = filename.lastIndexOf('.');
+            if ((dot >-1) && (dot < (filename.length() - 1))) {
+                return filename.substring(dot + 1);
+            }
+        }
+        return filename;
+    }
+
+    /**
+     * Java文件操作 获取不带扩展名的文件名
+     */
+    public static String getFileNameNoEx(String filename) {
+        if ((filename != null) && (filename.length() > 0)) {
+            int dot = filename.lastIndexOf('.');
+            if ((dot >-1) && (dot < (filename.length()))) {
+                return filename.substring(0, dot);
+            }
+        }
+        return filename;
+    }
+
+    /**
+     * 文件大小转换
+     */
+    public static String getSize(long size){
+        String resultSize;
+        if (size / GB >= 1) {
+            //如果当前Byte的值大于等于1GB
+            resultSize = DF.format(size / (float) GB) + "GB   ";
+        } else if (size / MB >= 1) {
+            //如果当前Byte的值大于等于1MB
+            resultSize = DF.format(size / (float) MB) + "MB   ";
+        } else if (size / KB >= 1) {
+            //如果当前Byte的值大于等于1KB
+            resultSize = DF.format(size / (float) KB) + "KB   ";
+        } else {
+            resultSize = size + "B   ";
+        }
+        return resultSize;
+    }
+
+    /**
+     * 将文件名解析成文件的上传路径
+     */
+    public static File upload(MultipartFile file, String filePath) {
+        Date date = new Date();
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
+        String name = getFileNameNoEx(file.getOriginalFilename());
+        String suffix = getExtensionName(file.getOriginalFilename());
+        String nowStr = "-" + format.format(date);
+        try {
+            String fileName = name + nowStr + "." + suffix;
+            String path = filePath + fileName;
+            // getCanonicalFile 可解析正确各种路径
+//            File dest = new File(path).getCanonicalFile();
+            log.info("上传文件路径为:{}",path);
+            File    dest= cn.hutool.core.io.FileUtil.touch(path);
+            // 检测是否存在目录
+//
+//            if (!dest.getParentFile().exists()) {
+//
+////                if (!dest.getParentFile().mkdirs()) {
+////                    System.out.println("was not successful.>>>>>"+dest.getPath());
+////                }
+//            }
+            // 文件写入
+            file.transferTo(dest);
+            return dest;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 导出excel
+     */
+    public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {
+        String tempPath =System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx";
+        File file = new File(tempPath);
+        BigExcelWriter writer= ExcelUtil.getBigWriter(file);
+        // 一次性写出内容,使用默认样式,强制输出标题
+        writer.write(list, true);
+        //response为HttpServletResponse对象
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
+        //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
+        response.setHeader("Content-Disposition","attachment;filename=file.xlsx");
+        ServletOutputStream out=response.getOutputStream();
+        // 终止后删除临时文件
+        file.deleteOnExit();
+        writer.flush(out, true);
+        //此处记得关闭输出Servlet流
+        IoUtil.close(out);
+    }
+
+
+    /**
+     * 导出excel
+     */
+    public static void downloadExcel(ExcelWriter writer, HttpServletResponse response) throws IOException {
+        //response为HttpServletResponse对象
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
+        //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
+        response.setHeader("Content-Disposition","attachment;filename=file.xlsx");
+        ServletOutputStream out=response.getOutputStream();
+        writer.flush(out, true);
+        //此处记得关闭输出Servlet流
+        IoUtil.close(out);
+    }
+
+    public static String getFileType(String type) {
+        String documents = "txt doc pdf ppt pps xlsx xls docx";
+        String music = "mp3 wav wma mpa ram ra aac aif m4a";
+        String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";
+        String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
+        if(image.contains(type)){
+            //图片
+            return "image";
+        } else if(documents.contains(type)){
+            //文档
+            return "doc";
+        } else if(music.contains(type)){
+            //音乐
+            return "music";
+        } else if(video.contains(type)){
+            //视频
+            return "video";
+        } else {
+            //其他
+            return "else";
+        }
+    }
+
+    public static void checkSize(long maxSize, long size) {
+        long len = 1024 * 1024*maxSize;
+        if(size > (maxSize * len)){
+            throw new CustomException("文件超出"+maxSize+"M");
+        }
+    }
+
+    /**
+     * 判断两个文件是否相同
+     */
+    public static boolean check(File file1, File file2) {
+        String img1Md5 = getMd5(file1);
+        String img2Md5 = getMd5(file2);
+        return img1Md5.equals(img2Md5);
+    }
+
+    /**
+     * 判断两个文件是否相同
+     */
+    public static boolean check(String file1Md5, String file2Md5) {
+        return file1Md5.equals(file2Md5);
+    }
+
+    @SuppressWarnings("resource")
+    private static byte[] getByte(File file) {
+        // 得到文件长度
+        byte[] b = new byte[(int) file.length()];
+        try {
+            InputStream in = new FileInputStream(file);
+            try {
+                System.out.println(in.read(b));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            return null;
+        }
+        return b;
+    }
+
+    private static String getMd5(byte[] bytes) {
+        // 16进制字符
+        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+        try {
+            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
+            mdTemp.update(bytes);
+            byte[] md = mdTemp.digest();
+            int j = md.length;
+            char[] str = new char[j * 2];
+            int k = 0;
+            // 移位 输出字符串
+            for (byte byte0 : md) {
+                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
+                str[k++] = hexDigits[byte0 & 0xf];
+            }
+            return new String(str);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 下载文件
+     * @param request /
+     * @param response /
+     * @param file /
+     */
+    public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit){
+        response.setCharacterEncoding(request.getCharacterEncoding());
+        response.setContentType("application/octet-stream");
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(file);
+            response.setHeader("Content-Disposition", "attachment; filename="+file.getName());
+            IOUtils.copy(fis,response.getOutputStream());
+            response.flushBuffer();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                    if(deleteOnExit){
+                        file.deleteOnExit();
+                    }
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 下载文件
+     * @param request /
+     * @param response /
+     * @param  /
+     */
+    public static void downloadFile(HttpServletRequest request, HttpServletResponse response, InputStream in, String filename){
+        response.setCharacterEncoding(request.getCharacterEncoding());
+        response.setContentType("application/octet-stream");
+        BufferedInputStream fis = null;
+        try {
+            response.setHeader("Content-Disposition", "attachment; filename="+filename);
+            IOUtils.copy(in,response.getOutputStream());
+            response.flushBuffer();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    public static String getMd5(File file) {
+        return getMd5(getByte(file));
+    }
+
+
+    public static void zipFiles(File[] srcfile,File zipfile){
+        byte[] buf=new byte[1024];
+        try {
+            //ZipOutputStream类:完成文件或文件夹的压缩
+            ZipOutputStream out=new ZipOutputStream(new FileOutputStream(zipfile));
+            for(int i=0;i<srcfile.length;i++){
+                FileInputStream in=new FileInputStream(srcfile[i]);
+                out.putNextEntry(new ZipEntry(srcfile[i].getName()));
+                int len;
+                while((len=in.read(buf))!=0){
+                    out.write(buf,0,len);
+                }
+                out.closeEntry();
+                in.close();
+            }
+            out.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 迭代方式进行文件压缩
+     * @param file
+     * @param fileName
+     * @param outputStream
+     * @throws IOException
+     */
+    public static void compressFile(File file, String fileName, final ZipOutputStream outputStream) throws IOException {
+        //如果是目录
+        if (file.isDirectory()) {
+            //创建文件夹
+            outputStream.putNextEntry(new ZipEntry(fileName + "/"));
+            //迭代判断,并且加入对应文件路径
+            File[] files = file.listFiles();
+            Iterator<File> iterator = Arrays.asList(files).iterator();
+            while (iterator.hasNext()) {
+                File f = iterator.next();
+                compressFile(f, fileName + "/" + f.getName(), outputStream);
+            }
+        } else {
+            //创建文件
+            outputStream.putNextEntry(new ZipEntry(fileName));
+            //读取文件并写出
+            FileInputStream fileInputStream = new FileInputStream(file);
+            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
+            byte[] bytes = new byte[1024];
+            int n;
+            while ((n = bufferedInputStream.read(bytes)) != -1) {
+                outputStream.write(bytes, 0, n);
+            }
+            //关闭流
+            fileInputStream.close();
+            bufferedInputStream.close();
+        }
+    }
+}

+ 1 - 1
coffee-common/src/main/java/com/coffee/common/util/MinioUtil.java

@@ -46,7 +46,7 @@ public class MinioUtil {
             }
             PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                     .bucket(minioConfig.getBucketName())
-                    .object(filepath.substring(1))
+                    .object(filepath.startsWith("/")?filepath.substring(1):filepath)
                     .contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE)
                     .stream(stream, stream.available(), -1).build();
             minioClient.putObject(putObjectArgs);

+ 4 - 0
coffee-common/src/main/java/com/coffee/common/util/SecurityUtil.java

@@ -1,5 +1,6 @@
 package com.coffee.common.util;
 
+import cn.dev33.satoken.spring.SpringMVCUtil;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
@@ -49,6 +50,9 @@ public class SecurityUtil {
         return Boolean.TRUE.equals(getLoginUser().getIsSys());
     }
 
+    public static String getTenantId(){
+        return String.valueOf(SpringMVCUtil.getRequest().getAttribute("tenantId"));
+    }
     /**
      * 是否是超级管理员
      **/

+ 2 - 0
coffee-framework/src/main/java/com/coffee/framework/config/SaTokenConfig.java

@@ -32,6 +32,8 @@ public class SaTokenConfig {
     private static final List<String> IGNORE_URL = Lists.newArrayList();
 
     static {
+        IGNORE_URL.add("/app/favicon.ico");
+        IGNORE_URL.add("/sys/app/get");
         IGNORE_URL.add("/index");
         IGNORE_URL.add("/login");
         IGNORE_URL.add("/logout");

+ 2 - 1
coffee-oss/src/main/java/com/coffee/oss/strategy/FileStorageStrategy.java

@@ -1,5 +1,6 @@
 package com.coffee.oss.strategy;
 
+import com.coffee.oss.strategy.storage.SysStorage;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
@@ -43,6 +44,6 @@ public interface FileStorageStrategy {
      * @return
      * @throws IOException
      */
-    String upload(MultipartFile file, String bizPath) throws IOException;
+    SysStorage upload(MultipartFile file, String bizPath) throws IOException;
 
 }

+ 2 - 1
coffee-oss/src/main/java/com/coffee/oss/strategy/impl/AliyunStorageStrategy.java

@@ -1,6 +1,7 @@
 package com.coffee.oss.strategy.impl;
 
 import com.coffee.common.enums.FileStorageStrategyEnum;
+import com.coffee.oss.strategy.storage.SysStorage;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -19,7 +20,7 @@ public class AliyunStorageStrategy extends AbstractFileStorage {
 
 
     @Override
-    public String upload(MultipartFile file, String bizPath) {
+    public SysStorage upload(MultipartFile file, String bizPath) {
         return null;
     }
 }

+ 25 - 3
coffee-oss/src/main/java/com/coffee/oss/strategy/impl/MinioStorageStrategy.java

@@ -1,7 +1,12 @@
 package com.coffee.oss.strategy.impl;
 
+import cn.hutool.core.text.CharSequenceUtil;
+import com.coffee.common.config.MinioConfig;
 import com.coffee.common.enums.FileStorageStrategyEnum;
+import com.coffee.common.util.FileUtil;
 import com.coffee.common.util.MinioUtil;
+import com.coffee.oss.strategy.storage.LocalSysStorageService;
+import com.coffee.oss.strategy.storage.SysStorage;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
@@ -21,20 +26,37 @@ public class MinioStorageStrategy extends AbstractFileStorage {
     @Resource
     MinioUtil minioUtils;
 
+    @Resource
+    LocalSysStorageService sysStorageService;
+
+    @Resource
+    MinioConfig minioConfig;
+
     @Override
     public String getStrategyName() {
         return FileStorageStrategyEnum.MINIO.name();
     }
 
     @Override
-    public String upload(MultipartFile file, String bizPath) throws IOException {
+    public SysStorage upload(MultipartFile file, String bizPath) throws IOException {
         // 校验文件
         this.checkFile(file);
+        String suffix = FileUtil.getExtensionName(file.getOriginalFilename());
+        String name =file.getName();
+        String type = FileUtil.getFileType(suffix);
         String filepath = this.getFilepath(file, bizPath);
+        String url = minioUtils.uploadObject(file.getInputStream(), filepath);
+        name = CharSequenceUtil.isBlank(name) ? FileUtil.getFileNameNoEx(file.getOriginalFilename()) : name;
+
+        SysStorage localStorage = new SysStorage(file.getName(), name, suffix,url, type,
+                FileUtil.getSize(file.getSize()));
+
+        sysStorageService.save(localStorage);
+
         log.info("上传文件原始名称:{}", file.getOriginalFilename());
         log.info("上传文件路径:{}", filepath);
-        String url = minioUtils.uploadObject(file.getInputStream(), filepath);
+
         log.info("上传文件URL:{}", url);
-        return url;
+        return localStorage;
     }
 }

+ 30 - 0
coffee-oss/src/main/java/com/coffee/oss/strategy/storage/LocalSysStorageService.java

@@ -0,0 +1,30 @@
+package com.coffee.oss.strategy.storage;
+
+import com.coffee.common.crud.BaseService;
+import com.coffee.oss.strategy.storage.mapper.SysLocalStorageMapper;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName LocalSysStorageService.java
+ * @Description TODO
+ * @createTime 2022年06月24日 14:31:00
+ */
+@Service
+public class LocalSysStorageService extends BaseService<SysLocalStorageMapper, SysStorage,String> {
+    @Override
+    public void validateBeforeSave(SysStorage entity) {
+
+    }
+
+    @Override
+    public void validateBeforeUpdate(SysStorage entity) {
+
+    }
+
+    @Override
+    public void validateBeforeDelete(String id) {
+
+    }
+}

+ 76 - 0
coffee-oss/src/main/java/com/coffee/oss/strategy/storage/SysStorage.java

@@ -0,0 +1,76 @@
+/*
+ *  Copyright 2019-2020 Fang Jin Biao
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.coffee.oss.strategy.storage;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.coffee.common.entity.GenericEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author adyfang
+ * @date 2020年5月4日
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("sys_storage")
+@ApiModel(value = "存储对象", description = "本地存储")
+public class SysStorage extends GenericEntity<String> implements Serializable {
+    private static final long serialVersionUID = -4784057124954100795L;
+
+    private String realName;
+
+    @ApiModelProperty(value = "文件名")
+    private String name;
+
+    @ApiModelProperty(value = "后缀")
+    private String suffix;
+
+    @ApiModelProperty(value = "路径")
+    private String path;
+
+    @ApiModelProperty(value = "类型")
+    private String type;
+
+    @ApiModelProperty(value = "大小")
+    private String size;
+
+    @ApiModelProperty("版本号")
+    private String version;
+
+    public SysStorage(String realName, String name, String suffix, String path, String type, String size) {
+        new SysStorage(realName,name,suffix,path,type,size,null);
+    }
+
+    public SysStorage(String realName, String name, String suffix, String path, String type, String size,String version) {
+        this.realName = realName;
+        this.name = name;
+        this.suffix = suffix;
+        this.path = path;
+        this.type = type;
+        this.size = size;
+        this.version=version;
+    }
+}

+ 16 - 0
coffee-oss/src/main/java/com/coffee/oss/strategy/storage/mapper/SysLocalStorageMapper.java

@@ -0,0 +1,16 @@
+package com.coffee.oss.strategy.storage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.coffee.oss.strategy.storage.SysStorage;
+
+/**
+ * <p>
+ * 系统配置 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+public interface SysLocalStorageMapper extends BaseMapper<SysStorage> {
+
+}

+ 72 - 0
coffee-system/src/main/java/com/coffee/bus/controller/BusAppController.java

@@ -0,0 +1,72 @@
+package com.coffee.bus.controller;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.hutool.core.text.CharSequenceUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.Mapper;
+import com.coffee.common.crud.BaseService;
+import com.coffee.common.crud.controller.BaseQueryController;
+import com.coffee.common.crud.controller.BaseSaveController;
+import com.coffee.common.result.R;
+import com.coffee.bus.entity.BusAppConfig;
+import com.coffee.bus.service.LocalBusAppConfigService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName SysAppController.java
+ * @Description TODO
+ * @createTime 2022年06月24日 15:02:00
+ */
+@RestController
+@RequestMapping("/bus/app")
+@Api(tags = "app安装包管理",description="app安装包管理")
+public class BusAppController implements BaseQueryController<BusAppConfig,String>, BaseSaveController<BusAppConfig,String> {
+    @Resource
+    private LocalBusAppConfigService appConfigService;
+
+
+    @GetMapping("/last")
+    @ApiOperation(value="查看最新的安装包信息")
+    public R get() {
+        return R.success(appConfigService.getOne(new QueryWrapper<BusAppConfig>().lambda().last("limit 1")));
+    }
+
+
+
+    @PostMapping
+    @SaCheckPermission("bus:app:save")
+    @ApiOperation(value="上传安装包",notes = "权限【bus:app:save】")
+    public R save(@RequestBody BusAppConfig busAppConfig) {
+        if(CharSequenceUtil.isAllBlank(busAppConfig.getId())){
+            BusAppConfig exist = appConfigService.getOne(new QueryWrapper<BusAppConfig>().lambda().last("limit 1"));
+            if(exist!=null){
+                busAppConfig.setId(exist.getId());
+            }
+        }
+        appConfigService.saveOrUpdate(busAppConfig);
+        return R.success();
+    }
+
+    @Override
+    public BaseService<? extends Mapper<BusAppConfig>, BusAppConfig, String> getService() {
+        return appConfigService;
+    }
+
+    @Override
+    public String getPermissionPrefix() {
+        return "bus:app";
+    }
+
+    @Override
+    public StpLogic getStpLogin() {
+        return SaManager.getStpLogic("");
+    }
+}

+ 3 - 0
coffee-system/src/main/java/com/coffee/bus/controller/BusHospitalController.java

@@ -142,4 +142,7 @@ public class BusHospitalController extends BaseCrudController<BusHospitalEntity,
                         BusHospitalEntity::getUpdateConfig)
                 .eq(BusHospitalEntity::getId,id)));
     }
+
+
+
 }

+ 74 - 0
coffee-system/src/main/java/com/coffee/bus/entity/BusAppConfig.java

@@ -0,0 +1,74 @@
+package com.coffee.bus.entity;
+
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.coffee.common.entity.GenericEntity;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 行政区域
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-08-08
+ */
+@Data
+@TableName("sys_app_config")
+public class BusAppConfig extends GenericEntity<String> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * app名称
+     */
+    @NotNull(message = "名称不能为空")
+    @ApiModelProperty("安装包名称")
+    private String name;
+
+    /**
+     * 存储id
+     */
+    @NotNull(message = "文件路径不能为空",groups = Insert.class)
+    @ApiModelProperty("安装包存储url")
+    private String url;
+
+    /**
+     * 版本号
+     */
+    @NotNull(message = "版本号不能为空")
+    @ApiModelProperty("安装包版本号")
+    private String version;
+
+    /**
+     * 版本号
+     */
+    @NotNull(message = "版本号不能为空")
+    @ApiModelProperty("版本号名称")
+    private String versionName;
+
+    /**
+     * 版本号
+     */
+    @NotNull(message = "版本号不能为空")
+    @ApiModelProperty("apk大小")
+    private String apkSize;
+
+    /**
+     * 版本号
+     */
+    @NotNull(message = "版本号不能为空")
+    @ApiModelProperty("apkMd5")
+    private String apkMd5;
+
+}

+ 31 - 0
coffee-system/src/main/java/com/coffee/bus/service/LocalBusAppConfigService.java

@@ -0,0 +1,31 @@
+package com.coffee.bus.service;
+
+import com.coffee.common.crud.BaseService;
+import com.coffee.bus.entity.BusAppConfig;
+import com.coffee.system.mapper.SysAppConfigMapper;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName LocalSysAppConfigService.java
+ * @Description TODO
+ * @createTime 2022年06月24日 15:08:00
+ */
+@Service
+public class LocalBusAppConfigService extends BaseService<SysAppConfigMapper, BusAppConfig,String> {
+    @Override
+    public void validateBeforeSave(BusAppConfig entity) {
+
+    }
+
+    @Override
+    public void validateBeforeUpdate(BusAppConfig entity) {
+
+    }
+
+    @Override
+    public void validateBeforeDelete(String id) {
+
+    }
+}

+ 9 - 0
coffee-system/src/main/java/com/coffee/bus/service/LocalBusEvaluationService.java

@@ -1,5 +1,6 @@
 package com.coffee.bus.service;
 
+import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -8,6 +9,7 @@ import com.coffee.bus.entity.BusClinicEntity;
 import com.coffee.bus.entity.BusEvaluationEntity;
 import com.coffee.bus.mapper.BusEvaluationMapper;
 import com.coffee.bus.service.dto.EvalQuery;
+import com.coffee.bus.utils.WsPublishUtils;
 import com.coffee.common.crud.BaseService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
@@ -30,6 +32,10 @@ public class LocalBusEvaluationService extends BaseService<BusEvaluationMapper,
     @Lazy
     private LocalBusClinicService clinicService;
 
+    @Autowired
+    @Lazy
+    private WsPublishUtils wsPublishUtils;
+
     public IPage<BusEvaluationEntity> pageQuery(EvalQuery query) {
         return this.baseMapper.pageQuery(query.getPage(),query);
     }
@@ -50,6 +56,9 @@ public class LocalBusEvaluationService extends BaseService<BusEvaluationMapper,
             clinicService.update(new UpdateWrapper<BusClinicEntity>().lambda()
                     .eq(BusClinicEntity::getId,entity.getClinicId())
                     .set(BusClinicEntity::getEvalTime, Optional.ofNullable(entity.getEvaluateTime()).orElse(new Date())));
+            if(CharSequenceUtil.isNotBlank(entity.getPatientCode())){
+                wsPublishUtils.publishPatientMonitor(entity.getPatientCode(),entity.getTenantId());
+            }
         }
     }
 

+ 31 - 0
coffee-system/src/main/java/com/coffee/bus/service/LocalBusHospitalService.java

@@ -4,7 +4,9 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.coffee.bus.bean.GeoPoint;
 import com.coffee.bus.entity.*;
 import com.coffee.bus.enums.ConstantMixEnum;
@@ -19,12 +21,15 @@ import com.coffee.common.cache.manager.ConfigStorageManager;
 import com.coffee.common.config.mybatis.GetNameInterface;
 import com.coffee.common.config.websocket.HospitalCodeCheck;
 import com.coffee.common.crud.BaseService;
+import com.coffee.common.entity.QueryParamEntity;
 import com.coffee.common.exception.CustomException;
+import com.coffee.common.util.SecurityUtil;
 import com.coffee.system.entity.SysRole;
 import com.coffee.system.service.impl.SysRoleServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.jdbc.BadSqlGrammarException;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
@@ -239,4 +244,30 @@ public class LocalBusHospitalService extends BaseService<BusHospitalMapper, BusH
     public String getHospitalId(String code) {
         return Optional.ofNullable(this.getOne(new QueryWrapper<BusHospitalEntity>().lambda().eq(BusHospitalEntity::getCode,code))).orElse(new BusHospitalEntity()).getId();
     }
+
+
+    @Override
+    public IPage<BusHospitalEntity> list(QueryParamEntity<BusHospitalEntity> param) {
+        //是否为分页查询
+        QueryWrapper<BusHospitalEntity> wrapper = build(param);
+        if (!SecurityUtil.isSys()) {
+            wrapper.lambda().eq(BusHospitalEntity::getId,SecurityUtil.getTenantId());
+        }
+        if(ObjectUtil.isNotNull(param.getPage())){
+            Page<BusHospitalEntity> page = param.getPage();
+            return this.page(page,wrapper);
+        }else {
+            try {
+                List<BusHospitalEntity> list = list(wrapper);
+                Page<BusHospitalEntity> page = Page.of(0,1, CollUtil.isEmpty(list)?0:list.size());
+                page.setRecords(list);
+                return page;
+            }catch (Exception e){
+                if(e instanceof BadSqlGrammarException){
+                    throw new CustomException(e.getCause().getMessage());
+                }
+            }
+            return  new Page<>();
+        }
+    }
 }

+ 2 - 2
coffee-system/src/main/java/com/coffee/bus/service/LocalBusInfusionHistoryService.java

@@ -180,7 +180,7 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
                 .eq(BusInfusionHistoryEntity::getTenantId, tenantId)
                 .eq(BusInfusionHistoryEntity::getPatientCode, patientCode)
                 .ge(BusInfusionHistoryEntity::getStartTime, startTime)
-                .lt(BusInfusionHistoryEntity::getClinicStartTime, startTime));
+                .le(BusInfusionHistoryEntity::getClinicStartTime, startTime));
         if(CollectionUtil.isNotEmpty(infusionHistories)){
             infusionHistories.sort(Comparator.comparing(BusInfusionHistoryEntity::getStartTime));
             infusionHistories.forEach(infusion-> {
@@ -190,7 +190,7 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
             );
             this.updateBatchById(infusionHistories);
             clinicService.update(new UpdateWrapper<BusClinicEntity>().lambda().eq(BusClinicEntity::getId,clinicId)
-                    .isNull(CollUtil.isEmpty(infusionHistories),BusClinicEntity::getMonitorStartTime)
+//                    .isNull(CollUtil.isEmpty(infusionHistories),BusClinicEntity::getMonitorStartTime)
                     .set(BusClinicEntity::getMonitorStartTime,infusionHistories.get(0).getStartTime()));
         }else {
             clinicService.update(new UpdateWrapper<BusClinicEntity>().lambda().eq(BusClinicEntity::getId,clinicId)

+ 16 - 0
coffee-system/src/main/java/com/coffee/system/mapper/SysAppConfigMapper.java

@@ -0,0 +1,16 @@
+package com.coffee.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.coffee.bus.entity.BusAppConfig;
+
+/**
+ * <p>
+ * 部门表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+public interface SysAppConfigMapper extends BaseMapper<BusAppConfig> {
+
+}

+ 1 - 1
coffee-system/src/main/resources/mapper/bus/BusInfusionHistoryMapper.xml

@@ -205,7 +205,7 @@
             </if>
 
             <if test="query.finished != null">
-                and device_id =#{query.finished}
+                and finished =#{query.finished}
             </if>