lihao16 7 сар өмнө
parent
commit
f66dd08ccc

+ 0 - 1
smsb-admin/src/main/java/org/dromara/web/controller/AuthController.java

@@ -99,7 +99,6 @@ public class AuthController {
         loginService.checkTenant(loginBody.getTenantId());
         // 登录
         LoginVo loginVo = IAuthStrategy.login(body, client, grantType);
-
         return R.ok(loginVo);
     }
 

+ 2 - 0
smsb-admin/src/main/resources/application.yml

@@ -40,6 +40,8 @@ server:
       io: 8
       # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
       worker: 256
+  # 文件临时目录
+  tempDir: /home/inspur/temp
 
 # 日志配置
 logging:

+ 7 - 0
smsb-modules/smsb-source/pom.xml

@@ -125,6 +125,13 @@
             <version>5.2.3</version>
         </dependency>
 
+        <!-- 图片质量压缩 -->
+        <dependency>
+            <groupId>org.jpedal</groupId>
+            <artifactId>OpenViewerFX</artifactId>
+            <version>6.6.14</version>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 3 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbMinioData.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import lombok.ToString;
 import org.dromara.common.tenant.core.TenantEntity;
 
 import java.io.Serial;
@@ -19,6 +20,7 @@ import java.util.Date;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("smsb_minio_data")
+@ToString
 public class SmsbMinioData extends TenantEntity {
 
     @Serial
@@ -132,6 +134,7 @@ public class SmsbMinioData extends TenantEntity {
 
     private String createUser;
 
+    /** 0-待转 1-成功 2-失败 */
     private Integer transState;
 
     private String fileUrl;

+ 2 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbMinioTransRecord.java

@@ -1,5 +1,6 @@
 package com.inspur.source.domain;
 
+import lombok.ToString;
 import org.dromara.common.tenant.core.TenantEntity;
 import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
@@ -16,6 +17,7 @@ import java.io.Serial;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("smsb_minio_trans_record")
+@ToString
 public class SmsbMinioTransRecord extends TenantEntity {
 
     @Serial

+ 180 - 3
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbMinioDataServiceImpl.java

@@ -5,24 +5,40 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.idrsolutions.image.png.PngCompressor;
 import com.inspur.source.domain.*;
 import com.inspur.source.domain.bo.SmsbMinioDataBo;
 import com.inspur.source.domain.vo.*;
 import com.inspur.source.mapper.*;
 import com.inspur.source.service.ISmsbMinioDataService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.oss.core.OssClient;
+import org.dromara.common.oss.entity.UploadResult;
+import org.dromara.common.oss.factory.OssFactory;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.system.domain.SysOss;
 import org.dromara.system.domain.vo.SysOssVo;
 import org.dromara.system.mapper.SysOssMapper;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.util.List;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -34,6 +50,7 @@ import java.util.stream.Collectors;
  */
 @RequiredArgsConstructor
 @Service
+@Slf4j
 public class SmsbMinioDataServiceImpl implements ISmsbMinioDataService {
 
     private final SmsbMinioDataMapper baseMapper;
@@ -44,6 +61,12 @@ public class SmsbMinioDataServiceImpl implements ISmsbMinioDataService {
     @Autowired
     private SysOssMapper sysOssMapper;
 
+    @Autowired
+    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    @Value("${server.tempDir}")
+    private String tempDir;
+
     /**
      * 查询文件资源
      *
@@ -139,6 +162,7 @@ public class SmsbMinioDataServiceImpl implements ISmsbMinioDataService {
             return false;
         }
         List<Long> sourceTreeIds = bo.getSourceTreeIds();
+        List<SmsbMinioTransRecord> transRecordList = new ArrayList<>();
         for (String ossId : ossIdList) {
             SysOssVo sysOssVo = sysOssMapper.selectVoById(ossId);
             // 创建add
@@ -146,8 +170,6 @@ public class SmsbMinioDataServiceImpl implements ISmsbMinioDataService {
             boolean flag = baseMapper.insert(add) > 0;
             if (flag) {
                 bo.setId(add.getId());
-                // 创建转码任务
-                createTransRecord(add);
                 // 保存sourceTree-source关联关系
                 if (CollectionUtil.isNotEmpty(sourceTreeIds)) {
                     sourceTreeIds.forEach(sourceTreeId -> {
@@ -162,12 +184,166 @@ public class SmsbMinioDataServiceImpl implements ISmsbMinioDataService {
                     sourceTreeRel.setTreeId(0L);
                     smsbSourceTreeRelMapper.insert(sourceTreeRel);
                 }
+                // 创建转码任务
+                SmsbMinioTransRecord transRecord = createTransRecord(add);
+                transRecordList.add(transRecord);
             }
         }
+        doMinioFileTrans(transRecordList, baseMapper, transRecordMapper);
         return true;
     }
 
-    private void createTransRecord(SmsbMinioData add) {
+    private void doMinioFileTrans(List<SmsbMinioTransRecord> transRecordList, SmsbMinioDataMapper baseMapper, SmsbMinioTransRecordMapper transRecordMapper) {
+        Runnable transTask = () -> {
+            for (SmsbMinioTransRecord transRecord : transRecordList) {
+                log.info("doMinioFileTrans transRecord : " + transRecord.toString());
+                SmsbMinioData smsbMinioData = baseMapper.selectById(transRecord.getFileId());
+                log.info("doMinioFileTrans smsbMinioData : " + smsbMinioData.toString());
+                // 图片转码
+                // 更新转码记录状态 正在转
+                transRecord.setTransProgress(1);
+                transRecordMapper.updateById(transRecord);
+                if (transRecord.getTransType() == 1) {
+                    log.info("transTask start : " + smsbMinioData.getId() + ",file Type is image");
+                    compressImg(smsbMinioData, transRecord);
+                } else if (transRecord.getTransType() == 2) {
+                    // TODO 视频转码
+                }
+                // 更新转码记录状态
+                baseMapper.updateById(smsbMinioData);
+                transRecordMapper.updateById(transRecord);
+                log.info("transTask end : " + smsbMinioData.getId() + ",trans result : " + smsbMinioData.getTransState());
+            }
+        };
+        // 提交Runnable任务到线程池
+        threadPoolTaskExecutor.submit(transTask);
+    }
+
+    public void compressImg(SmsbMinioData smsbMinioData, SmsbMinioTransRecord transRecord) {
+        // 图片的横屏、竖屏
+        String hwType = getHWType(smsbMinioData);
+        // 压缩前分辨率
+        Integer width = Integer.parseInt(smsbMinioData.getResolution().split("x")[0]);
+        Integer height = Integer.parseInt(smsbMinioData.getResolution().split("x")[1]);
+        // 缩放比率因子,保留2位小数
+        double factor = 0.0;
+        // 压缩后分辨率
+        double imageWidth = 0;
+        double imageHeight = 0;
+        if ("width".equals(hwType)) {
+            imageWidth = 480.0;
+            factor = new BigDecimal((float) imageWidth / width).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+            //获取缩放后的高度
+            imageHeight = height * factor;
+        } else {
+            imageHeight = 480.0;
+            factor = new BigDecimal((float) imageHeight / height).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+            //获取缩放后的宽度
+            imageWidth = height * factor;
+        }
+        log.info("image hwType is : " + hwType + ",imageWidth : " + imageWidth + ",imageHeight : " + imageHeight);
+        //  图片压缩
+        boolean compressResult = doCompressImg(imageWidth, imageHeight, smsbMinioData);
+        // 压缩成功 更新主表和记录表状态
+        if (compressResult) {
+            smsbMinioData.setTransState(1);
+            transRecord.setResult(1);
+        } else {
+            smsbMinioData.setTransState(2);
+            transRecord.setResult(2);
+        }
+        transRecord.setTransProgress(2);
+    }
+
+    private boolean doCompressImg(double imageWidth, double imageHeight, SmsbMinioData smsbMinioData) {
+        // 临时文件
+        String tempFile = tempDir + File.separator + System.currentTimeMillis() + ".png";
+        try {
+            URL srcFileUrl = new URL(smsbMinioData.getFileUrl());
+            //获取图片对象
+            Image src = javax.imageio.ImageIO.read(srcFileUrl);
+            //缓存图片对象
+            BufferedImage to = new BufferedImage((int) imageWidth, (int) imageHeight,
+                BufferedImage.TYPE_INT_RGB);
+            Graphics2D g2d = to.createGraphics();
+            to = g2d.getDeviceConfiguration().createCompatibleImage((int) imageWidth, (int) imageWidth,
+                Transparency.TRANSLUCENT);
+            g2d.dispose();
+            //绘制图片
+            to.getGraphics().drawImage(src.getScaledInstance((int) imageWidth, (int) imageWidth, Image.SCALE_SMOOTH), 0, 0, null);
+            //获取输入流对象
+            FileOutputStream out = new FileOutputStream(tempFile);
+            ImageIO.write(to, "png", out);
+            out.close();
+            // 文件质量压缩
+            compressImageSize(tempFile);
+            // 上传文件至minio
+            String imageUrl = uploadCompressImage(tempFile);
+            // 压缩成功,报错压缩图片路径
+            smsbMinioData.setScreenshot(imageUrl);
+            return true;
+        } catch (IOException ex) {
+            log.error("doCompressImg exception : " + ex.getMessage());
+            return false;
+        } finally {
+            // 文件删除
+            deleteFiles(tempFile);
+        }
+    }
+
+    private String uploadCompressImage(String tempFile) {
+        File file = new File(tempFile);
+        String suffix = ".png";
+        OssClient storage = OssFactory.instance();
+        UploadResult uploadResult;
+        uploadResult = storage.uploadSuffix(file, suffix);
+        String imageUrl = uploadResult.getUrl();
+        return imageUrl;
+    }
+
+    /**
+     * 原图质量压缩
+     *
+     * @param filePath 图片地址
+     * @return
+     */
+    private void compressImageSize(String filePath) throws IOException {
+        // 源文件
+        File file = new File(filePath);
+        // 目标输出文件,可与源文件一致,一致会覆盖
+        File outfile = new File(filePath);
+        PngCompressor.compress(file, outfile);
+    }
+
+    /**
+     * 刪除本地文件
+     *
+     * @param path 图片地址
+     * @return
+     */
+    private void deleteFiles(String path) {
+        boolean flag = false;
+        //根据路径创建文件对象
+        File file = new File(path);
+        //路径是个文件且不为空时删除文件
+        if (file.isFile() && file.exists()) {
+            flag = file.delete();
+            log.info("delete temp file is : " + flag);
+        }
+    }
+
+
+    private String getHWType(SmsbMinioData smsbMinioData) {
+        Integer width = Integer.parseInt(smsbMinioData.getResolution().split("x")[0]);
+        Integer height = Integer.parseInt(smsbMinioData.getResolution().split("x")[1]);
+        if (width >= height) {
+            return "width";
+        } else {
+            return "height";
+        }
+    }
+
+    private SmsbMinioTransRecord createTransRecord(SmsbMinioData add) {
         SmsbMinioTransRecord transRecord = new SmsbMinioTransRecord();
         transRecord.setCreateUser(LoginHelper.getUsername());
         transRecord.setFileId(add.getId());
@@ -176,6 +352,7 @@ public class SmsbMinioDataServiceImpl implements ISmsbMinioDataService {
         transRecord.setTransProgress(0);
         transRecord.setResult(0);
         transRecordMapper.insert(transRecord);
+        return transRecord;
     }
 
     private void createSaveMinioData(SysOssVo sysOssVo, SmsbMinioData add) {

+ 5 - 0
smsb-plus-ui/src/views/smsb/device/index.vue

@@ -49,6 +49,11 @@
             <el-form-item label="MAC" prop="mac">
               <el-input v-model="queryParams.mac" style="width: 150px" placeholder="请输入设备MAC" clearable @keyup.enter="handleQuery" />
             </el-form-item>
+            <el-form-item label="状态" prop="onlineStatus">
+              <el-select v-model="queryParams.onlineStatus" placeholder="请选择设备状态" clearable @change="handleQuery" style="width: 150px">
+                <el-option v-for="item in sys_device_online" :key="item.label" :value="item.value" :label="item.label"></el-option>
+              </el-select>
+            </el-form-item>
             <el-form-item>
               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
               <el-button icon="Refresh" @click="resetQuery">重置</el-button>