运维模块补充
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
package org.dromara.system.api;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025-09-10 16:15
|
||||
@ -14,4 +16,10 @@ public interface RemoteProjectService {
|
||||
*/
|
||||
String selectProjectNameById(Long projectId);
|
||||
|
||||
/**
|
||||
*校验用户是否拥有操作项目的权限
|
||||
* @param projectId
|
||||
* @param userId
|
||||
*/
|
||||
void validAuth(Long projectId, Long userId);
|
||||
}
|
||||
|
||||
@ -189,4 +189,5 @@ public interface RemoteUserService {
|
||||
*/
|
||||
Map<Long, String> selectPostNamesByIds(List<Long> postIds);
|
||||
|
||||
RemoteUserVo selectUserByPhonenumber(String phone);
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package org.dromara.system.api.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025/5/27 9:16
|
||||
*/
|
||||
public class BigDecimalUtil {
|
||||
|
||||
/**
|
||||
* 计算百分比
|
||||
*
|
||||
* @param dividend 被除数
|
||||
* @param divisor 除数
|
||||
* @return 百分比(保留2位小数)如 12.34%
|
||||
*/
|
||||
public static BigDecimal toPercentage(BigDecimal dividend, BigDecimal divisor) {
|
||||
if (dividend == null || divisor == null || divisor.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return BigDecimal.valueOf(0.00);
|
||||
}
|
||||
return dividend
|
||||
.multiply(new BigDecimal("100"))
|
||||
.divide(divisor, 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
package org.dromara.system.api.utils;
|
||||
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025/4/17 14:53
|
||||
*/
|
||||
public class DocumentUtil {
|
||||
|
||||
/**
|
||||
* 在给定的 run 里插入图片,并按原始大小(或缩放后大小)设置宽高。
|
||||
*
|
||||
* @param run 要插入图片的 XWPFRun
|
||||
* @param imagePath 本地图片路径或 URL(这里示例用本地文件)
|
||||
* @param document 当前文档对象
|
||||
* @param maxWidthPx 最大允许宽度(像素),如果原图更宽就按比例缩放;设置为 <=0 则不缩放
|
||||
*/
|
||||
public static void insertImageDynamic(XWPFRun run,
|
||||
String imagePath,
|
||||
XWPFDocument document,
|
||||
int maxWidthPx) throws Exception {
|
||||
// 1. 先把图片读到 byte[]
|
||||
byte[] imgBytes = Files.readAllBytes(Paths.get(imagePath));
|
||||
// 2. 用 ImageIO 读出宽高(像素)
|
||||
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgBytes));
|
||||
int widthPx = img.getWidth();
|
||||
int heightPx = img.getHeight();
|
||||
// 3. 如果指定了最大宽度,而且原图更宽,则按比例缩放
|
||||
if (maxWidthPx > 0 && widthPx > maxWidthPx) {
|
||||
double ratio = (double) maxWidthPx / widthPx;
|
||||
widthPx = maxWidthPx;
|
||||
heightPx = (int) (heightPx * ratio);
|
||||
}
|
||||
// 4. 把像素转换成 EMU
|
||||
int widthEmu = Units.pixelToEMU(widthPx);
|
||||
int heightEmu = Units.pixelToEMU(heightPx);
|
||||
// 5. 插入图片
|
||||
String lower = imagePath.toLowerCase();
|
||||
int format = lower.endsWith(".png") ? XWPFDocument.PICTURE_TYPE_PNG
|
||||
: lower.endsWith(".gif") ? XWPFDocument.PICTURE_TYPE_GIF
|
||||
: lower.endsWith(".jpeg") ? XWPFDocument.PICTURE_TYPE_JPEG
|
||||
: lower.endsWith(".jpg") ? XWPFDocument.PICTURE_TYPE_JPEG
|
||||
: XWPFDocument.PICTURE_TYPE_PNG; // 默认当 PNG
|
||||
try (InputStream picIn = new ByteArrayInputStream(imgBytes)) {
|
||||
run.addPicture(picIn, format, imagePath, widthEmu, heightEmu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 递归将 sourceDir 中的所有文件和子目录,按照相对于 rootDir 的路径写入 ZipOutputStream。
|
||||
*
|
||||
* @param rootDir 源目录的根,用来计算相对路径
|
||||
* @param sourceDir 当前递归到的目录
|
||||
* @param zos ZIP 输出流
|
||||
*/
|
||||
public static void zipDirectory(Path rootDir, Path sourceDir, ZipOutputStream zos) throws IOException {
|
||||
// 遍历当前目录下的所有文件和文件夹
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir)) {
|
||||
for (Path entry : stream) {
|
||||
if (Files.isDirectory(entry)) {
|
||||
// 如果是目录,递归
|
||||
zipDirectory(rootDir, entry, zos);
|
||||
} else {
|
||||
// 如果是文件,创建一个 ZipEntry,路径以 '/' 分隔
|
||||
Path relativePath = rootDir.relativize(entry);
|
||||
String zipEntryName = relativePath.toString().replace(File.separatorChar, '/');
|
||||
ZipEntry zipEntry = new ZipEntry(zipEntryName);
|
||||
zos.putNextEntry(zipEntry);
|
||||
// 把文件内容写入 ZIP
|
||||
try (InputStream is = Files.newInputStream(entry)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
zos.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
package org.dromara.system.api.utils;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025/4/23 10:42
|
||||
*/
|
||||
@Slf4j
|
||||
public class Dxf2JsonUtil {
|
||||
|
||||
/**
|
||||
* dxf转json
|
||||
*
|
||||
* @param exePath dxf2json.exe路径
|
||||
* @param inputDXFPath 输入dxf文件路径
|
||||
* @param outputJSONPath 输出json文件路径
|
||||
* @param sourceEPSG 源坐标系
|
||||
* @param targetEPSG 目标坐标系
|
||||
*/
|
||||
public static void dxf2json(String exePath, String inputDXFPath, String outputJSONPath, String sourceEPSG, String targetEPSG) {
|
||||
// 判断对应文件是否存在
|
||||
File exeFile = new File(exePath);
|
||||
if (!exeFile.exists()) {
|
||||
throw new ServiceException("转换程序不存在!");
|
||||
}
|
||||
File inputDXFFile = new File(inputDXFPath);
|
||||
if (!inputDXFFile.exists()) {
|
||||
throw new ServiceException("待转换 dxf 文件不存在!");
|
||||
}
|
||||
// 构造命令行参数
|
||||
List<String> parameters = buildParameter(exePath, inputDXFPath, outputJSONPath, sourceEPSG, targetEPSG);
|
||||
// 执行命令行
|
||||
ProcessBuilder builder = new ProcessBuilder(parameters);
|
||||
// 合并标准错误和输出
|
||||
builder.redirectErrorStream(true);
|
||||
try {
|
||||
Process process = builder.start();
|
||||
// 读取输出
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream(), "GBK")
|
||||
);
|
||||
String line;
|
||||
log.info("dxf 转 json 程序开始执行,程序路径:{},输入 dxf 路径:{},输出 json 文件路径:{},源坐标系:{},模板坐标系:{}",
|
||||
exePath, inputDXFPath, outputJSONPath, sourceEPSG, targetEPSG);
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("dxf 转 json 程序执行中:{}", line);
|
||||
JSONObject jsonObject = JSONUtil.parseObj(line);
|
||||
Integer code = jsonObject.get("code", Integer.class);
|
||||
if (code != 0 && code != 200) {
|
||||
throw new ServiceException("dxf 转 json 程序执行出错!");
|
||||
}
|
||||
}
|
||||
int exitCode = process.waitFor();
|
||||
log.info("dxf 转 json 程序执行完毕,程序退出码:{}", exitCode);
|
||||
reader.close();
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.error("执行 dxf 转 json 命令行时出错", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造命令行参数
|
||||
*
|
||||
* @param exePath dxf2json.exe路径
|
||||
* @param inputDXFPath 输入dxf文件路径
|
||||
* @param outputJSONPath 输出json文件路径
|
||||
* @param sourceEPSG 源坐标系
|
||||
* @param targetEPSG 目标坐标系
|
||||
* @return 命令行参数
|
||||
*/
|
||||
public static List<String> buildParameter(String exePath,
|
||||
String inputDXFPath,
|
||||
String outputJSONPath,
|
||||
String sourceEPSG,
|
||||
String targetEPSG) {
|
||||
// 构造命令行
|
||||
return Arrays.asList(
|
||||
exePath,
|
||||
inputDXFPath,
|
||||
outputJSONPath,
|
||||
sourceEPSG,
|
||||
targetEPSG
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.dromara.system.api.utils;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* @Author 铁憨憨
|
||||
* @Date 2025/7/18 10:16
|
||||
* @Version 1.0
|
||||
*
|
||||
* HttpClient 设计为可重用、线程安全的组件,其内部维护了连接池等资源,适合在多个接口调用中共享使用,所以交给Spring Bean 管理
|
||||
*/
|
||||
@Configuration
|
||||
public class HttpClientConfig {
|
||||
@Bean
|
||||
public HttpClient httpClient() {
|
||||
return HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(10))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package org.dromara.system.api.utils;
|
||||
|
||||
import cn.hutool.core.util.HexUtil;
|
||||
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.symmetric.AES;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025/6/25 10:57
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class IdCardEncryptorUtil {
|
||||
|
||||
@Value("${id-card.encrypt-key}")
|
||||
private String encryptKeyHex;
|
||||
|
||||
private AES aes;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
byte[] keyBytes = HexUtil.decodeHex(encryptKeyHex);
|
||||
this.aes = SecureUtil.aes(keyBytes);
|
||||
log.info("身份证 AES 加解密工具初始化成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
*
|
||||
* @param idCard 身份证号码
|
||||
* @return 加密后的身份证号码
|
||||
*/
|
||||
public String encrypt(String idCard) {
|
||||
return aes.encryptBase64(idCard);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
*
|
||||
* @param encrypted 密文
|
||||
* @return 解密后的身份证号码
|
||||
*/
|
||||
public String decrypt(String encrypted) {
|
||||
if (encrypted == null) {
|
||||
return null;
|
||||
}
|
||||
return aes.decryptStr(encrypted);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,316 @@
|
||||
//package org.dromara.system.api.utils;
|
||||
//
|
||||
//import cn.hutool.json.JSONUtil;
|
||||
//import org.dromara.common.constant.GeoJsonConstant;
|
||||
//import org.dromara.common.core.constant.HttpStatus;
|
||||
//import org.dromara.common.core.exception.ServiceException;
|
||||
//import org.dromara.common.domain.GeoPoint;
|
||||
//import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane;
|
||||
//import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
|
||||
//import org.dromara.facility.domain.dto.geojson.FacGeometry;
|
||||
//import org.dromara.facility.domain.dto.geojson.FacGeometryByPoint;
|
||||
//import org.locationtech.jts.geom.*;
|
||||
//import org.locationtech.jts.index.strtree.STRtree;
|
||||
//
|
||||
//import java.util.HashMap;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
///**
|
||||
// * @author lilemy
|
||||
// * @date 2025/4/24 11:48
|
||||
// */
|
||||
//public class JSTUtil {
|
||||
//
|
||||
// private static final GeometryFactory geometryFactory = new GeometryFactory();
|
||||
//
|
||||
// /**
|
||||
// * 获取最近点的名称
|
||||
// *
|
||||
// * @param target 目标点
|
||||
// * @param nameGeoJson 点对象列表
|
||||
// * @return 最近点的名称
|
||||
// */
|
||||
// public static String findNearestText(List<Double> target, List<FacFeatureByPoint> nameGeoJson) {
|
||||
// Point targetPoint = geometryFactory.createPoint(new Coordinate(target.get(0), target.get(1)));
|
||||
// FacFeatureByPoint nearestFeature = null;
|
||||
// double minDistance = Double.MAX_VALUE;
|
||||
// for (FacFeatureByPoint feature : nameGeoJson) {
|
||||
// FacGeometryByPoint geometry = feature.getGeometry();
|
||||
// List<Double> coords = geometry.getCoordinates();
|
||||
// if (coords != null && coords.size() == 2) {
|
||||
// Point currentPoint = geometryFactory.createPoint(new Coordinate(coords.get(0), coords.get(1)));
|
||||
// double distance = targetPoint.distance(currentPoint);
|
||||
// if (distance < minDistance) {
|
||||
// minDistance = distance;
|
||||
// nearestFeature = feature;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (nearestFeature != null && nearestFeature.getProperties() != null) {
|
||||
// return nearestFeature.getProperties().getText();
|
||||
// }
|
||||
// return null; // 如果没找到合适的点
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 点是否在平面内
|
||||
// *
|
||||
// * @param planeLists 平面坐标
|
||||
// * @param pointList 点坐标
|
||||
// * @return 点是否在平面内
|
||||
// */
|
||||
// public static Boolean pointIsWithInPlane(List<List<Double>> planeLists, List<Double> pointList) {
|
||||
// // 构建平面
|
||||
// Coordinate[] coordinates = getPlaneCoordinate(planeLists);
|
||||
// Polygon polygon = geometryFactory.createPolygon(coordinates);
|
||||
// // 构建待判断点
|
||||
// Point point = geometryFactory.createPoint(new Coordinate(pointList.get(0), pointList.get(1)));
|
||||
// // 判断是否在多边形内
|
||||
// return polygon.contains(point);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取平面内点列表集合
|
||||
// *
|
||||
// * @param planeLists 平面坐标列表
|
||||
// * @param pointLists 点坐标列表集合
|
||||
// * @return 平面内点坐标列表集合
|
||||
// */
|
||||
// public static List<List<Double>> getPointInPlaneList(List<List<Double>> planeLists, List<List<Double>> pointLists) {
|
||||
// // 构建平面
|
||||
// Coordinate[] coordinates = getPlaneCoordinate(planeLists);
|
||||
// LinearRing shell = geometryFactory.createLinearRing(coordinates);
|
||||
// Polygon polygon = geometryFactory.createPolygon(shell);
|
||||
// // 获取平面内点结合
|
||||
// return pointLists.stream().filter(pointList -> {
|
||||
// // 构建待判断点
|
||||
// Point point = geometryFactory.createPoint(new Coordinate(pointList.get(0), pointList.get(1)));
|
||||
// // 判断是否在多边形内
|
||||
// return polygon.contains(point);
|
||||
// }).toList();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 平面是否在平面内
|
||||
// *
|
||||
// * @param referencePlane 参考平面
|
||||
// * @param comparePlane 比较平面
|
||||
// * @return 平面是否在平面内
|
||||
// */
|
||||
// public static Boolean planeIsWithInPlane(List<List<Double>> referencePlane, List<List<Double>> comparePlane) {
|
||||
// // 构建参考平面
|
||||
// Coordinate[] referenceCoordinates = getPlaneCoordinate(referencePlane);
|
||||
// Polygon referencePolygon = geometryFactory.createPolygon(referenceCoordinates);
|
||||
// // 构建比较平面
|
||||
// Coordinate[] compareCoordinates = getPlaneCoordinate(comparePlane);
|
||||
// Polygon comparePolygon = geometryFactory.createPolygon(compareCoordinates);
|
||||
// // 判断是否在多边形内
|
||||
// return referencePolygon.contains(comparePolygon);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 判断两个平面是否相交
|
||||
// *
|
||||
// * @param referencePlane 参考平面
|
||||
// * @param comparePlane 待比较平面
|
||||
// * @return 平面是否相交
|
||||
// */
|
||||
// public static Boolean arePolygonsIntersecting(List<List<Double>> referencePlane, List<List<Double>> comparePlane) {
|
||||
// // 构建 Polygon A(参考面)
|
||||
// Coordinate[] coordsA = referencePlane.stream()
|
||||
// .map(p -> new Coordinate(p.getFirst(), p.get(1)))
|
||||
// .toArray(Coordinate[]::new);
|
||||
// Polygon polygonA = geometryFactory.createPolygon(coordsA);
|
||||
// // 构建 Polygon B(比较面)
|
||||
// Coordinate[] coordsB = comparePlane.stream()
|
||||
// .map(p -> new Coordinate(p.getFirst(), p.get(1)))
|
||||
// .toArray(Coordinate[]::new);
|
||||
// Polygon polygonB = geometryFactory.createPolygon(coordsB);
|
||||
// // 使用 JTS 判断是否相交
|
||||
// return polygonA.intersects(polygonB);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取平面坐标数组
|
||||
// *
|
||||
// * @param planeLists 平面坐标列表
|
||||
// * @return 平面坐标数组
|
||||
// */
|
||||
// public static Coordinate[] getPlaneCoordinate(List<List<Double>> planeLists) {
|
||||
// return planeLists.stream().map(planeList ->
|
||||
// new Coordinate(planeList.getFirst(), planeList.get(1)))
|
||||
// .toList().toArray(new Coordinate[0]);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 获取二维坐标
|
||||
// *
|
||||
// * @param geometry 几何对象
|
||||
// * @return 二维坐标
|
||||
// */
|
||||
// public static List<List<Double>> getTwoDimensionalCoordinates(FacGeometry geometry) {
|
||||
// String type = geometry.getType();
|
||||
// List<Object> coordinates = geometry.getCoordinates();
|
||||
// return switch (type) {
|
||||
// case GeoJsonConstant.POINT -> throw new ServiceException("点位无法创建方阵", HttpStatus.BAD_REQUEST);
|
||||
// case GeoJsonConstant.LINE -> coordinates.stream()
|
||||
// .filter(obj -> obj instanceof List<?>)
|
||||
// .map(obj -> ((List<?>) obj).stream()
|
||||
// .filter(num -> num instanceof Number)
|
||||
// .map(num -> ((Number) num).doubleValue())
|
||||
// .collect(Collectors.toList()))
|
||||
// .collect(Collectors.toList());
|
||||
// case GeoJsonConstant.POLYGON -> coordinates.stream()
|
||||
// .filter(obj -> obj instanceof List<?>)
|
||||
// .flatMap(obj -> ((List<?>) obj).stream())
|
||||
// .filter(pointObj -> pointObj instanceof List<?>)
|
||||
// .map(pointObj -> ((List<?>) pointObj).stream()
|
||||
// .filter(num -> num instanceof Number)
|
||||
// .map(num -> ((Number) num).doubleValue())
|
||||
// .collect(Collectors.toList()))
|
||||
// .collect(Collectors.toList());
|
||||
// default -> throw new ServiceException("暂不支持该类型", HttpStatus.BAD_REQUEST);
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 匹配最近的点,获取该点的名称
|
||||
// *
|
||||
// * @param polygon 平面
|
||||
// * @param points 点列表集合
|
||||
// * @return 最近点的名称
|
||||
// */
|
||||
// public static String findNearestPointText(List<List<Double>> polygon, List<FacFeatureByPoint> points) {
|
||||
// if (polygon == null || polygon.size() < 3 || points == null || points.isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
// // 1. 构建 Polygon
|
||||
// Coordinate[] polygonCoords = polygon.stream()
|
||||
// .map(coord -> new Coordinate(coord.getFirst(), coord.get(1)))
|
||||
// .toArray(Coordinate[]::new);
|
||||
// Polygon jtsPolygon = geometryFactory.createPolygon(polygonCoords);
|
||||
// // 2. 构建空间索引(JTS STRtree)
|
||||
// STRtree spatialIndex = new STRtree();
|
||||
// Map<Coordinate, FacFeatureByPoint> coordToFeatureMap = new HashMap<>();
|
||||
// for (FacFeatureByPoint feature : points) {
|
||||
// List<Double> coords = feature.getGeometry().getCoordinates();
|
||||
// if (coords == null || coords.size() != 2) continue;
|
||||
// Coordinate coord = new Coordinate(coords.get(0), coords.get(1));
|
||||
// Point point = geometryFactory.createPoint(coord);
|
||||
// // 用点的 Envelope 加入索引
|
||||
// spatialIndex.insert(point.getEnvelopeInternal(), point);
|
||||
// coordToFeatureMap.put(coord, feature);
|
||||
// }
|
||||
// // 3. 查询距离 polygon 最近的点
|
||||
// // 用 polygon 中心点附近构造 Envelope(扩大一些范围)
|
||||
// Envelope searchEnv = jtsPolygon.getEnvelopeInternal();
|
||||
// searchEnv.expandBy(10); // 扩大搜索半径
|
||||
// @SuppressWarnings("unchecked")
|
||||
// List<Point> candidatePoints = spatialIndex.query(searchEnv);
|
||||
// double minDistance = Double.MAX_VALUE;
|
||||
// Coordinate nearestCoord = null;
|
||||
// for (Point point : candidatePoints) {
|
||||
// double distance = point.distance(jtsPolygon);
|
||||
// if (distance < minDistance) {
|
||||
// minDistance = distance;
|
||||
// nearestCoord = point.getCoordinate();
|
||||
// }
|
||||
// }
|
||||
// if (nearestCoord != null) {
|
||||
// FacFeatureByPoint nearestFeature = coordToFeatureMap.get(nearestCoord);
|
||||
// if (nearestFeature != null && nearestFeature.getProperties() != null) {
|
||||
// return nearestFeature.getProperties().getText();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 匹配最近的面,获取该面的信息
|
||||
// *
|
||||
// * @param pointFeature 点位
|
||||
// * @param polygons 平面列表
|
||||
// * @return 最近面的信息
|
||||
// */
|
||||
// public static FacFeatureByPlane findNearestOrContainingPolygon(
|
||||
// FacFeatureByPoint pointFeature,
|
||||
// List<FacFeatureByPlane> polygons
|
||||
// ) {
|
||||
// if (pointFeature == null || polygons == null || polygons.isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
// List<Double> coords = pointFeature.getGeometry().getCoordinates();
|
||||
// if (coords == null || coords.size() != 2) return null;
|
||||
// Coordinate pointCoord = new Coordinate(coords.get(0), coords.get(1));
|
||||
// Point point = geometryFactory.createPoint(pointCoord);
|
||||
// FacFeatureByPlane nearestPolygon = null;
|
||||
// double minDistance = Double.MAX_VALUE;
|
||||
// for (FacFeatureByPlane polygonFeature : polygons) {
|
||||
// if (polygonFeature == null || polygonFeature.getGeometry() == null) {
|
||||
// continue; // 跳过空对象
|
||||
// }
|
||||
// List<List<Double>> polyCoords = polygonFeature.getGeometry().getCoordinates().getFirst();
|
||||
// Coordinate[] polygonCoords = polyCoords.stream()
|
||||
// .map(c -> new Coordinate(c.getFirst(), c.get(1)))
|
||||
// .toArray(Coordinate[]::new);
|
||||
// Polygon polygon = geometryFactory.createPolygon(polygonCoords);
|
||||
// // 优先使用包含点的 polygon
|
||||
// if (polygon.contains(point)) {
|
||||
// return polygonFeature;
|
||||
// }
|
||||
// double distance = polygon.distance(point);
|
||||
// if (distance < minDistance) {
|
||||
// minDistance = distance;
|
||||
// nearestPolygon = polygonFeature;
|
||||
// }
|
||||
// }
|
||||
// return nearestPolygon;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 判断一个点是否在多个区域中,返回第一个匹配区域的点集合(否则 null)
|
||||
// *
|
||||
// * @param lat 纬度
|
||||
// * @param lng 经度
|
||||
// * @param rangeListJson 多边形列表,每个为 JSON 数组(多边形的点数组)
|
||||
// * @return 匹配区域的 List<Point>,否则 null
|
||||
// */
|
||||
// public static List<GeoPoint> findMatchingRange(String lat, String lng, List<String> rangeListJson) {
|
||||
// double latitude = Double.parseDouble(lat);
|
||||
// double longitude = Double.parseDouble(lng);
|
||||
// Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
|
||||
// for (String rangeJson : rangeListJson) {
|
||||
// List<GeoPoint> polygonPoints = JSONUtil.toList(rangeJson, GeoPoint.class);
|
||||
// if (polygonPoints.size() < 3) continue; // 不是有效多边形
|
||||
//
|
||||
// Polygon polygon = buildPolygon(polygonPoints);
|
||||
// if (polygon.contains(point)) {
|
||||
// return polygonPoints; // 找到匹配范围
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 将点集合转换为 JTS 多边形
|
||||
// */
|
||||
// private static Polygon buildPolygon(List<GeoPoint> points) {
|
||||
// Coordinate[] coordinates = points.stream()
|
||||
// .map(p -> new Coordinate(p.getLng(), p.getLat()))
|
||||
// .toArray(Coordinate[]::new);
|
||||
//
|
||||
// // 需要闭合坐标环(首尾相连)
|
||||
// if (!coordinates[0].equals2D(coordinates[coordinates.length - 1])) {
|
||||
// Coordinate[] closed = new Coordinate[coordinates.length + 1];
|
||||
// System.arraycopy(coordinates, 0, closed, 0, coordinates.length);
|
||||
// closed[closed.length - 1] = coordinates[0];
|
||||
// coordinates = closed;
|
||||
// }
|
||||
//
|
||||
// LinearRing shell = geometryFactory.createLinearRing(coordinates);
|
||||
// return geometryFactory.createPolygon(shell);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -0,0 +1,24 @@
|
||||
package org.dromara.system.api.utils;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
* @date 2025/5/30 14:55
|
||||
*/
|
||||
public class JsonDimensionUtil {
|
||||
|
||||
/**
|
||||
* 判断 JSONArray 的嵌套维度
|
||||
*
|
||||
* @param array 需要判断的 JSONArray
|
||||
* @return 返回维度层级:1 表示一维,2 表示二维,3 表示三维 ...
|
||||
*/
|
||||
public static int getJsonArrayDepth(Object array) {
|
||||
if (array instanceof JSONArray jsonArray && !jsonArray.isEmpty()) {
|
||||
return 1 + getJsonArrayDepth(jsonArray.getFirst());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
//package org.dromara.system.api.utils;
|
||||
//
|
||||
//import cn.hutool.core.collection.CollUtil;
|
||||
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
//
|
||||
//import java.util.Collections;
|
||||
//import java.util.List;
|
||||
//import java.util.function.Function;
|
||||
//
|
||||
///**
|
||||
// * @author lilemy
|
||||
// * @date 2025/5/28 11:25
|
||||
// */
|
||||
//public class PageConvertUtil {
|
||||
//
|
||||
// /**
|
||||
// * 将 Page<T> 转换为 Page<V>
|
||||
// *
|
||||
// * @param source 原始分页数据
|
||||
// * @param mapper 实体 -> VO 的转换函数
|
||||
// * @return Page<V>
|
||||
// */
|
||||
// public static <T, V> Page<V> convert(Page<T> source, Function<T, V> mapper) {
|
||||
// Page<V> target = new Page<>(source.getCurrent(), source.getSize(), source.getTotal());
|
||||
// if (CollUtil.isEmpty(source.getRecords())) {
|
||||
// target.setRecords(Collections.emptyList());
|
||||
// } else {
|
||||
// List<V> voList = source.getRecords().stream().map(mapper).toList();
|
||||
// target.setRecords(voList);
|
||||
// }
|
||||
// return target;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -58,18 +58,19 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.38</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.hutool</groupId>-->
|
||||
<!-- <artifactId>hutool-http</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-extra</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.hutool</groupId>-->
|
||||
<!-- <artifactId>hutool-extra</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
||||
@ -27,4 +27,9 @@ public class RemoteProjectServiceImpl implements RemoteProjectService {
|
||||
public String selectProjectNameById(Long projectId) {
|
||||
return projectService.getProjectNameById(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validAuth(Long projectId, Long userId) {
|
||||
projectService.validAuth(projectId, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -488,4 +488,10 @@ public class RemoteUserServiceImpl implements RemoteUserService {
|
||||
.collect(Collectors.toMap(SysPost::getPostId, SysPost::getPostName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteUserVo selectUserByPhonenumber(String phone) {
|
||||
SysUserVo sysUserVo = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phone));
|
||||
return BeanUtil.copyProperties(sysUserVo, RemoteUserVo.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.ops;
|
||||
package org.dromara;
|
||||
|
||||
|
||||
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.ops.personnel.controller;
|
||||
package org.dromara.personnel.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -17,9 +17,9 @@ import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.ops.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.ops.personnel.domain.bo.OpsUserBo;
|
||||
import org.dromara.ops.personnel.service.IOpsUserService;
|
||||
import org.dromara.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.personnel.domain.bo.OpsUserBo;
|
||||
import org.dromara.personnel.service.IOpsUserService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
@ -0,0 +1,106 @@
|
||||
package org.dromara.personnel.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.personnel.domain.vo.OpsUserFilesVo;
|
||||
import org.dromara.personnel.domain.bo.OpsUserFilesBo;
|
||||
import org.dromara.personnel.service.IOpsUserFilesService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 运维人员文件
|
||||
* 前端访问路由地址为:/personnel/userFiles
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/userFiles")
|
||||
public class OpsUserFilesController extends BaseController {
|
||||
|
||||
private final IOpsUserFilesService opsUserFilesService;
|
||||
|
||||
/**
|
||||
* 查询运维人员文件列表
|
||||
*/
|
||||
@SaCheckPermission("personnel:userFiles:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<OpsUserFilesVo> list(OpsUserFilesBo bo, PageQuery pageQuery) {
|
||||
return opsUserFilesService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出运维人员文件列表
|
||||
*/
|
||||
@SaCheckPermission("personnel:userFiles:export")
|
||||
@Log(title = "运维人员文件", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(OpsUserFilesBo bo, HttpServletResponse response) {
|
||||
List<OpsUserFilesVo> list = opsUserFilesService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "运维人员文件", OpsUserFilesVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运维人员文件详细信息
|
||||
*
|
||||
* @param opsUserId 主键
|
||||
*/
|
||||
@SaCheckPermission("personnel:userFiles:query")
|
||||
@GetMapping("/{opsUserId}")
|
||||
public R<OpsUserFilesVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable("opsUserId") Long opsUserId) {
|
||||
return R.ok(opsUserFilesService.queryById(opsUserId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增运维人员文件
|
||||
*/
|
||||
@SaCheckPermission("personnel:userFiles:add")
|
||||
@Log(title = "运维人员文件", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody OpsUserFilesBo bo) {
|
||||
return toAjax(opsUserFilesService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改运维人员文件
|
||||
*/
|
||||
@SaCheckPermission("personnel:userFiles:edit")
|
||||
@Log(title = "运维人员文件", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody OpsUserFilesBo bo) {
|
||||
return toAjax(opsUserFilesService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除运维人员文件
|
||||
*
|
||||
* @param opsUserIds 主键串
|
||||
*/
|
||||
@SaCheckPermission("personnel:userFiles:remove")
|
||||
@Log(title = "运维人员文件", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{opsUserIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable("opsUserIds") Long[] opsUserIds) {
|
||||
return toAjax(opsUserFilesService.deleteWithValidByIds(List.of(opsUserIds), true));
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.ops.personnel.domain;
|
||||
package org.dromara.personnel.domain;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
@ -48,10 +48,6 @@ public class OpsUser extends BaseEntity {
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 分包公司id
|
||||
*/
|
||||
private Long contractorId;
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
@ -0,0 +1,46 @@
|
||||
package org.dromara.personnel.domain;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 运维人员文件对象 ops_user_files
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("ops_user_files")
|
||||
public class OpsUserFiles extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 运维人员id
|
||||
*/
|
||||
@TableId(value = "ops_user_id")
|
||||
private Long opsUserId;
|
||||
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
private Long fileId;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 文件类型(1、特种作业证图片)
|
||||
*/
|
||||
private String fileType;
|
||||
|
||||
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
package org.dromara.ops.personnel.domain.bo;
|
||||
package org.dromara.personnel.domain.bo;
|
||||
|
||||
import org.dromara.ops.personnel.domain.OpsUser;
|
||||
import org.dromara.personnel.domain.OpsUser;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
@ -35,7 +35,7 @@ public class OpsUserBo extends BaseEntity {
|
||||
/**
|
||||
* 系统用户id
|
||||
*/
|
||||
@NotNull(message = "系统用户id不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
@NotNull(message = "系统用户id不能为空", groups = { EditGroup.class })
|
||||
private Long sysUserId;
|
||||
|
||||
/**
|
||||
@ -50,22 +50,18 @@ public class OpsUserBo extends BaseEntity {
|
||||
@NotNull(message = "项目id不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 分包公司id
|
||||
*/
|
||||
@NotNull(message = "分包公司id不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long contractorId;
|
||||
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
*/
|
||||
@NotNull(message = "班组id不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotNull(message = "班组id不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long teamId;
|
||||
|
||||
/**
|
||||
* 班组名称
|
||||
*/
|
||||
@NotBlank(message = "班组名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotBlank(message = "班组名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String teamName;
|
||||
|
||||
/**
|
||||
@ -0,0 +1,47 @@
|
||||
package org.dromara.personnel.domain.bo;
|
||||
|
||||
import org.dromara.personnel.domain.OpsUserFiles;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 运维人员文件业务对象 ops_user_files
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = OpsUserFiles.class, reverseConvertGenerate = false)
|
||||
public class OpsUserFilesBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 运维人员id
|
||||
*/
|
||||
private Long opsUserId;
|
||||
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
@NotNull(message = "文件id不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long fileId;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
@NotBlank(message = "文件名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 文件类型(1、特种作业证图片)
|
||||
*/
|
||||
@NotBlank(message = "文件类型(1、特种作业证图片)不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String fileType;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package org.dromara.personnel.domain.vo;
|
||||
|
||||
import org.dromara.personnel.domain.OpsUserFiles;
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 运维人员文件视图对象 ops_user_files
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = OpsUserFiles.class)
|
||||
public class OpsUserFilesVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 运维人员id
|
||||
*/
|
||||
@ExcelProperty(value = "运维人员id")
|
||||
private Long opsUserId;
|
||||
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
@ExcelProperty(value = "文件id")
|
||||
private Long fileId;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
@ExcelProperty(value = "文件名称")
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 文件类型(1、特种作业证图片)
|
||||
*/
|
||||
@ExcelProperty(value = "文件类型", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "1=、特种作业证图片")
|
||||
private String fileType;
|
||||
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.ops.personnel.domain.vo;
|
||||
package org.dromara.personnel.domain.vo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -8,7 +8,7 @@ import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.ops.personnel.domain.OpsUser;
|
||||
import org.dromara.personnel.domain.OpsUser;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@ -58,11 +58,7 @@ public class OpsUserVo implements Serializable {
|
||||
@ExcelProperty(value = "项目id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 分包公司id
|
||||
*/
|
||||
@ExcelProperty(value = "分包公司id")
|
||||
private Long contractorId;
|
||||
|
||||
|
||||
/**
|
||||
* 班组id
|
||||
@ -0,0 +1,15 @@
|
||||
package org.dromara.personnel.mapper;
|
||||
|
||||
import org.dromara.personnel.domain.OpsUserFiles;
|
||||
import org.dromara.personnel.domain.vo.OpsUserFilesVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 运维人员文件Mapper接口
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
public interface OpsUserFilesMapper extends BaseMapperPlus<OpsUserFiles, OpsUserFilesVo> {
|
||||
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.ops.personnel.mapper;
|
||||
package org.dromara.personnel.mapper;
|
||||
|
||||
import org.dromara.ops.personnel.domain.OpsUser;
|
||||
import org.dromara.ops.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.personnel.domain.OpsUser;
|
||||
import org.dromara.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
@ -0,0 +1,69 @@
|
||||
package org.dromara.personnel.service;
|
||||
|
||||
import org.dromara.personnel.domain.OpsUserFiles;
|
||||
import org.dromara.personnel.domain.vo.OpsUserFilesVo;
|
||||
import org.dromara.personnel.domain.bo.OpsUserFilesBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 运维人员文件Service接口
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
public interface IOpsUserFilesService {
|
||||
|
||||
/**
|
||||
* 查询运维人员文件
|
||||
*
|
||||
* @param opsUserId 主键
|
||||
* @return 运维人员文件
|
||||
*/
|
||||
OpsUserFilesVo queryById(Long opsUserId);
|
||||
|
||||
/**
|
||||
* 分页查询运维人员文件列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 运维人员文件分页列表
|
||||
*/
|
||||
TableDataInfo<OpsUserFilesVo> queryPageList(OpsUserFilesBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的运维人员文件列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 运维人员文件列表
|
||||
*/
|
||||
List<OpsUserFilesVo> queryList(OpsUserFilesBo bo);
|
||||
|
||||
/**
|
||||
* 新增运维人员文件
|
||||
*
|
||||
* @param bo 运维人员文件
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(OpsUserFilesBo bo);
|
||||
|
||||
/**
|
||||
* 修改运维人员文件
|
||||
*
|
||||
* @param bo 运维人员文件
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(OpsUserFilesBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除运维人员文件信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
package org.dromara.ops.personnel.service;
|
||||
package org.dromara.personnel.service;
|
||||
|
||||
import org.dromara.ops.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.ops.personnel.domain.bo.OpsUserBo;
|
||||
import org.dromara.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.personnel.domain.bo.OpsUserBo;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
@ -0,0 +1,134 @@
|
||||
package org.dromara.personnel.service.impl;
|
||||
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.personnel.domain.bo.OpsUserFilesBo;
|
||||
import org.dromara.personnel.domain.vo.OpsUserFilesVo;
|
||||
import org.dromara.personnel.domain.OpsUserFiles;
|
||||
import org.dromara.personnel.mapper.OpsUserFilesMapper;
|
||||
import org.dromara.personnel.service.IOpsUserFilesService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 运维人员文件Service业务层处理
|
||||
*
|
||||
* @author LionLi
|
||||
* @date 2025-09-17
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class OpsUserFilesServiceImpl implements IOpsUserFilesService {
|
||||
|
||||
private final OpsUserFilesMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询运维人员文件
|
||||
*
|
||||
* @param opsUserId 主键
|
||||
* @return 运维人员文件
|
||||
*/
|
||||
@Override
|
||||
public OpsUserFilesVo queryById(Long opsUserId){
|
||||
return baseMapper.selectVoById(opsUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询运维人员文件列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 运维人员文件分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<OpsUserFilesVo> queryPageList(OpsUserFilesBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<OpsUserFiles> lqw = buildQueryWrapper(bo);
|
||||
Page<OpsUserFilesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的运维人员文件列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 运维人员文件列表
|
||||
*/
|
||||
@Override
|
||||
public List<OpsUserFilesVo> queryList(OpsUserFilesBo bo) {
|
||||
LambdaQueryWrapper<OpsUserFiles> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<OpsUserFiles> buildQueryWrapper(OpsUserFilesBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<OpsUserFiles> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(OpsUserFiles::getOpsUserId);
|
||||
lqw.eq(bo.getFileId() != null, OpsUserFiles::getFileId, bo.getFileId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getFileName()), OpsUserFiles::getFileName, bo.getFileName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getFileType()), OpsUserFiles::getFileType, bo.getFileType());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增运维人员文件
|
||||
*
|
||||
* @param bo 运维人员文件
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(OpsUserFilesBo bo) {
|
||||
OpsUserFiles add = MapstructUtils.convert(bo, OpsUserFiles.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setOpsUserId(add.getOpsUserId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改运维人员文件
|
||||
*
|
||||
* @param bo 运维人员文件
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(OpsUserFilesBo bo) {
|
||||
OpsUserFiles update = MapstructUtils.convert(bo, OpsUserFiles.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(OpsUserFiles entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除运维人员文件信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
package org.dromara.ops.personnel.service.impl;
|
||||
package org.dromara.personnel.service.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
@ -9,12 +12,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.system.api.RemoteProjectService;
|
||||
import org.dromara.system.api.RemoteUserService;
|
||||
import org.dromara.system.api.domain.vo.RemoteUserVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.ops.personnel.domain.bo.OpsUserBo;
|
||||
import org.dromara.ops.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.ops.personnel.domain.OpsUser;
|
||||
import org.dromara.ops.personnel.mapper.OpsUserMapper;
|
||||
import org.dromara.ops.personnel.service.IOpsUserService;
|
||||
import org.dromara.personnel.domain.bo.OpsUserBo;
|
||||
import org.dromara.personnel.domain.vo.OpsUserVo;
|
||||
import org.dromara.personnel.domain.OpsUser;
|
||||
import org.dromara.personnel.mapper.OpsUserMapper;
|
||||
import org.dromara.personnel.service.IOpsUserService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -33,6 +41,10 @@ public class OpsUserServiceImpl implements IOpsUserService {
|
||||
|
||||
private final OpsUserMapper baseMapper;
|
||||
|
||||
private final RemoteProjectService remoteProjectService;
|
||||
@Autowired
|
||||
private RemoteUserService remoteUserService;
|
||||
|
||||
/**
|
||||
* 查询运维人员
|
||||
*
|
||||
@ -78,7 +90,6 @@ public class OpsUserServiceImpl implements IOpsUserService {
|
||||
lqw.eq(bo.getSysUserId() != null, OpsUser::getSysUserId, bo.getSysUserId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getUserName()), OpsUser::getUserName, bo.getUserName());
|
||||
lqw.eq(bo.getProjectId() != null, OpsUser::getProjectId, bo.getProjectId());
|
||||
lqw.eq(bo.getContractorId() != null, OpsUser::getContractorId, bo.getContractorId());
|
||||
lqw.eq(bo.getTeamId() != null, OpsUser::getTeamId, bo.getTeamId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTeamName()), OpsUser::getTeamName, bo.getTeamName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OpsUser::getStatus, bo.getStatus());
|
||||
@ -120,6 +131,13 @@ public class OpsUserServiceImpl implements IOpsUserService {
|
||||
public Boolean insertByBo(OpsUserBo bo) {
|
||||
OpsUser add = MapstructUtils.convert(bo, OpsUser.class);
|
||||
validEntityBeforeSave(add);
|
||||
Long userId = LoginHelper.getUserId();
|
||||
remoteProjectService.validAuth(bo.getProjectId(), userId);
|
||||
String phone = add.getPhone();
|
||||
RemoteUserVo userVo = remoteUserService.selectUserByPhonenumber(phone);
|
||||
if (userVo == null) {
|
||||
throw new ServiceException("当前用户未在系统注册", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.personnel.mapper.OpsUserFilesMapper">
|
||||
|
||||
</mapper>
|
||||
@ -2,6 +2,6 @@
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.ops.personnel.mapper.OpsUserMapper">
|
||||
<mapper namespace="org.dromara.personnel.mapper.OpsUserMapper">
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user