forked from dyf/fys-Multi-tenant
Compare commits
10 Commits
e35955f156
...
73e1df4232
Author | SHA1 | Date | |
---|---|---|---|
73e1df4232 | |||
4e608b8f3a | |||
7d91426414 | |||
ad06811747 | |||
aeaa906bc9 | |||
36092932bf | |||
34188f20dd | |||
0fa0e4ab1b | |||
e321dcd652 | |||
3c2d97aaf2 |
@ -7,6 +7,7 @@ import com.fuyuanshen.common.mybatis.core.page.PageQuery;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -66,6 +67,8 @@ public class AppOperationVideoServiceImpl implements IAppOperationVideoService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<AppOperationVideoVo> queryList(AppOperationVideoBo bo) {
|
public List<AppOperationVideoVo> queryList(AppOperationVideoBo bo) {
|
||||||
|
Long userId = AppLoginHelper.getUserId();
|
||||||
|
bo.setCreateBy(userId);
|
||||||
LambdaQueryWrapper<AppOperationVideo> lqw = buildQueryWrapper(bo);
|
LambdaQueryWrapper<AppOperationVideo> lqw = buildQueryWrapper(bo);
|
||||||
return baseMapper.selectVoList(lqw);
|
return baseMapper.selectVoList(lqw);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,12 @@ public class UserQueryCriteria extends BaseEntity {
|
|||||||
@Schema(name = "是否启用")
|
@Schema(name = "是否启用")
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 帐号状态(0正常 1停用)
|
||||||
|
*/
|
||||||
|
@Schema(name = "帐号状态(0正常 1停用)")
|
||||||
|
private String status;
|
||||||
|
|
||||||
@Schema(name = "部门ID")
|
@Schema(name = "部门ID")
|
||||||
private Long deptId;
|
private Long deptId;
|
||||||
|
|
||||||
|
@ -58,6 +58,12 @@ public class ConsumerVo extends TenantEntity {
|
|||||||
@Schema(name = "是否启用")
|
@Schema(name = "是否启用")
|
||||||
private Boolean enabled;
|
private Boolean enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 帐号状态(0正常 1停用)
|
||||||
|
*/
|
||||||
|
@Schema(name = "帐号状态(0正常 1停用)")
|
||||||
|
private String status;
|
||||||
|
|
||||||
@Schema(name = "是否为admin账号", hidden = true)
|
@Schema(name = "是否为admin账号", hidden = true)
|
||||||
private Boolean isAdmin = false;
|
private Boolean isAdmin = false;
|
||||||
|
|
||||||
|
@ -112,6 +112,11 @@ public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> i
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateCustomer(Customer resources) throws Exception {
|
public void updateCustomer(Customer resources) throws Exception {
|
||||||
|
if (resources.getEnabled()) {
|
||||||
|
resources.setStatus("0");
|
||||||
|
} else {
|
||||||
|
resources.setStatus("1");
|
||||||
|
}
|
||||||
saveOrUpdate(resources);
|
saveOrUpdate(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +68,8 @@
|
|||||||
<if test="criteria.id != null">
|
<if test="criteria.id != null">
|
||||||
and u1.user_id = #{criteria.id}
|
and u1.user_id = #{criteria.id}
|
||||||
</if>
|
</if>
|
||||||
<if test="criteria.enabled != null">
|
<if test="criteria.status != null">
|
||||||
and u1.enabled = #{criteria.enabled}
|
and u.status = #{criteria.status}
|
||||||
</if>
|
</if>
|
||||||
<if test="criteria.deptIds != null and criteria.deptIds.size() != 0">
|
<if test="criteria.deptIds != null and criteria.deptIds.size() != 0">
|
||||||
and u1.dept_id in
|
and u1.dept_id in
|
||||||
@ -94,7 +94,7 @@
|
|||||||
<!-- 分页查询客户 -->
|
<!-- 分页查询客户 -->
|
||||||
<select id="findCustomers" resultType="com.fuyuanshen.customer.domain.Customer">
|
<select id="findCustomers" resultType="com.fuyuanshen.customer.domain.Customer">
|
||||||
select
|
select
|
||||||
u.user_id as customerId, u.nick_name , u.user_name, u.enabled, u.create_time
|
u.user_id as customerId, u.nick_name , u.user_name, u.enabled, u.create_time,u.status
|
||||||
from sys_user u
|
from sys_user u
|
||||||
<where>
|
<where>
|
||||||
<if test="criteria.ids != null and !criteria.ids.isEmpty()">
|
<if test="criteria.ids != null and !criteria.ids.isEmpty()">
|
||||||
@ -109,8 +109,8 @@
|
|||||||
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
|
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
|
||||||
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
|
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="criteria.enabled != null">
|
<if test="criteria.status != null">
|
||||||
and u.enabled = #{criteria.enabled}
|
and u.status = #{criteria.status}
|
||||||
</if>
|
</if>
|
||||||
<if test="criteria.params.beginTime != null and criteria.params.endTime != null">
|
<if test="criteria.params.beginTime != null and criteria.params.endTime != null">
|
||||||
and u.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
and u.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
||||||
@ -139,8 +139,8 @@
|
|||||||
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
|
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
|
||||||
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
|
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="criteria.enabled != null">
|
<if test="criteria.status != null">
|
||||||
and u.enabled = #{criteria.enabled}
|
and u.status = #{criteria.status}
|
||||||
</if>
|
</if>
|
||||||
<if test="criteria.params.beginTime != null and criteria.params.endTime != null">
|
<if test="criteria.params.beginTime != null and criteria.params.endTime != null">
|
||||||
and u.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
and u.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime}
|
||||||
|
@ -103,6 +103,11 @@
|
|||||||
<artifactId>fys-common-websocket</artifactId>
|
<artifactId>fys-common-websocket</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacv-platform</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,244 @@
|
|||||||
|
package com.fuyuanshen.demo.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
|
import com.fuyuanshen.common.core.domain.R;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||||
|
import org.bytedeco.javacv.Frame;
|
||||||
|
import org.bytedeco.javacv.Java2DFrameUtils;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/video")
|
||||||
|
public class VideoUploadController {
|
||||||
|
|
||||||
|
// 可配置项:建议从 application.yml 中读取
|
||||||
|
private static final int MAX_VIDEO_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||||
|
private static final int FRAME_RATE = 15; // 每秒抽15帧
|
||||||
|
private static final int DURATION = 2; // 抽2秒
|
||||||
|
private static final int TOTAL_FRAMES = FRAME_RATE * DURATION;
|
||||||
|
private static final int WIDTH = 160;
|
||||||
|
private static final int HEIGHT = 80;
|
||||||
|
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||||
|
|
||||||
|
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
@SaIgnore
|
||||||
|
public R<List<String>> upload(@RequestParam("file") MultipartFile file) {
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
return R.fail("上传文件不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isVideo(file.getOriginalFilename())) {
|
||||||
|
return R.fail("只允许上传视频文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getSize() > MAX_VIDEO_SIZE) {
|
||||||
|
return R.fail("视频大小不能超过10MB");
|
||||||
|
}
|
||||||
|
|
||||||
|
File tempFile = null;
|
||||||
|
try {
|
||||||
|
// 创建临时文件保存上传的视频
|
||||||
|
tempFile = createTempVideoFile(file);
|
||||||
|
|
||||||
|
|
||||||
|
List<BufferedImage> frames = extractFramesFromVideo(tempFile);
|
||||||
|
if (frames.isEmpty()) {
|
||||||
|
return R.fail("无法提取任何帧");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 新增:保存帧为图片
|
||||||
|
//saveFramesToLocal(frames, "extracted_frame");
|
||||||
|
|
||||||
|
byte[] binaryData = convertFramesToRGB565(frames);
|
||||||
|
// String base64Data = Base64.getEncoder().encodeToString(binaryData);
|
||||||
|
//
|
||||||
|
// return R.ok(base64Data);
|
||||||
|
// 构造响应头
|
||||||
|
// 将二进制数据转为 Hex 字符串
|
||||||
|
// 转换为 Hex 字符串列表
|
||||||
|
List<String> hexList = bytesToHexList(binaryData);
|
||||||
|
|
||||||
|
return R.ok(hexList);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return R.fail("视频处理失败:" + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
deleteTempFile(tempFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rgb565 转 hex
|
||||||
|
*/
|
||||||
|
private List<String> bytesToHexList(byte[] bytes) {
|
||||||
|
List<String> hexList = new ArrayList<>();
|
||||||
|
for (byte b : bytes) {
|
||||||
|
int value = b & 0xFF;
|
||||||
|
char high = HEX_ARRAY[value >>> 4];
|
||||||
|
char low = HEX_ARRAY[value & 0x0F];
|
||||||
|
hexList.add(String.valueOf(high) + low);
|
||||||
|
}
|
||||||
|
return hexList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建临时文件并保存上传的视频
|
||||||
|
*/
|
||||||
|
private File createTempVideoFile(MultipartFile file) throws Exception {
|
||||||
|
File tempFile = Files.createTempFile("upload-", ".mp4").toFile();
|
||||||
|
file.transferTo(tempFile);
|
||||||
|
return tempFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从视频中按时间均匀提取指定数量的帧
|
||||||
|
*/
|
||||||
|
private List<BufferedImage> extractFramesFromVideo(File videoFile) throws Exception {
|
||||||
|
List<BufferedImage> frames = new ArrayList<>();
|
||||||
|
|
||||||
|
try (FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(videoFile)) {
|
||||||
|
grabber.start();
|
||||||
|
|
||||||
|
// 获取视频总帧数和帧率
|
||||||
|
long totalFramesInVideo = grabber.getLengthInFrames();
|
||||||
|
int fps = (int) Math.round(grabber.getFrameRate());
|
||||||
|
if (fps <= 0) fps = 30;
|
||||||
|
|
||||||
|
double durationSeconds = (double) totalFramesInVideo / fps;
|
||||||
|
|
||||||
|
if (durationSeconds < DURATION) {
|
||||||
|
throw new IllegalArgumentException("视频太短,至少需要 " + DURATION + " 秒");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算每帧之间的间隔(浮点以实现更精确跳转)
|
||||||
|
double frameInterval = (double) totalFramesInVideo / TOTAL_FRAMES;
|
||||||
|
|
||||||
|
for (int i = 0; i < TOTAL_FRAMES; i++) {
|
||||||
|
int targetFrameNumber = (int) Math.round(i * frameInterval);
|
||||||
|
|
||||||
|
// 避免设置无效帧号
|
||||||
|
if (targetFrameNumber >= totalFramesInVideo) {
|
||||||
|
throw new IllegalArgumentException("目标帧超出范围: " + targetFrameNumber + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
grabber.setFrameNumber(targetFrameNumber);
|
||||||
|
Frame frame = grabber.grab();
|
||||||
|
|
||||||
|
if (frame != null && frame.image != null) {
|
||||||
|
BufferedImage bufferedImage = Java2DFrameUtils.toBufferedImage(frame);
|
||||||
|
frames.add(cropImage(bufferedImage, WIDTH, HEIGHT));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("无法获取第 " + targetFrameNumber + "帧 ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grabber.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将抽取的帧保存到本地,用于调试
|
||||||
|
*/
|
||||||
|
private void saveFramesToLocal(List<BufferedImage> frames, String prefix) {
|
||||||
|
// 指定输出目录
|
||||||
|
File outputDir = new File("output_frames");
|
||||||
|
if (!outputDir.exists()) {
|
||||||
|
outputDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (BufferedImage frame : frames) {
|
||||||
|
try {
|
||||||
|
File outputImage = new File(outputDir, prefix + "_" + (index++) + ".png");
|
||||||
|
ImageIO.write(frame, "png", outputImage);
|
||||||
|
System.out.println("保存帧图片成功: " + outputImage.getAbsolutePath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("保存帧图片失败 " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将所有帧转换为 RGB565 格式字节数组
|
||||||
|
*/
|
||||||
|
private byte[] convertFramesToRGB565(List<BufferedImage> frames) throws Exception {
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
for (BufferedImage image : frames) {
|
||||||
|
byte[] rgb565Bytes = convertToRGB565(image);
|
||||||
|
byteArrayOutputStream.write(rgb565Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteArrayOutputStream.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是支持的视频格式
|
||||||
|
*/
|
||||||
|
private boolean isVideo(String filename) {
|
||||||
|
String ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
|
||||||
|
return Arrays.asList(".mp4", ".avi", ".mov", ".mkv").contains(ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 裁剪图像到目标尺寸
|
||||||
|
*/
|
||||||
|
private BufferedImage cropImage(BufferedImage img, int targetWidth, int targetHeight) {
|
||||||
|
int w = Math.min(img.getWidth(), targetWidth);
|
||||||
|
int h = Math.min(img.getHeight(), targetHeight);
|
||||||
|
return img.getSubimage(0, 0, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 BufferedImage 转换为 RGB565 格式的字节数组
|
||||||
|
*/
|
||||||
|
private byte[] convertToRGB565(BufferedImage image) {
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
byte[] result = new byte[width * height * 2]; // RGB565: 2 bytes per pixel
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
int rgb = image.getRGB(x, y);
|
||||||
|
int r = ((rgb >> 16) & 0xFF) >> 3;
|
||||||
|
int g = ((rgb >> 8) & 0xFF) >> 2;
|
||||||
|
int b = (rgb & 0xFF) >> 3;
|
||||||
|
short pixel = (short) ((r << 11) | (g << 5) | b);
|
||||||
|
|
||||||
|
result[index++] = (byte) (pixel >> 8); // High byte first
|
||||||
|
result[index++] = (byte) pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除临时文件
|
||||||
|
*/
|
||||||
|
private void deleteTempFile(File file) {
|
||||||
|
if (file != null && file.exists()) {
|
||||||
|
if (!file.delete()) {
|
||||||
|
throw new IllegalArgumentException("无法删除临时文件: " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ public class DeviceAssignments extends TenantEntity {
|
|||||||
private Long fromCustomerId;
|
private Long fromCustomerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接收方
|
* 接收方(当前设备所处位置)
|
||||||
*/
|
*/
|
||||||
private Long toCustomerId;
|
private Long toCustomerId;
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ import com.fuyuanshen.system.domain.vo.SysOssVo;
|
|||||||
import com.fuyuanshen.system.service.ISysOssService;
|
import com.fuyuanshen.system.service.ISysOssService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -319,9 +320,9 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
|||||||
List<DeviceTypeGrants> deviceTypeGrants = new ArrayList<>();
|
List<DeviceTypeGrants> deviceTypeGrants = new ArrayList<>();
|
||||||
for (DeviceAssignments assignment : assignments) {
|
for (DeviceAssignments assignment : assignments) {
|
||||||
|
|
||||||
if (assignment.getToCustomerId() != null) {
|
if (assignment.getToCustomerId() != null && assignment.getToCustomerId() != 0L) {
|
||||||
log.info("设备已经分配客户!!!");
|
log.info("设备已经分配客户!!!");
|
||||||
continue;
|
throw new RuntimeException("设备已经分配客户!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Device device = deviceMapper.selectById(assignment.getDeviceId());
|
Device device = deviceMapper.selectById(assignment.getDeviceId());
|
||||||
@ -412,54 +413,6 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 撤回设备
|
|
||||||
*
|
|
||||||
* @param ids
|
|
||||||
*/
|
|
||||||
// @Override
|
|
||||||
// public void withdrawDevice(List<Long> ids) {
|
|
||||||
// ids.forEach((id) -> {
|
|
||||||
// List<Device> deviceChain = getDeviceChain(id);
|
|
||||||
// deviceChain.forEach((device) -> {
|
|
||||||
// device.setDeviceStatus(DeviceStatusEnum.INVALID.getCode());
|
|
||||||
// deviceMapper.updateById(device);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// ids.forEach((id) -> {
|
|
||||||
// Device device = new Device();
|
|
||||||
// device.setId(id);
|
|
||||||
// device.setCustomerId(null);
|
|
||||||
// device.setCustomerName("");
|
|
||||||
// deviceMapper.updateById(device);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// public List<Device> getDeviceChain(Long originalDeviceId) {
|
|
||||||
// List<Device> chain = new ArrayList<>();
|
|
||||||
// Set<Long> visited = new HashSet<>(); // 防止循环引用
|
|
||||||
// findNext(chain, visited, originalDeviceId);
|
|
||||||
// return chain;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void findNext(List<Device> chain, Set<Long> visited, Long currentOriginalDeviceId) {
|
|
||||||
// if (visited.contains(currentOriginalDeviceId)) {
|
|
||||||
// log.info("检测到循环引用,终止递归");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// visited.add(currentOriginalDeviceId);
|
|
||||||
//
|
|
||||||
// List<Device> devices = deviceMapper.findByOriginalDeviceId(currentOriginalDeviceId);
|
|
||||||
// for (Device device : devices) {
|
|
||||||
// chain.add(device);
|
|
||||||
// findNext(chain, visited, device.getId());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 撤回设备
|
* 撤回设备
|
||||||
*
|
*
|
||||||
@ -474,7 +427,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
|||||||
Device device = deviceMapper.selectById(assignment.getDeviceId());
|
Device device = deviceMapper.selectById(assignment.getDeviceId());
|
||||||
// 接收者
|
// 接收者
|
||||||
assignment.setAssigneeName("");
|
assignment.setAssigneeName("");
|
||||||
assignment.setToCustomerId(null);
|
assignment.setToCustomerId(0L);
|
||||||
deviceAssignmentsMapper.updateById(assignment);
|
deviceAssignmentsMapper.updateById(assignment);
|
||||||
|
|
||||||
// 获取所有已分配的设备
|
// 获取所有已分配的设备
|
||||||
|
8
pom.xml
8
pom.xml
@ -37,6 +37,8 @@
|
|||||||
<lombok.version>1.18.36</lombok.version>
|
<lombok.version>1.18.36</lombok.version>
|
||||||
<bouncycastle.version>1.80</bouncycastle.version>
|
<bouncycastle.version>1.80</bouncycastle.version>
|
||||||
<justauth.version>1.16.7</justauth.version>
|
<justauth.version>1.16.7</justauth.version>
|
||||||
|
|
||||||
|
<javacv-platform.version>1.5.7</javacv-platform.version>
|
||||||
<!-- 离线IP地址定位库 -->
|
<!-- 离线IP地址定位库 -->
|
||||||
<ip2region.version>2.7.0</ip2region.version>
|
<ip2region.version>2.7.0</ip2region.version>
|
||||||
|
|
||||||
@ -142,6 +144,12 @@
|
|||||||
<version>${justauth.version}</version>
|
<version>${justauth.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacv-platform</artifactId>
|
||||||
|
<version>${javacv-platform.version}</version> <!-- 使用合适的版本号 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- common 的依赖配置-->
|
<!-- common 的依赖配置-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fuyuanshen</groupId>
|
<groupId>com.fuyuanshen</groupId>
|
||||||
|
Reference in New Issue
Block a user