Merge branch 'refs/heads/dev' into updateMenu
This commit is contained in:
@ -5,6 +5,8 @@ import cn.hutool.captcha.AbstractCaptcha;
|
||||
import cn.hutool.captcha.generator.CodeGenerator;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -76,7 +78,7 @@ public class CaptchaController {
|
||||
SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, map);
|
||||
if (!smsResponse.isSuccess()) {
|
||||
log.error("验证码短信发送异常 => {}", smsResponse);
|
||||
return R.fail(smsResponse.getData().toString());
|
||||
return R.fail(parseData(smsResponse));
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
@ -140,4 +142,35 @@ public class CaptchaController {
|
||||
return R.ok(captchaVo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static String parseData(SmsResponse smsResponse ) {
|
||||
try {
|
||||
JSONObject json = JSONUtil.parseObj(smsResponse.getData());
|
||||
// 核心:用 JsonUtil 解析 data,通过键路径 "Response.SendStatusSet[0].Code" 提取字段
|
||||
// 键路径规则:层级用 "." 分隔,列表索引用 "[0]" 表示(第 1 个元素)
|
||||
String code = json.getByPath("Response.SendStatusSet[0].Code", String.class);
|
||||
System.out.println("错误码:" + code); // 输出:FailedOperation.InsufficientBalanceInSmsPackage
|
||||
return convert(code);
|
||||
} catch (Exception e) {
|
||||
return "短信发送未知错误";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String convert(String code) {
|
||||
return switch (code) {
|
||||
case "FailedOperation.InsufficientBalanceInSmsPackage" -> "套餐包余量不足,请购买套餐包";
|
||||
case "InternalError.SendAndRecvFail" -> "短信收发超时,请检查您的网络是否有波动";
|
||||
case "InvalidParameterValue.IncorrectPhoneNumber" -> "手机号格式错误";
|
||||
case "LimitExceeded.AppCountryOrRegionDailyLimit" -> "业务短信国家/地区日下发条数超过设定的上限";
|
||||
case "LimitExceeded.AppDailyLimit" -> "业务短信日下发条数超过设定的上限";
|
||||
case "LimitExceeded.PhoneNumberDailyLimit" -> "单个手机号日下发短信条数超过设定的上限";
|
||||
case "UnauthorizedOperation.ServiceSuspendDueToArrears" -> "欠费被停止服务";
|
||||
case "UnsupportedOperation.UnsupportedRegion" -> "不支持该地区短信下发";
|
||||
default -> "短信发送未知错误";
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -41,10 +41,10 @@ snail-job:
|
||||
spring:
|
||||
ai:
|
||||
dashscope:
|
||||
api-key: xxx
|
||||
api-key: sk-8d8df92fcbac4bd2922edba30b0bb8fa
|
||||
chat:
|
||||
options:
|
||||
model: qwen-plus
|
||||
model: qwen3-max
|
||||
datasource:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
|
||||
|
||||
@ -76,9 +76,9 @@ spring:
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 200MB
|
||||
max-file-size: 1024MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 200MB
|
||||
max-request-size: 1024MB
|
||||
mvc:
|
||||
# 设置静态资源路径 防止所有请求都去查静态资源
|
||||
static-path-pattern: /static/**
|
||||
|
||||
@ -1,14 +1,23 @@
|
||||
package org.dromara.test;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.manager.recognizermanager.RecognizerManager;
|
||||
import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum;
|
||||
import org.dromara.manager.recognizermanager.vo.RecognizeVo;
|
||||
import org.dromara.progress.domain.PgsProgressPlanDetail;
|
||||
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo;
|
||||
import org.dromara.progress.service.IPgsProgressPlanDetailService;
|
||||
import org.dromara.progress.service.IPgsProgressPlanService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author lilemy
|
||||
@ -21,6 +30,12 @@ public class RecognizerTest {
|
||||
@Resource
|
||||
private RecognizerManager recognizerManager;
|
||||
|
||||
@Resource
|
||||
private IPgsProgressPlanDetailService progressPlanDetailService;
|
||||
|
||||
@Resource
|
||||
private IPgsProgressPlanService progressPlanService;
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
RecognizeVo recognize = recognizerManager.recognize("http://xny.yj-3d.com:7363/file/tif/20250625160218orthophoto.png", List.of(RecognizerTypeEnum.PANEL));
|
||||
@ -31,4 +46,39 @@ public class RecognizerTest {
|
||||
void testChange() {
|
||||
recognizerManager.convertCoordinate("http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/11/11/d48767a62bc04867a552e06ba6712004.tif", List.of());
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkNumber() {
|
||||
List<PgsProgressPlanDetail> detailList = progressPlanDetailService.list();
|
||||
List<PgsProgressPlanDetail> planDetailList = detailList.stream()
|
||||
.filter(detail -> StringUtils.isNotBlank(detail.getFinishedDetail()))
|
||||
.toList();
|
||||
Map<String, List<PgsProgressPlanDetail>> collect = planDetailList.stream()
|
||||
.collect(Collectors.groupingBy(PgsProgressPlanDetail::getFinishedDetail));
|
||||
// 遍历分组结果,输出重复项
|
||||
for (Map.Entry<String, List<PgsProgressPlanDetail>> entry : collect.entrySet()) {
|
||||
String fieldValue = entry.getKey();
|
||||
List<PgsProgressPlanDetail> duplicates = entry.getValue();
|
||||
if (duplicates.size() > 1) { // 筛选出有重复的字段值
|
||||
PgsProgressPlanDetail first = duplicates.getFirst();
|
||||
Long id = first.getId();
|
||||
Long planId = first.getProgressPlanId();
|
||||
progressPlanService.removeById(planId);
|
||||
progressPlanDetailService.removeById(id);
|
||||
System.out.println("重复对象的对象:" + duplicates.stream().map(PgsProgressPlanDetail::getId).toList());
|
||||
}
|
||||
}
|
||||
for (PgsProgressPlanDetail detail : detailList) {
|
||||
BigDecimal aiFill = detail.getFinishedNumber();
|
||||
String finishedDetail = detail.getFinishedDetail();
|
||||
if (StringUtils.isBlank(finishedDetail)) {
|
||||
continue;
|
||||
}
|
||||
// log.info("id: {}, finishedDetail: {}", detail.getId(), finishedDetail);
|
||||
List<PgsProgressPlanDetailFinishedVo> finishedVos = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class);
|
||||
if (aiFill.compareTo(BigDecimal.valueOf(finishedVos.size())) != 0) {
|
||||
log.info("数量异常:{}:{}", detail.getId(), detail.getProgressCategoryId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,18 @@ public class AsyncConfig implements AsyncConfigurer {
|
||||
return executor;
|
||||
}
|
||||
|
||||
// 解压线程池(大文件操作,不需要太多线程)
|
||||
@Bean("unzipExecutor")
|
||||
public Executor unzipExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(2);
|
||||
executor.setMaxPoolSize(4);
|
||||
executor.setQueueCapacity(10);
|
||||
executor.setThreadNamePrefix("unzip-");
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行异常处理
|
||||
*/
|
||||
|
||||
@ -91,7 +91,7 @@ public class PlusDataPermissionHandler {
|
||||
DataPermissionHelper.setVariable("user", currentUser);
|
||||
}
|
||||
// 如果是超级管理员或租户管理员,则不过滤数据
|
||||
if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
|
||||
if (LoginHelper.isSuperAdmin()) {
|
||||
return where;
|
||||
}
|
||||
// 构造数据过滤条件的 SQL 片段
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.dromara.common.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MessageUtils;
|
||||
@ -9,6 +10,8 @@ import org.dromara.contractor.domain.SubConstructionUser;
|
||||
import org.dromara.mobileAttendanceMachine.DeviceMessageSender;
|
||||
import org.dromara.mobileAttendanceMachine.KqjEntity;
|
||||
import org.dromara.project.domain.BusAttendanceMachine;
|
||||
import org.dromara.project.domain.BusAttendanceMachineRepeat;
|
||||
import org.dromara.project.service.IBusAttendanceMachineRepeatService;
|
||||
import org.dromara.project.service.IBusAttendanceMachineService;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
@ -19,6 +22,7 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
@ -36,6 +40,9 @@ public class AsyncUtil {
|
||||
@Lazy
|
||||
private IBusAttendanceMachineService attendanceMachineService;
|
||||
|
||||
@Resource
|
||||
private IBusAttendanceMachineRepeatService busAttendanceMachineRepeatService;
|
||||
|
||||
//发送短信
|
||||
@Async
|
||||
public void sendSms(List<String> mobileList, String config) {
|
||||
@ -63,22 +70,107 @@ public class AsyncUtil {
|
||||
public void sendPersonnel(Long teamId, SubConstructionUser constructionUser) {
|
||||
SysOssVo byId = ossService.getById(Long.valueOf(constructionUser.getFacePic()));
|
||||
List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", teamId).list();
|
||||
|
||||
ArrayList<BusAttendanceMachineRepeat> repeats = new ArrayList<>();
|
||||
for (BusAttendanceMachine machine : list) {
|
||||
deviceMessageSender.sendPersonnelInformation(machine.getSn(), constructionUser.getSysUserId().toString(), constructionUser.getUserName(), byId.getUrl());
|
||||
Boolean b = deviceMessageSender.sendPersonnelInformation(machine.getSn(),
|
||||
constructionUser.getSysUserId().toString(), constructionUser.getUserName(), byId.getUrl());
|
||||
if (!b) {
|
||||
//记录下来重连时下发
|
||||
BusAttendanceMachineRepeat repeat = new BusAttendanceMachineRepeat();
|
||||
repeat.setSn(machine.getSn());
|
||||
repeat.setUserId(constructionUser.getSysUserId().toString());
|
||||
repeat.setUserName(constructionUser.getUserName());
|
||||
repeat.setUrl(byId.getUrl());
|
||||
repeat.setType("1");
|
||||
repeats.add(repeat);
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(repeats)) {
|
||||
busAttendanceMachineRepeatService.saveBatch(repeats);
|
||||
}
|
||||
}
|
||||
|
||||
//删除考勤人员
|
||||
@Async
|
||||
public void deletePersonnel(SubConstructionUser constructionUser) {
|
||||
ArrayList<BusAttendanceMachineRepeat> repeats = new ArrayList<>();
|
||||
List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", constructionUser.getTeamId()).list();
|
||||
for (BusAttendanceMachine machine : list) {
|
||||
try {
|
||||
deviceMessageSender.deleteUser(machine.getSn(), constructionUser.getSysUserId().toString());
|
||||
KqjEntity.CommonResponse commonResponse = deviceMessageSender.deleteUser(machine.getSn(), constructionUser.getSysUserId().toString());
|
||||
int code = commonResponse.getData().getCode();
|
||||
if (code != 0) {
|
||||
//记录下来重连时下发
|
||||
BusAttendanceMachineRepeat repeat = new BusAttendanceMachineRepeat();
|
||||
repeat.setSn(machine.getSn());
|
||||
repeat.setUserId(constructionUser.getSysUserId().toString());
|
||||
repeat.setUserName(constructionUser.getUserName());
|
||||
repeat.setUrl(null);
|
||||
repeat.setType("2");
|
||||
repeats.add(repeat);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("删除考勤人员异常", e);
|
||||
BusAttendanceMachineRepeat repeat = new BusAttendanceMachineRepeat();
|
||||
repeat.setSn(machine.getSn());
|
||||
repeat.setUserId(constructionUser.getSysUserId().toString());
|
||||
repeat.setUserName(constructionUser.getUserName());
|
||||
repeat.setUrl(null);
|
||||
repeat.setType("2");
|
||||
repeats.add(repeat);
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(repeats)) {
|
||||
busAttendanceMachineRepeatService.saveBatch(repeats);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//重新下发人员
|
||||
@Async
|
||||
public void repeatSend(String sn) {
|
||||
List<BusAttendanceMachineRepeat> list = busAttendanceMachineRepeatService.lambdaQuery()
|
||||
.eq(BusAttendanceMachineRepeat::getSn, sn)
|
||||
.eq(BusAttendanceMachineRepeat::getType, "1")
|
||||
.list();
|
||||
List<Long> repeatIds = new ArrayList<>();
|
||||
for (BusAttendanceMachineRepeat repeat : list) {
|
||||
Boolean b = deviceMessageSender.sendPersonnelInformation(repeat.getSn(), repeat.getUserId(), repeat.getUserName(), repeat.getUrl());
|
||||
if (b) {
|
||||
//成功删除记录
|
||||
repeatIds.add(repeat.getId());
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(repeatIds)) {
|
||||
busAttendanceMachineRepeatService.removeByIds(repeatIds);
|
||||
}
|
||||
}
|
||||
|
||||
//重新删除人员
|
||||
@Async
|
||||
public void repeatDelete(String sn) {
|
||||
List<BusAttendanceMachineRepeat> list = busAttendanceMachineRepeatService.lambdaQuery()
|
||||
.eq(BusAttendanceMachineRepeat::getSn, sn)
|
||||
.eq(BusAttendanceMachineRepeat::getType, "2")
|
||||
.list();
|
||||
List<Long> repeatIds = new ArrayList<>();
|
||||
for (BusAttendanceMachineRepeat repeat : list) {
|
||||
try {
|
||||
KqjEntity.CommonResponse commonResponse = deviceMessageSender.deleteUser(repeat.getSn(), repeat.getUserId());
|
||||
int code = commonResponse.getData().getCode();
|
||||
if (code == 0) {
|
||||
//成功删除记录
|
||||
repeatIds.add(repeat.getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("删除考勤人员异常", e);
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(repeatIds)) {
|
||||
busAttendanceMachineRepeatService.removeByIds(repeatIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ 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.FacMatrix;
|
||||
import org.dromara.facility.domain.FacPhotovoltaicPanel;
|
||||
import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane;
|
||||
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
|
||||
@ -338,6 +339,29 @@ public class JSTUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配最近方阵,获取该方阵的信息
|
||||
*
|
||||
* @param pointEntity 点位
|
||||
* @param matrices 方阵列表
|
||||
* @return 最近方阵的信息
|
||||
*/
|
||||
public static FacMatrix findContainingMatrix(
|
||||
RecognizeConvertCoordinateResult pointEntity,
|
||||
List<FacMatrix> matrices
|
||||
) {
|
||||
double lng = Double.parseDouble(pointEntity.getLng());
|
||||
double lat = Double.parseDouble(pointEntity.getLat());
|
||||
Point point = geometryFactory.createPoint(new Coordinate(lng, lat));
|
||||
for (FacMatrix matrix : matrices) {
|
||||
Polygon polygon = parsePolygon(matrix.getPositions());
|
||||
if (polygon.covers(point)) { // covers 包含边界}
|
||||
return matrix;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 FacPhotovoltaicPanel.positions 转成 Polygon
|
||||
*/
|
||||
@ -376,7 +400,7 @@ public class JSTUtil {
|
||||
List<String> list = new ArrayList<>();
|
||||
list.add(s);
|
||||
List<GeoPoint> matchingRange = findMatchingRange("30.247348", "105.729797", list);
|
||||
System.out.println(matchingRange==null);
|
||||
System.out.println(matchingRange == null);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ public class SubAttendanceMachineUserServiceImpl implements ISubAttendanceMachin
|
||||
vo.setMachineId(req.getMachineId());
|
||||
vo.setContractorId(req.getContractorId());
|
||||
vo.setUserId(userVo.getUserId());
|
||||
vo.setUserName(userVo.getUserName());
|
||||
vo.setUserName(userVo.getNickName());
|
||||
if (CollUtil.isEmpty(finalUserIdList)) {
|
||||
vo.setIdentifying(0);
|
||||
} else if (finalUserIdList.contains(userVo.getUserId().toString())) {
|
||||
|
||||
@ -257,6 +257,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
|
||||
constructionUser.setTypeOfWork(dto.getTypeOfWork());
|
||||
constructionUser.setEntryDate(new Date());
|
||||
constructionUser.setFirstDate(LocalDate.now());
|
||||
constructionUser.setStatus("0");
|
||||
|
||||
int i = baseMapper.updateById(constructionUser);
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import org.dromara.drone.domain.vo.DroDroneBigPictureVo;
|
||||
import org.dromara.drone.service.IDroDroneBigPictureService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -57,6 +58,16 @@ public class DroDroneBigPictureController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "无人机大图信息", DroDroneBigPictureVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传zip文件
|
||||
*/
|
||||
@SaCheckPermission("drone:droneBigPicture:add")
|
||||
@Log(title = "无人机大图信息", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/uploadZip")
|
||||
public R<Boolean> uploadZip(@RequestPart("file") MultipartFile file, @Validated(AddGroup.class) DroDroneBigPictureBo bo) {
|
||||
return R.ok(droDroneBigPictureService.uploadZip(file, bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取无人机大图信息详细信息
|
||||
*
|
||||
@ -77,7 +88,7 @@ public class DroDroneBigPictureController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody DroDroneBigPictureBo bo) {
|
||||
return toAjax(droDroneBigPictureService.insertByBo(bo));
|
||||
return toAjax(droDroneBigPictureService.insertByBo(bo, true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -73,6 +73,11 @@ public class DroDroneBigPicture extends BaseEntity {
|
||||
*/
|
||||
private String tifFile;
|
||||
|
||||
/**
|
||||
* 来源类型
|
||||
*/
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
||||
@ -74,6 +74,11 @@ public class DroDroneBigPictureBo extends BaseEntity {
|
||||
*/
|
||||
private String tifFile;
|
||||
|
||||
/**
|
||||
* 来源类型
|
||||
*/
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
||||
@ -91,12 +91,23 @@ public class DroDroneBigPictureVo implements Serializable {
|
||||
*/
|
||||
private String recognizeResult;
|
||||
|
||||
/**
|
||||
* 识别结果列表
|
||||
*/
|
||||
private String recognizeResultStr;
|
||||
|
||||
/**
|
||||
* tif文件
|
||||
*/
|
||||
@ExcelProperty(value = "tif文件")
|
||||
private String tifFile;
|
||||
|
||||
/**
|
||||
* 来源类型
|
||||
*/
|
||||
@ExcelProperty(value = "来源类型")
|
||||
private String sourceType;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
||||
@ -7,7 +7,9 @@ import org.dromara.drone.domain.DroDroneBigPicture;
|
||||
import org.dromara.drone.domain.bo.DroDroneBigPictureBo;
|
||||
import org.dromara.drone.domain.bo.DroDroneBigPictureProgressVo;
|
||||
import org.dromara.drone.domain.vo.DroDroneBigPictureVo;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -48,10 +50,11 @@ public interface IDroDroneBigPictureService extends IService<DroDroneBigPicture>
|
||||
/**
|
||||
* 新增无人机大图信息
|
||||
*
|
||||
* @param bo 无人机大图信息
|
||||
* @param bo 无人机大图信息
|
||||
* @param isNew 是否创建新记录
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(DroDroneBigPictureBo bo);
|
||||
Boolean insertByBo(DroDroneBigPictureBo bo, Boolean isNew);
|
||||
|
||||
/**
|
||||
* 修改无人机大图信息
|
||||
@ -100,6 +103,15 @@ public interface IDroDroneBigPictureService extends IService<DroDroneBigPicture>
|
||||
*/
|
||||
Boolean compressPicture(String ossIds, List<Long> compressPicIds);
|
||||
|
||||
/**
|
||||
* 异步合成大图
|
||||
*
|
||||
* @param businessName 业务名称
|
||||
* @param imageUrls 图片URL列表
|
||||
* @return 任务id
|
||||
*/
|
||||
CompletableFuture<String> asyncAddBigPicture(String businessName, List<String> imageUrls);
|
||||
|
||||
/**
|
||||
* 异步添加压缩图片
|
||||
*
|
||||
@ -116,4 +128,22 @@ public interface IDroDroneBigPictureService extends IService<DroDroneBigPicture>
|
||||
* @return 是否成功
|
||||
*/
|
||||
CompletableFuture<Boolean> asyncUpdateCompressPicture(DroDroneBigPicture pic, DroDroneBigPicture oldPic);
|
||||
|
||||
/**
|
||||
* 上传zip文件
|
||||
*
|
||||
* @param file zip文件
|
||||
* @param bo 无人机大图信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean uploadZip(MultipartFile file, DroDroneBigPictureBo bo);
|
||||
|
||||
/**
|
||||
* 解压zip文件
|
||||
*
|
||||
* @param zipFile zip文件
|
||||
* @param tempDir 临时目录
|
||||
* @return 解压后的文件的对象存储Ids
|
||||
*/
|
||||
CompletableFuture<List<Long>> unzipAsync(File zipFile, File tempDir);
|
||||
}
|
||||
|
||||
@ -2,6 +2,10 @@ package org.dromara.drone.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.io.FileTypeUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -27,7 +31,9 @@ import org.dromara.drone.service.IDroDroneBigPictureService;
|
||||
import org.dromara.manager.dronemanager.DroneManager;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeProgressVo;
|
||||
import org.dromara.manager.dronemanager.vo.DroneImgMergeUrlVo;
|
||||
import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum;
|
||||
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailAINumberReq;
|
||||
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailRecognizerVo;
|
||||
import org.dromara.progress.service.IPgsProgressPlanDetailService;
|
||||
import org.dromara.system.domain.vo.SysOssVo;
|
||||
import org.dromara.system.service.ISysOssService;
|
||||
@ -36,7 +42,9 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
@ -54,7 +62,8 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictureMapper, DroDroneBigPicture>
|
||||
public
|
||||
class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictureMapper, DroDroneBigPicture>
|
||||
implements IDroDroneBigPictureService {
|
||||
|
||||
@Lazy
|
||||
@ -90,11 +99,34 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
BigDecimal p = progressVo.getProgress()
|
||||
.multiply(new BigDecimal("100"));
|
||||
pictureVo.setProgress(p.compareTo(BigDecimal.valueOf(100)) == 0 ?
|
||||
BigDecimal.valueOf(100) : p.setScale(4, RoundingMode.HALF_UP));
|
||||
BigDecimal.valueOf(100) : p.setScale(2, RoundingMode.HALF_UP));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("查询图片合成进度异常", e);
|
||||
}
|
||||
if (StringUtils.isNotBlank(pictureVo.getRecognizeResult())) {
|
||||
List<PgsProgressPlanDetailRecognizerVo> recognizerList =
|
||||
JSONUtil.toList(pictureVo.getRecognizeResult(), PgsProgressPlanDetailRecognizerVo.class);
|
||||
if (CollUtil.isNotEmpty(recognizerList)) {
|
||||
// 1. 按类型名称分组
|
||||
Map<String, List<PgsProgressPlanDetailRecognizerVo>> groupMap = recognizerList.stream()
|
||||
.collect(Collectors.groupingBy(r -> {
|
||||
RecognizerTypeEnum typeEnum = RecognizerTypeEnum.fromValue(r.getType());
|
||||
return typeEnum != null ? typeEnum.getText() : "未知类型";
|
||||
}));
|
||||
// 2. 将每组转换为 “类型:name1, name2”
|
||||
String recognizerStr = groupMap.entrySet().stream()
|
||||
.map(entry -> {
|
||||
String type = entry.getKey();
|
||||
String names = entry.getValue().stream()
|
||||
.map(PgsProgressPlanDetailRecognizerVo::getName)
|
||||
.collect(Collectors.joining(", "));
|
||||
return type + ":" + names;
|
||||
})
|
||||
.collect(Collectors.joining(";")); // 组之间用分号分隔
|
||||
pictureVo.setRecognizeResultStr(recognizerStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pictureVo;
|
||||
}
|
||||
@ -123,13 +155,36 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
BigDecimal p = progressVo.getProgress()
|
||||
.multiply(new BigDecimal("100"));
|
||||
pictureVo.setProgress(p.compareTo(BigDecimal.valueOf(100)) == 0 ?
|
||||
BigDecimal.valueOf(100) : p.setScale(4, RoundingMode.HALF_UP));
|
||||
BigDecimal.valueOf(100) : p.setScale(2, RoundingMode.HALF_UP));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
pictureVo.setStatus("4");
|
||||
pictureVo.setRemark(e.getMessage());
|
||||
log.error("查询图片合成进度异常", e);
|
||||
}
|
||||
if (StringUtils.isNotBlank(pictureVo.getRecognizeResult())) {
|
||||
List<PgsProgressPlanDetailRecognizerVo> recognizerList =
|
||||
JSONUtil.toList(pictureVo.getRecognizeResult(), PgsProgressPlanDetailRecognizerVo.class);
|
||||
if (CollUtil.isNotEmpty(recognizerList)) {
|
||||
// 1. 按类型名称分组
|
||||
Map<String, List<PgsProgressPlanDetailRecognizerVo>> groupMap = recognizerList.stream()
|
||||
.collect(Collectors.groupingBy(r -> {
|
||||
RecognizerTypeEnum typeEnum = RecognizerTypeEnum.fromValue(r.getType());
|
||||
return typeEnum != null ? typeEnum.getText() : "未知类型";
|
||||
}));
|
||||
// 2. 将每组转换为 “类型:name1, name2”
|
||||
String recognizerStr = groupMap.entrySet().stream()
|
||||
.map(entry -> {
|
||||
String type = entry.getKey();
|
||||
String names = entry.getValue().stream()
|
||||
.map(PgsProgressPlanDetailRecognizerVo::getName)
|
||||
.collect(Collectors.joining(", "));
|
||||
return type + ":" + names;
|
||||
})
|
||||
.collect(Collectors.joining(";")); // 组之间用分号分隔
|
||||
pictureVo.setRecognizeResultStr(recognizerStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setRecords(records);
|
||||
@ -157,6 +212,7 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getBigPic()), DroDroneBigPicture::getBigPic, bo.getBigPic());
|
||||
lqw.eq(bo.getRecognizePic() != null, DroDroneBigPicture::getRecognizePic, bo.getRecognizePic());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getTifFile()), DroDroneBigPicture::getTifFile, bo.getTifFile());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getSourceType()), DroDroneBigPicture::getSourceType, bo.getSourceType());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), DroDroneBigPicture::getStatus, bo.getStatus());
|
||||
return lqw;
|
||||
}
|
||||
@ -164,19 +220,27 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
/**
|
||||
* 新增无人机大图信息
|
||||
*
|
||||
* @param bo 无人机大图信息
|
||||
* @param bo 无人机大图信息
|
||||
* @param isNew 是否创建新记录
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(DroDroneBigPictureBo bo) {
|
||||
public Boolean insertByBo(DroDroneBigPictureBo bo, Boolean isNew) {
|
||||
DroDroneBigPicture add = MapstructUtils.convert(bo, DroDroneBigPicture.class);
|
||||
if (add == null) {
|
||||
return false;
|
||||
}
|
||||
boolean save = this.save(add);
|
||||
if (!save) {
|
||||
throw new ServiceException("新增无人机大图信息失败");
|
||||
if (isNew) {
|
||||
if (StringUtils.isNotBlank(add.getBigPic()) && StringUtils.isNotBlank(add.getTifFile())) {
|
||||
add.setStatus("3");
|
||||
}
|
||||
add.setSourceType("1");
|
||||
boolean save = this.save(add);
|
||||
if (!save) {
|
||||
throw new ServiceException("新增无人机大图信息失败");
|
||||
}
|
||||
}
|
||||
Long id = add.getId();
|
||||
// 压缩图片
|
||||
String smallPic = add.getSmallPic();
|
||||
if (StringUtils.isNotBlank(smallPic)) {
|
||||
@ -188,7 +252,7 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(","));
|
||||
DroDroneBigPicture update = new DroDroneBigPicture();
|
||||
update.setId(add.getId());
|
||||
update.setId(id);
|
||||
update.setCompressPic(ossIds);
|
||||
this.updateById(update);
|
||||
}).exceptionally(ex -> {
|
||||
@ -196,6 +260,30 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if (StringUtils.isNotBlank(smallPic) && StringUtils.isBlank(add.getBigPic())) {
|
||||
List<Long> picIds = StringUtils.splitTo(smallPic, Convert::toLong);
|
||||
List<SysOssVo> ossVos = ossService.listByIds(picIds);
|
||||
List<String> picUrls = ossVos.stream().map(SysOssVo::getUrl).toList();
|
||||
// 异步执行大图合并
|
||||
self.asyncAddBigPicture(add.getTaskName(), picUrls)
|
||||
.thenAccept(result -> {
|
||||
DroDroneBigPicture update = new DroDroneBigPicture();
|
||||
update.setId(id);
|
||||
update.setStatus("2");
|
||||
update.setTaskId(result);
|
||||
this.updateById(update);
|
||||
}).exceptionally(ex -> {
|
||||
log.error("无人机大图信息[{}]异步执行合成图片失败", add.getTaskName(), ex);
|
||||
DroDroneBigPicture update = new DroDroneBigPicture();
|
||||
update.setId(id);
|
||||
update.setStatus("4");
|
||||
this.updateById(update);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if (StringUtils.isNotBlank(add.getBigPic()) && StringUtils.isNotBlank(add.getTifFile())) {
|
||||
return this.createProgressRecognize(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -254,8 +342,26 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
fileUrl = mergeUrlVo.getPngUrl();
|
||||
tifUrl = mergeUrlVo.getTifUrl();
|
||||
} else {
|
||||
fileUrl = bigPicture.getBigPic();
|
||||
tifUrl = bigPicture.getTifFile();
|
||||
String bigPic = bigPicture.getBigPic();
|
||||
if (isLong(bigPic)) {
|
||||
SysOssVo ossVo = ossService.getById(Long.parseLong(bigPic));
|
||||
if (ossVo != null) {
|
||||
bigPic = ossVo.getUrl();
|
||||
} else {
|
||||
throw new ServiceException("图片不存在");
|
||||
}
|
||||
}
|
||||
fileUrl = bigPic;
|
||||
String tifFile = bigPicture.getTifFile();
|
||||
if (isLong(tifFile)) {
|
||||
SysOssVo ossVo = ossService.getById(Long.parseLong(tifFile));
|
||||
if (ossVo != null) {
|
||||
tifFile = ossVo.getUrl();
|
||||
} else {
|
||||
throw new ServiceException("TIF文件不存在");
|
||||
}
|
||||
}
|
||||
tifUrl = tifFile;
|
||||
}
|
||||
// 创建进度识别
|
||||
PgsProgressPlanDetailAINumberReq ai = new PgsProgressPlanDetailAINumberReq();
|
||||
@ -317,6 +423,32 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
throw new ServiceException("图片删除异常");
|
||||
}
|
||||
}
|
||||
for (DroDroneBigPicture picture : list) {
|
||||
String bigPic = picture.getBigPic();
|
||||
if (StringUtils.isNotBlank(bigPic)) {
|
||||
if (isLong(bigPic)) {
|
||||
SysOssVo ossVo = ossService.getById(Long.parseLong(bigPic));
|
||||
if (ossVo != null) {
|
||||
ossService.deleteWithValidByIds(Collections.singleton(ossVo.getOssId()), false);
|
||||
}
|
||||
} else {
|
||||
OssClient storage = OssFactory.instance();
|
||||
storage.delete(bigPic);
|
||||
}
|
||||
}
|
||||
String tifFile = picture.getTifFile();
|
||||
if (StringUtils.isNotBlank(tifFile)) {
|
||||
if (isLong(tifFile)) {
|
||||
SysOssVo ossVo = ossService.getById(Long.parseLong(tifFile));
|
||||
if (ossVo != null) {
|
||||
ossService.deleteWithValidByIds(Collections.singleton(ossVo.getOssId()), false);
|
||||
}
|
||||
} else {
|
||||
OssClient storage = OssFactory.instance();
|
||||
storage.delete(tifFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.removeBatchByIds(ids);
|
||||
}
|
||||
|
||||
@ -342,7 +474,12 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
if (!status.equals("2")) {
|
||||
return vo;
|
||||
}
|
||||
DroneImgMergeProgressVo imgMergeProgress = droneManager.getImgMergeProgress(taskId);
|
||||
DroneImgMergeProgressVo imgMergeProgress = null;
|
||||
try {
|
||||
imgMergeProgress = droneManager.getImgMergeProgress(taskId);
|
||||
} catch (Exception e) {
|
||||
log.error("获取图片合并进度失败:{}", e.getMessage());
|
||||
}
|
||||
if (imgMergeProgress == null) {
|
||||
return vo;
|
||||
}
|
||||
@ -354,6 +491,7 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
} else if (msg != null && msg.compareTo(BigDecimal.ZERO) >= 0 && msg.compareTo(BigDecimal.ONE) < 0) {
|
||||
return vo;
|
||||
} else {
|
||||
vo.setProgress(BigDecimal.ZERO);
|
||||
newStatus = "4";
|
||||
picture.setStatus(newStatus);
|
||||
}
|
||||
@ -413,6 +551,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步合成大图
|
||||
*
|
||||
* @param businessName 业务名称
|
||||
* @param imageUrls 图片URL列表
|
||||
* @return 任务id
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
public CompletableFuture<String> asyncAddBigPicture(String businessName, List<String> imageUrls) {
|
||||
return CompletableFuture.completedFuture(droneManager.createImageMergeTask(businessName, imageUrls));
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步添加压缩图片
|
||||
*
|
||||
@ -498,6 +649,136 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
return CompletableFuture.completedFuture(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传zip文件
|
||||
*
|
||||
* @param file zip文件
|
||||
* @param bo 无人机大图信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean uploadZip(MultipartFile file, DroDroneBigPictureBo bo) {
|
||||
if (file == null) {
|
||||
throw new ServiceException("请选择文件");
|
||||
}
|
||||
String zipName = file.getOriginalFilename();
|
||||
if (StringUtils.isBlank(zipName)) {
|
||||
throw new ServiceException("请选择文件");
|
||||
}
|
||||
File tempDir = new File(System.getProperty("java.io.tmpdir"), "zip_" + System.currentTimeMillis());
|
||||
if (!tempDir.exists()) {
|
||||
boolean mkdirs = tempDir.mkdirs();
|
||||
if (!mkdirs) {
|
||||
throw new RuntimeException("创建临时目录失败");
|
||||
}
|
||||
}
|
||||
// 主线程保存 ZIP 文件(必须提前保存!)
|
||||
File zipFile = new File(tempDir, zipName);
|
||||
try {
|
||||
file.transferTo(zipFile);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("ZIP 文件保存失败");
|
||||
}
|
||||
// 保存数据
|
||||
bo.setStatus("9");
|
||||
DroDroneBigPicture picture = new DroDroneBigPicture();
|
||||
BeanUtils.copyProperties(bo, picture);
|
||||
picture.setSourceType("1");
|
||||
boolean save = this.save(picture);
|
||||
if (!save) {
|
||||
throw new ServiceException("保存数据失败");
|
||||
}
|
||||
Long id = picture.getId();
|
||||
// 异步解压
|
||||
self.unzipAsync(zipFile, tempDir)
|
||||
.thenAccept(result -> {
|
||||
String fileStr = result.stream()
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(","));
|
||||
bo.setId(id);
|
||||
bo.setSmallPic(fileStr);
|
||||
this.insertByBo(bo, false);
|
||||
})
|
||||
.exceptionally(ex -> {
|
||||
// 统一处理解压失败(包括 ZipUtil 等异常)
|
||||
log.error("压缩包处理失败: {}", ex.getMessage(), ex);
|
||||
// 保存数据
|
||||
DroDroneBigPicture update = new DroDroneBigPicture();
|
||||
update.setId(id);
|
||||
update.setStatus("8");
|
||||
update.setRemark(ex.getMessage());
|
||||
this.updateById(picture);
|
||||
return null;
|
||||
}).whenComplete((r, ex) -> {
|
||||
// 不管成功失败,都删除临时文件
|
||||
FileUtil.del(tempDir);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解压zip文件
|
||||
*
|
||||
* @param zipFile zip文件
|
||||
* @param tempDir 临时目录
|
||||
* @return 解压后的文件的对象存储Ids
|
||||
*/
|
||||
@Async("unzipExecutor")
|
||||
@Override
|
||||
public CompletableFuture<List<Long>> unzipAsync(File zipFile, File tempDir) {
|
||||
File unzipDir;
|
||||
try {
|
||||
unzipDir = ZipUtil.unzip(zipFile);
|
||||
} catch (Exception e) {
|
||||
// 记录错误日志
|
||||
log.error("解压失败:{}", zipFile.getAbsolutePath(), e);
|
||||
// 抛出异常到上层 thenCompose,便于处理
|
||||
CompletableFuture<List<Long>> future = new CompletableFuture<>();
|
||||
future.completeExceptionally(new ServiceException("压缩包解压失败"));
|
||||
return future;
|
||||
}
|
||||
// 找图片
|
||||
List<File> imageFiles = FileUtil.loopFiles(unzipDir).stream()
|
||||
.filter(this::isImage)
|
||||
.toList();
|
||||
if (CollUtil.isEmpty(imageFiles)) {
|
||||
// 抛出异常到上层 thenCompose,便于处理
|
||||
CompletableFuture<List<Long>> future = new CompletableFuture<>();
|
||||
future.completeExceptionally(new ServiceException("压缩包中没有图片"));
|
||||
return future;
|
||||
}
|
||||
// 异步上传任务
|
||||
List<CompletableFuture<Long>> uploadFutures = new ArrayList<>();
|
||||
for (File img : imageFiles) {
|
||||
SysOssVo upload = ossService.upload(img);
|
||||
uploadFutures.add(CompletableFuture.completedFuture(upload.getOssId()));
|
||||
}
|
||||
return CompletableFuture.allOf(uploadFutures.toArray(new CompletableFuture[0]))
|
||||
.thenApply(v -> uploadFutures.stream()
|
||||
.map(CompletableFuture::join)
|
||||
.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否是图片
|
||||
*
|
||||
* @param file 文件
|
||||
* @return 是否是图片
|
||||
*/
|
||||
private boolean isImage(File file) {
|
||||
// 方式 1:判断扩展名
|
||||
String ext = FileUtil.extName(file).toLowerCase();
|
||||
List<String> imageExt = Arrays.asList("jpg", "jpeg", "png", "bmp", "gif", "webp");
|
||||
if (imageExt.contains(ext)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 方式 2:判断真实文件类型(更安全)
|
||||
String type = FileTypeUtil.getType(file);
|
||||
return type != null && (type.equals("jpg") || type.equals("png")
|
||||
|| type.equals("jpeg") || type.equals("gif") || type.equals("bmp"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断两个Ids是否相同
|
||||
*
|
||||
@ -516,4 +797,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
|
||||
.collect(Collectors.toSet());
|
||||
return set1.equals(set2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否为Long
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return 是否为Long
|
||||
*/
|
||||
private static boolean isLong(String str) {
|
||||
try {
|
||||
Long.parseLong(str);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,11 +773,11 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
// 获取项目下的所有未完成的光伏板
|
||||
List<FacPhotovoltaicPanel> panelList = this.lambdaQuery()
|
||||
.in(FacPhotovoltaicPanel::getProjectId, projectIds)
|
||||
.ne(FacPhotovoltaicPanel::getStatus, FacFinishStatusEnum.FINISH.getValue())
|
||||
.eq(type.equals(RecognizerTypeEnum.BRACKET.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "支架安装")
|
||||
.eq(type.equals(RecognizerTypeEnum.PANEL.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "组件安装")
|
||||
.list();
|
||||
if (CollUtil.isEmpty(panelList)) {
|
||||
log.info("没有需要更新的光伏板");
|
||||
return recognizeVoList;
|
||||
}
|
||||
// 判断识别出来的坐标是否包含在某个面内
|
||||
@ -792,7 +792,9 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
|
||||
vo.setName(containingPanel.getName());
|
||||
vo.setType(type);
|
||||
recognizeVoList.add(vo);
|
||||
finishPanelList.add(containingPanel);
|
||||
if (!containingPanel.getStatus().equals(FacFinishStatusEnum.FINISH.getValue())) {
|
||||
finishPanelList.add(containingPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(finishPanelList)) {
|
||||
|
||||
@ -0,0 +1,106 @@
|
||||
package org.dromara.gps.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.gps.domain.bo.GpsSafetyUserRecordBo;
|
||||
import org.dromara.gps.domain.vo.GpsSafetyUserRecordVo;
|
||||
import org.dromara.gps.service.IGpsSafetyUserRecordService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/gps/safetyUserRecord")
|
||||
public class GpsSafetyUserRecordController extends BaseController {
|
||||
|
||||
private final IGpsSafetyUserRecordService gpsSafetyUserRecordService;
|
||||
|
||||
/**
|
||||
* 查询安全员轨迹信息列表
|
||||
*/
|
||||
@SaCheckPermission("gps:safetyUserRecord:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<GpsSafetyUserRecordVo> list(GpsSafetyUserRecordBo bo, PageQuery pageQuery) {
|
||||
return gpsSafetyUserRecordService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出安全员轨迹信息列表
|
||||
*/
|
||||
@SaCheckPermission("gps:safetyUserRecord:export")
|
||||
@Log(title = "安全员轨迹信息", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(GpsSafetyUserRecordBo bo, HttpServletResponse response) {
|
||||
List<GpsSafetyUserRecordVo> list = gpsSafetyUserRecordService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "安全员轨迹信息", GpsSafetyUserRecordVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取安全员轨迹信息详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("gps:safetyUserRecord:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<GpsSafetyUserRecordVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(gpsSafetyUserRecordService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增安全员轨迹信息
|
||||
*/
|
||||
@SaCheckPermission("gps:safetyUserRecord:add")
|
||||
@Log(title = "安全员轨迹信息", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody GpsSafetyUserRecordBo bo) {
|
||||
return toAjax(gpsSafetyUserRecordService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改安全员轨迹信息
|
||||
*/
|
||||
@SaCheckPermission("gps:safetyUserRecord:edit")
|
||||
@Log(title = "安全员轨迹信息", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody GpsSafetyUserRecordBo bo) {
|
||||
return toAjax(gpsSafetyUserRecordService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除安全员轨迹信息
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
@SaCheckPermission("gps:safetyUserRecord:remove")
|
||||
@Log(title = "安全员轨迹信息", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(gpsSafetyUserRecordService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,8 @@
|
||||
package org.dromara.gps.domain;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@ -29,12 +28,12 @@ public class GpsManmachine implements Serializable {
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 绑定id
|
||||
* 绑定id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 类型(绑定id类型,1、车辆,2人员)
|
||||
* 类型(绑定id类型,1车辆 2人员 3安全员)
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
|
||||
@ -0,0 +1,73 @@
|
||||
package org.dromara.gps.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息对象 gps_safety_user_record
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("gps_safety_user_record")
|
||||
public class GpsSafetyUserRecord extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 人员id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 人员名称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 记录时间
|
||||
*/
|
||||
private LocalDate recordDate;
|
||||
|
||||
/**
|
||||
* 入场时间
|
||||
*/
|
||||
private LocalDateTime entryTime;
|
||||
|
||||
/**
|
||||
* 退场时间
|
||||
*/
|
||||
private LocalDateTime exitTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@ -1,13 +1,12 @@
|
||||
package org.dromara.gps.domain.bo;
|
||||
|
||||
import org.dromara.gps.domain.GpsEquipment;
|
||||
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 jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import jakarta.validation.constraints.*;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.gps.domain.GpsEquipment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -25,7 +24,7 @@ public class GpsEquipmentBo extends BaseEntity {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||
@NotNull(message = "主键ID不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
@ -88,7 +87,7 @@ public class GpsEquipmentBo extends BaseEntity {
|
||||
private Integer gpsType;
|
||||
|
||||
/**
|
||||
* 设备类型(0、人员设备,1、车辆设备)
|
||||
* 设备类型(0人员设备 1车辆设备 2安全员设备)
|
||||
*/
|
||||
private Integer clientType;
|
||||
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
package org.dromara.gps.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.gps.domain.GpsSafetyUserRecord;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息业务对象 gps_safety_user_record
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = GpsSafetyUserRecord.class, reverseConvertGenerate = false)
|
||||
public class GpsSafetyUserRecordBo extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 70132320796943002L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
@NotNull(message = "项目id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 人员id
|
||||
*/
|
||||
@NotNull(message = "人员id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
@NotBlank(message = "设备id不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 人员名称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 记录时间
|
||||
*/
|
||||
@NotNull(message = "记录时间不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private LocalDate recordDate;
|
||||
|
||||
/**
|
||||
* 入场时间
|
||||
*/
|
||||
private LocalDateTime entryTime;
|
||||
|
||||
/**
|
||||
* 退场时间
|
||||
*/
|
||||
private LocalDateTime exitTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
package org.dromara.gps.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.gps.domain.GpsSafetyUserRecord;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息视图对象 gps_safety_user_record
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = GpsSafetyUserRecord.class)
|
||||
public class GpsSafetyUserRecordVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
@ExcelProperty(value = "项目id")
|
||||
private Long projectId;
|
||||
|
||||
/**
|
||||
* 人员id
|
||||
*/
|
||||
@ExcelProperty(value = "人员id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
@ExcelProperty(value = "设备id")
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 人员名称
|
||||
*/
|
||||
@ExcelProperty(value = "人员名称")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 记录时间
|
||||
*/
|
||||
@ExcelProperty(value = "记录时间")
|
||||
private LocalDate recordDate;
|
||||
|
||||
/**
|
||||
* 入场时间
|
||||
*/
|
||||
@ExcelProperty(value = "入场时间")
|
||||
private LocalDateTime entryTime;
|
||||
|
||||
/**
|
||||
* 退场时间
|
||||
*/
|
||||
@ExcelProperty(value = "退场时间")
|
||||
private LocalDateTime exitTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
package org.dromara.gps.mapper;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.gps.domain.GpsEquipment;
|
||||
import org.dromara.gps.domain.vo.GpsEquipmentVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.gps.domain.vo.GpsUserVo;
|
||||
|
||||
import java.util.List;
|
||||
@ -21,7 +19,7 @@ public interface GpsEquipmentMapper extends BaseMapperPlus<GpsEquipment, GpsEqui
|
||||
|
||||
@Select("SELECT\n" +
|
||||
" gm.user_id AS userId,\n" +
|
||||
" su.user_name AS userName, \n" +
|
||||
" su.nick_name AS userName, \n" +
|
||||
" gm.project_id AS projectId,\n" +
|
||||
" bp.project_name AS projectName \n" +
|
||||
"FROM\n" +
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package org.dromara.gps.mapper;
|
||||
|
||||
import org.dromara.gps.domain.GpsSafetyUserRecord;
|
||||
import org.dromara.gps.domain.vo.GpsSafetyUserRecordVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息Mapper接口
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
public interface GpsSafetyUserRecordMapper extends BaseMapperPlus<GpsSafetyUserRecord, GpsSafetyUserRecordVo> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package org.dromara.gps.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.gps.domain.GpsSafetyUserRecord;
|
||||
import org.dromara.gps.domain.bo.GpsSafetyUserRecordBo;
|
||||
import org.dromara.gps.domain.vo.GpsSafetyUserRecordVo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息Service接口
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
public interface IGpsSafetyUserRecordService extends IService<GpsSafetyUserRecord> {
|
||||
|
||||
/**
|
||||
* 查询安全员轨迹信息
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 安全员轨迹信息
|
||||
*/
|
||||
GpsSafetyUserRecordVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询安全员轨迹信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 安全员轨迹信息分页列表
|
||||
*/
|
||||
TableDataInfo<GpsSafetyUserRecordVo> queryPageList(GpsSafetyUserRecordBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的安全员轨迹信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 安全员轨迹信息列表
|
||||
*/
|
||||
List<GpsSafetyUserRecordVo> queryList(GpsSafetyUserRecordBo bo);
|
||||
|
||||
/**
|
||||
* 新增安全员轨迹信息
|
||||
*
|
||||
* @param bo 安全员轨迹信息
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(GpsSafetyUserRecordBo bo);
|
||||
|
||||
/**
|
||||
* 修改安全员轨迹信息
|
||||
*
|
||||
* @param bo 安全员轨迹信息
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(GpsSafetyUserRecordBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除安全员轨迹信息信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 校验并保存轨迹信息
|
||||
* 核心逻辑:根据用户当前坐标判断是否在项目区域内,更新或创建轨迹记录(进入/离开区域)
|
||||
*
|
||||
* @param clientId 设备id,非空
|
||||
* @param projectId 项目id,非空
|
||||
* @param userId 用户id,非空
|
||||
* @param longitude 经度,非空
|
||||
* @param latitude 纬度,非空
|
||||
*/
|
||||
void validTrackByEquipment(String clientId, Long projectId, Long userId, String longitude, String latitude);
|
||||
}
|
||||
@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
@ -31,6 +32,7 @@ import org.dromara.gps.mapper.GpsEquipmentMapper;
|
||||
import org.dromara.gps.mapper.GpsManmachineMapper;
|
||||
import org.dromara.gps.service.IGpsEquipmentService;
|
||||
import org.dromara.gps.service.IGpsEquipmentSonService;
|
||||
import org.dromara.gps.service.IGpsSafetyUserRecordService;
|
||||
import org.dromara.project.domain.vo.project.BusProjectVo;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
@ -81,6 +83,9 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
|
||||
@Autowired
|
||||
private IVehVehicleTripService iVehVehicleTripService;
|
||||
|
||||
@Resource
|
||||
private IGpsSafetyUserRecordService safetyUserRecordService;
|
||||
|
||||
/**
|
||||
* 查询GPS设备详细
|
||||
*
|
||||
@ -265,7 +270,9 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
|
||||
|
||||
gpsEquipmentSonService.insertByBo(gpsEquipmentSon);
|
||||
|
||||
|
||||
// 记录安全员轨迹
|
||||
safetyUserRecordService.validTrackByEquipment(gpsEquipmentSon.getClientId(), gpsEquipmentSon.getProjectId(),
|
||||
gpsEquipmentSon.getUserId(), location.getStr("longitude"), location.getStr("latitude"));
|
||||
//保存到redis,如果存在则更新存活时间
|
||||
|
||||
// --------------------------
|
||||
@ -465,7 +472,13 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
|
||||
GpsManmachine gpsManmachine = new GpsManmachine();
|
||||
gpsManmachine.setClientId(bo.getClientId());
|
||||
gpsManmachine.setUserId(bo.getUserId());
|
||||
gpsManmachine.setType(bo.getClientType() == 1 ? 1 : 2);
|
||||
Integer type = switch (bo.getClientType()) {
|
||||
case 1 -> 1; // 车辆
|
||||
case 0 -> 2; // 人员
|
||||
case 2 -> 3; // 安全员
|
||||
default -> throw new ServiceException("未知设备类型");
|
||||
};
|
||||
gpsManmachine.setType(type);
|
||||
if (bo.getClientType() == 1) {
|
||||
iVehVehicleInfoService.update(new LambdaUpdateWrapper<VehVehicleInfo>().set(VehVehicleInfo::getClientId, bo.getClientId()).eq(VehVehicleInfo::getId, bo.getUserId()));
|
||||
}
|
||||
|
||||
@ -0,0 +1,266 @@
|
||||
package org.dromara.gps.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
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.utils.JSTUtil;
|
||||
import org.dromara.facility.domain.FacMatrix;
|
||||
import org.dromara.facility.service.IFacMatrixService;
|
||||
import org.dromara.gps.domain.GpsSafetyUserRecord;
|
||||
import org.dromara.gps.domain.bo.GpsSafetyUserRecordBo;
|
||||
import org.dromara.gps.domain.vo.GpsSafetyUserRecordVo;
|
||||
import org.dromara.gps.mapper.GpsSafetyUserRecordMapper;
|
||||
import org.dromara.gps.service.IGpsSafetyUserRecordService;
|
||||
import org.dromara.manager.recognizermanager.vo.RecognizeConvertCoordinateResult;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
import org.dromara.system.service.ISysUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 安全员轨迹信息Service业务层处理
|
||||
*
|
||||
* @author lilemy
|
||||
* @date 2025-11-26
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class GpsSafetyUserRecordServiceImpl extends ServiceImpl<GpsSafetyUserRecordMapper, GpsSafetyUserRecord>
|
||||
implements IGpsSafetyUserRecordService {
|
||||
|
||||
@Resource
|
||||
private IFacMatrixService matrixService;
|
||||
|
||||
@Resource
|
||||
private ISysUserService userService;
|
||||
|
||||
/**
|
||||
* 查询安全员轨迹信息
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 安全员轨迹信息
|
||||
*/
|
||||
@Override
|
||||
public GpsSafetyUserRecordVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询安全员轨迹信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 安全员轨迹信息分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<GpsSafetyUserRecordVo> queryPageList(GpsSafetyUserRecordBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<GpsSafetyUserRecord> lqw = buildQueryWrapper(bo);
|
||||
Page<GpsSafetyUserRecordVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的安全员轨迹信息列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 安全员轨迹信息列表
|
||||
*/
|
||||
@Override
|
||||
public List<GpsSafetyUserRecordVo> queryList(GpsSafetyUserRecordBo bo) {
|
||||
LambdaQueryWrapper<GpsSafetyUserRecord> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<GpsSafetyUserRecord> buildQueryWrapper(GpsSafetyUserRecordBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<GpsSafetyUserRecord> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByDesc(GpsSafetyUserRecord::getId);
|
||||
lqw.eq(bo.getProjectId() != null, GpsSafetyUserRecord::getProjectId, bo.getProjectId());
|
||||
lqw.eq(bo.getUserId() != null, GpsSafetyUserRecord::getUserId, bo.getUserId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getClientId()), GpsSafetyUserRecord::getClientId, bo.getClientId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getUserName()), GpsSafetyUserRecord::getUserName, bo.getUserName());
|
||||
lqw.eq(bo.getRecordDate() != null, GpsSafetyUserRecord::getRecordDate, bo.getRecordDate());
|
||||
lqw.eq(bo.getEntryTime() != null, GpsSafetyUserRecord::getEntryTime, bo.getEntryTime());
|
||||
lqw.eq(bo.getExitTime() != null, GpsSafetyUserRecord::getExitTime, bo.getExitTime());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增安全员轨迹信息
|
||||
*
|
||||
* @param bo 安全员轨迹信息
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(GpsSafetyUserRecordBo bo) {
|
||||
GpsSafetyUserRecord add = MapstructUtils.convert(bo, GpsSafetyUserRecord.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改安全员轨迹信息
|
||||
*
|
||||
* @param bo 安全员轨迹信息
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(GpsSafetyUserRecordBo bo) {
|
||||
GpsSafetyUserRecord update = MapstructUtils.convert(bo, GpsSafetyUserRecord.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(GpsSafetyUserRecord entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除安全员轨迹信息信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并保存轨迹信息
|
||||
* 核心逻辑:根据用户当前坐标判断是否在项目区域内,更新或创建轨迹记录(进入/离开区域)
|
||||
*
|
||||
* @param clientId 设备id,非空
|
||||
* @param projectId 项目id,非空
|
||||
* @param userId 用户id,非空
|
||||
* @param longitude 经度,非空
|
||||
* @param latitude 纬度,非空
|
||||
*/
|
||||
@Override
|
||||
public void validTrackByEquipment(String clientId, Long projectId, Long userId, String longitude, String latitude) {
|
||||
// 1. 参数校验:任一参数为空则记录错误日志并终止流程
|
||||
if (StringUtils.isBlank(clientId) || Objects.isNull(projectId)
|
||||
|| Objects.isNull(userId) || StringUtils.isBlank(longitude)
|
||||
|| StringUtils.isBlank(latitude)) {
|
||||
log.error("同步安全员轨迹参数异常 clientId: {}, projectId: {}, userId: {}, longitude: {}, latitude: {}",
|
||||
clientId, projectId, userId, longitude, latitude);
|
||||
return; // 提前返回,避免无效执行
|
||||
}
|
||||
|
||||
LocalDateTime currentTime = LocalDateTime.now();
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
|
||||
// 2. 查询当前项目的地理范围配置
|
||||
List<FacMatrix> matrixList = matrixService.lambdaQuery()
|
||||
.eq(FacMatrix::getProjectId, projectId)
|
||||
.list();
|
||||
if (CollUtil.isEmpty(matrixList)) {
|
||||
log.error("同步安全员轨迹项目范围不存在 projectId: {}", projectId);
|
||||
return; // 无地理范围配置,终止流程
|
||||
}
|
||||
|
||||
// 3. 解析坐标并判断是否在项目区域内
|
||||
RecognizeConvertCoordinateResult coordinateResult = new RecognizeConvertCoordinateResult();
|
||||
coordinateResult.setLng(longitude);
|
||||
coordinateResult.setLat(latitude);
|
||||
FacMatrix currentMatrix = JSTUtil.findContainingMatrix(coordinateResult, matrixList); // 命中的地理范围
|
||||
|
||||
// 4. 查询用户当天最新轨迹记录
|
||||
GpsSafetyUserRecord latestRecord = lambdaQuery()
|
||||
.eq(GpsSafetyUserRecord::getClientId, clientId)
|
||||
.eq(GpsSafetyUserRecord::getProjectId, projectId)
|
||||
.eq(GpsSafetyUserRecord::getUserId, userId)
|
||||
.eq(GpsSafetyUserRecord::getRecordDate, currentDate)
|
||||
.orderByDesc(GpsSafetyUserRecord::getId)
|
||||
.last("limit 1")
|
||||
.one();
|
||||
|
||||
// 5. 获取用户信息(用于轨迹记录)
|
||||
SysUserVo userVo = userService.selectUserById(userId);
|
||||
|
||||
// 6. 轨迹记录逻辑处理:根据是否在区域内+是否已有记录,分支处理
|
||||
handleTrackRecord(currentMatrix, latestRecord, userVo, clientId, projectId, userId, currentDate, currentTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理轨迹记录的创建或更新逻辑
|
||||
* 封装核心业务逻辑,减少主方法嵌套
|
||||
*
|
||||
* @param currentMatrix 当前命中的地理范围(null表示不在区域内)
|
||||
* @param latestRecord 用户当天最新轨迹记录
|
||||
* @param userVo 用户信息
|
||||
* @param clientId 设备ID
|
||||
* @param projectId 项目ID
|
||||
* @param userId 用户ID
|
||||
* @param currentDate 当前日期
|
||||
* @param currentTime 当前时间
|
||||
*/
|
||||
private void handleTrackRecord(FacMatrix currentMatrix, GpsSafetyUserRecord latestRecord,
|
||||
SysUserVo userVo, String clientId, Long projectId,
|
||||
Long userId, LocalDate currentDate, LocalDateTime currentTime) {
|
||||
// 场景1:用户当天已有轨迹记录
|
||||
if (Objects.nonNull(latestRecord)) {
|
||||
LocalDateTime exitTime = latestRecord.getExitTime();
|
||||
|
||||
// 子场景1.1:当前在区域内,且上次记录已标记离开 → 创建新的进入记录
|
||||
if (Objects.nonNull(currentMatrix) && Objects.nonNull(exitTime)) {
|
||||
createNewTrackRecord(userVo, clientId, projectId, userId, currentDate, currentTime);
|
||||
}
|
||||
// 子场景1.2:当前不在区域内,且上次记录未标记离开 → 更新离开时间
|
||||
else if (Objects.isNull(currentMatrix) && Objects.isNull(exitTime)) {
|
||||
latestRecord.setExitTime(currentTime);
|
||||
this.updateById(latestRecord);
|
||||
}
|
||||
// 其他情况(如在区域内但未离开/不在区域内但已离开)无需处理
|
||||
return;
|
||||
}
|
||||
|
||||
// 场景2:用户当天无轨迹记录,且当前在区域内 → 创建首次进入记录
|
||||
if (Objects.nonNull(currentMatrix)) {
|
||||
createNewTrackRecord(userVo, clientId, projectId, userId, currentDate, currentTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新的轨迹记录(进入区域)
|
||||
* 封装重复的对象创建逻辑,提升代码复用性
|
||||
*/
|
||||
private void createNewTrackRecord(SysUserVo userVo, String clientId, Long projectId,
|
||||
Long userId, LocalDate currentDate, LocalDateTime currentTime) {
|
||||
GpsSafetyUserRecord newRecord = new GpsSafetyUserRecord();
|
||||
newRecord.setProjectId(projectId);
|
||||
newRecord.setUserId(userId);
|
||||
newRecord.setClientId(clientId);
|
||||
newRecord.setUserName(Objects.nonNull(userVo) ? userVo.getNickName() : "未知用户"); // 空值保护
|
||||
newRecord.setRecordDate(currentDate);
|
||||
newRecord.setEntryTime(currentTime);
|
||||
this.save(newRecord);
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,7 @@ public class DroneManager {
|
||||
*
|
||||
* @param businessName 业务名称
|
||||
* @param imageUrls 图片URL列表
|
||||
* @return 任务ID
|
||||
*/
|
||||
public String createImageMergeTask(String businessName, List<String> imageUrls) {
|
||||
return DroneRequestUtils.createImgMergeTask(droneProperties.getUrl(), businessName, imageUrls);
|
||||
|
||||
@ -67,6 +67,7 @@ public class DroneRequestUtils {
|
||||
*
|
||||
* @param businessName 业务名称
|
||||
* @param imageUrls 图片URL列表
|
||||
* @return 任务ID
|
||||
*/
|
||||
public static String createImgMergeTask(String url, String businessName, List<String> imageUrls) {
|
||||
if (StringUtils.isBlank(businessName) || CollUtil.isEmpty(imageUrls)) {
|
||||
@ -97,17 +98,17 @@ public class DroneRequestUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载图片合成结果
|
||||
* 获取图片合成结果
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
*/
|
||||
public static DroneImgMergeUrlVo getMergedFileUrl(String url, String taskId) {
|
||||
if (StringUtils.isAnyBlank(taskId)) {
|
||||
throw new ServiceException("下载图片合成结果请求参数错误", HttpStatus.BAD_REQUEST);
|
||||
throw new ServiceException("获取图片合成结果请求参数错误", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 完整 URL
|
||||
String fullUrl = url + DroneConstant.GET_MERGED_FILE_URL + "/" + taskId;
|
||||
String errorMsg = "下载图片合成结果请求失败";
|
||||
String errorMsg = "获取图片合成结果请求失败";
|
||||
try (HttpResponse response = HttpRequest.get(fullUrl).execute()) {
|
||||
if (!response.isOk()) {
|
||||
log.error("{}:{}", errorMsg, response.getStatus());
|
||||
@ -121,7 +122,7 @@ public class DroneRequestUtils {
|
||||
}
|
||||
String data = obj.getStr("data");
|
||||
DroneImgMergeUrlVo mergeUrlVo = JSONUtil.toBean(data, DroneImgMergeUrlVo.class);
|
||||
log.info("下载图片合成结果请求成功:{}", mergeUrlVo);
|
||||
log.info("获取图片合成结果请求成功:{}", mergeUrlVo);
|
||||
return mergeUrlVo;
|
||||
}
|
||||
}
|
||||
@ -148,7 +149,14 @@ public class DroneRequestUtils {
|
||||
JSONObject obj = JSONUtil.parseObj(body);
|
||||
if (!obj.getStr("code").equals("200")) {
|
||||
log.error("{},状态码:{},错误信息:{}", errorMsg, obj.get("code"), obj.get("msg"));
|
||||
throw new ServiceException(errorMsg + ":" + obj.get("msg"));
|
||||
if (obj.getStr("code").equals("500")) {
|
||||
DroneImgMergeProgressVo vo = new DroneImgMergeProgressVo();
|
||||
vo.setCode("404");
|
||||
vo.setMsg(null);
|
||||
return vo;
|
||||
} else {
|
||||
throw new ServiceException(errorMsg + ":" + obj.get("msg"));
|
||||
}
|
||||
}
|
||||
DroneImgMergeProgressVo progress = JSONUtil.toBean(obj, DroneImgMergeProgressVo.class);
|
||||
if (progress == null) {
|
||||
|
||||
@ -453,7 +453,7 @@ public class OutTableController extends BaseController {
|
||||
|
||||
BigDecimal monthCompletionValue = BigDecimal.ZERO;
|
||||
for (BusProcurement busProcurement : busProcurements1) {
|
||||
if(busProcurement.getAcceptedQuantity()!=null){
|
||||
if (busProcurement.getAcceptedQuantity() != null && busProcurement.getUnitPrice() != null) {
|
||||
monthCompletionValue = monthCompletionValue.add(busProcurement.getAcceptedQuantity().multiply(busProcurement.getUnitPrice()).setScale(4, RoundingMode.HALF_UP));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1184,6 +1184,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
droDroneBigPicture.setProjectId(projectId);
|
||||
droDroneBigPicture.setBigPic(fileUrl);
|
||||
droDroneBigPicture.setTifFile(tifUrl);
|
||||
droDroneBigPicture.setSourceType("2");
|
||||
droDroneBigPicture.setStatus("5");
|
||||
boolean save = droDroneBigPictureService.save(droDroneBigPicture);
|
||||
if (!save) {
|
||||
@ -1230,7 +1231,12 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
}
|
||||
if (recognizeVo.getHasTarget().equals(RecognizerHasTargetEnum.NO.getValue())) {
|
||||
log.info("没有识别到设施");
|
||||
return CompletableFuture.completedFuture(true);
|
||||
// 更新数据和状态
|
||||
boolean update = droDroneBigPictureService.lambdaUpdate()
|
||||
.eq(DroDroneBigPicture::getId, bigPictureId)
|
||||
.set(DroDroneBigPicture::getStatus, "6")
|
||||
.update();
|
||||
return CompletableFuture.completedFuture(update);
|
||||
}
|
||||
String fileName = FileNameUtil.getName(fileUrl);
|
||||
List<RecognizeTargetVo> targets = recognizeVo.getTargets();
|
||||
@ -1281,6 +1287,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
|
||||
recognizePic = drawnVo.getOssId();
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
log.error("将识别数据同步到图片上失败", e);
|
||||
throw new ServiceException("将识别数据同步到图片上失败", HttpStatus.ERROR);
|
||||
}
|
||||
String recognizerStr = JSONUtil.toJsonStr(recognizerVoList);
|
||||
|
||||
@ -0,0 +1,105 @@
|
||||
package org.dromara.project.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.project.domain.vo.BusAttendanceMachineRepeatVo;
|
||||
import org.dromara.project.domain.bo.BusAttendanceMachineRepeatBo;
|
||||
import org.dromara.project.service.IBusAttendanceMachineRepeatService;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 考勤重新下发
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/project/attendanceMachineRepeat")
|
||||
public class BusAttendanceMachineRepeatController extends BaseController {
|
||||
|
||||
private final IBusAttendanceMachineRepeatService busAttendanceMachineRepeatService;
|
||||
|
||||
/**
|
||||
* 查询考勤重新下发列表
|
||||
*/
|
||||
@SaCheckPermission("project:attendanceMachineRepeat:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<BusAttendanceMachineRepeatVo> list(BusAttendanceMachineRepeatBo bo, PageQuery pageQuery) {
|
||||
return busAttendanceMachineRepeatService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出考勤重新下发列表
|
||||
*/
|
||||
@SaCheckPermission("project:attendanceMachineRepeat:export")
|
||||
@Log(title = "考勤重新下发", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(BusAttendanceMachineRepeatBo bo, HttpServletResponse response) {
|
||||
List<BusAttendanceMachineRepeatVo> list = busAttendanceMachineRepeatService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "考勤重新下发", BusAttendanceMachineRepeatVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取考勤重新下发详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@SaCheckPermission("project:attendanceMachineRepeat:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<BusAttendanceMachineRepeatVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(busAttendanceMachineRepeatService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增考勤重新下发
|
||||
*/
|
||||
@SaCheckPermission("project:attendanceMachineRepeat:add")
|
||||
@Log(title = "考勤重新下发", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody BusAttendanceMachineRepeatBo bo) {
|
||||
return toAjax(busAttendanceMachineRepeatService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改考勤重新下发
|
||||
*/
|
||||
@SaCheckPermission("project:attendanceMachineRepeat:edit")
|
||||
@Log(title = "考勤重新下发", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BusAttendanceMachineRepeatBo bo) {
|
||||
return toAjax(busAttendanceMachineRepeatService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除考勤重新下发
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
@SaCheckPermission("project:attendanceMachineRepeat:remove")
|
||||
@Log(title = "考勤重新下发", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(busAttendanceMachineRepeatService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package org.dromara.project.domain;
|
||||
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 考勤重新下发对象 bus_attendance_machine_repeat
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("bus_attendance_machine_repeat")
|
||||
public class BusAttendanceMachineRepeat extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备sn
|
||||
*/
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 人脸地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* (1-新增 2-删除)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package org.dromara.project.domain.bo;
|
||||
|
||||
import org.dromara.project.domain.BusAttendanceMachineRepeat;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* 考勤重新下发业务对象 bus_attendance_machine_repeat
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = BusAttendanceMachineRepeat.class, reverseConvertGenerate = false)
|
||||
public class BusAttendanceMachineRepeatBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备sn
|
||||
*/
|
||||
@NotBlank(message = "设备sn不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 人脸地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* (1-新增 2-删除)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package org.dromara.project.domain.vo;
|
||||
|
||||
import org.dromara.project.domain.BusAttendanceMachineRepeat;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.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;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 考勤重新下发视图对象 bus_attendance_machine_repeat
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = BusAttendanceMachineRepeat.class)
|
||||
public class BusAttendanceMachineRepeatVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@ExcelProperty(value = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备sn
|
||||
*/
|
||||
@ExcelProperty(value = "设备sn")
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ExcelProperty(value = "用户id")
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@ExcelProperty(value = "用户名")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 人脸地址
|
||||
*/
|
||||
@ExcelProperty(value = "人脸地址")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* (1-新增 2-删除)
|
||||
*/
|
||||
@ExcelProperty(value = "", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "1=-新增,2=-删除")
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package org.dromara.project.mapper;
|
||||
|
||||
import org.dromara.project.domain.BusAttendanceMachineRepeat;
|
||||
import org.dromara.project.domain.vo.BusAttendanceMachineRepeatVo;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 考勤重新下发Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
public interface BusAttendanceMachineRepeatMapper extends BaseMapperPlus<BusAttendanceMachineRepeat, BusAttendanceMachineRepeatVo> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package org.dromara.project.service;
|
||||
|
||||
import org.dromara.project.domain.vo.BusAttendanceMachineRepeatVo;
|
||||
import org.dromara.project.domain.bo.BusAttendanceMachineRepeatBo;
|
||||
import org.dromara.project.domain.BusAttendanceMachineRepeat;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考勤重新下发Service接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
public interface IBusAttendanceMachineRepeatService extends IService<BusAttendanceMachineRepeat>{
|
||||
|
||||
/**
|
||||
* 查询考勤重新下发
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 考勤重新下发
|
||||
*/
|
||||
BusAttendanceMachineRepeatVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询考勤重新下发列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 考勤重新下发分页列表
|
||||
*/
|
||||
TableDataInfo<BusAttendanceMachineRepeatVo> queryPageList(BusAttendanceMachineRepeatBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的考勤重新下发列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 考勤重新下发列表
|
||||
*/
|
||||
List<BusAttendanceMachineRepeatVo> queryList(BusAttendanceMachineRepeatBo bo);
|
||||
|
||||
/**
|
||||
* 新增考勤重新下发
|
||||
*
|
||||
* @param bo 考勤重新下发
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(BusAttendanceMachineRepeatBo bo);
|
||||
|
||||
/**
|
||||
* 修改考勤重新下发
|
||||
*
|
||||
* @param bo 考勤重新下发
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(BusAttendanceMachineRepeatBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除考勤重新下发信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package org.dromara.project.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
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 org.springframework.stereotype.Service;
|
||||
import org.dromara.project.domain.bo.BusAttendanceMachineRepeatBo;
|
||||
import org.dromara.project.domain.vo.BusAttendanceMachineRepeatVo;
|
||||
import org.dromara.project.domain.BusAttendanceMachineRepeat;
|
||||
import org.dromara.project.mapper.BusAttendanceMachineRepeatMapper;
|
||||
import org.dromara.project.service.IBusAttendanceMachineRepeatService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 考勤重新下发Service业务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2025-11-24
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class BusAttendanceMachineRepeatServiceImpl extends ServiceImpl<BusAttendanceMachineRepeatMapper, BusAttendanceMachineRepeat>
|
||||
implements IBusAttendanceMachineRepeatService {
|
||||
|
||||
private final BusAttendanceMachineRepeatMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询考勤重新下发
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 考勤重新下发
|
||||
*/
|
||||
@Override
|
||||
public BusAttendanceMachineRepeatVo queryById(Long id){
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询考勤重新下发列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 考勤重新下发分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<BusAttendanceMachineRepeatVo> queryPageList(BusAttendanceMachineRepeatBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<BusAttendanceMachineRepeat> lqw = buildQueryWrapper(bo);
|
||||
Page<BusAttendanceMachineRepeatVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的考勤重新下发列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 考勤重新下发列表
|
||||
*/
|
||||
@Override
|
||||
public List<BusAttendanceMachineRepeatVo> queryList(BusAttendanceMachineRepeatBo bo) {
|
||||
LambdaQueryWrapper<BusAttendanceMachineRepeat> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<BusAttendanceMachineRepeat> buildQueryWrapper(BusAttendanceMachineRepeatBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<BusAttendanceMachineRepeat> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByDesc(BusAttendanceMachineRepeat::getId);
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getSn()), BusAttendanceMachineRepeat::getSn, bo.getSn());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getUserId()), BusAttendanceMachineRepeat::getUserId, bo.getUserId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getUserName()), BusAttendanceMachineRepeat::getUserName, bo.getUserName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getUrl()), BusAttendanceMachineRepeat::getUrl, bo.getUrl());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getType()), BusAttendanceMachineRepeat::getType, bo.getType());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增考勤重新下发
|
||||
*
|
||||
* @param bo 考勤重新下发
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(BusAttendanceMachineRepeatBo bo) {
|
||||
BusAttendanceMachineRepeat add = MapstructUtils.convert(bo, BusAttendanceMachineRepeat.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改考勤重新下发
|
||||
*
|
||||
* @param bo 考勤重新下发
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(BusAttendanceMachineRepeatBo bo) {
|
||||
BusAttendanceMachineRepeat update = MapstructUtils.convert(bo, BusAttendanceMachineRepeat.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(BusAttendanceMachineRepeat entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除考勤重新下发信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@ -409,6 +409,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
if (!checkInRange(req)) {
|
||||
throw new ServiceException("打卡位置不在范围内", HttpStatus.ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
//用户信息校验
|
||||
SubConstructionUser constructionUser = constructionUserService.getBySysUserId(userId);
|
||||
@ -429,15 +430,16 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
// 判断用户是否已经被拉黑
|
||||
constructionBlacklistService.validUserInBlacklist(constructionUser.getSysUserId(), req.getProjectId());
|
||||
Boolean result = false;
|
||||
// 进行人脸比对
|
||||
try {
|
||||
result = constructionUserService.faceComparison(file, userId);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(e.getMessage(), HttpStatus.ERROR);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
throw new ServiceException("人脸识别失败,请重新识别", HttpStatus.ERROR);
|
||||
// 进行人脸比对 考勤机过来不需进行这一步
|
||||
if (!"1".equals(req.getSource())) {
|
||||
try {
|
||||
result = constructionUserService.faceComparison(file, userId);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(e.getMessage(), HttpStatus.ERROR);
|
||||
}
|
||||
if (!result) {
|
||||
throw new ServiceException("人脸识别失败,请重新识别", HttpStatus.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
//打卡规则
|
||||
@ -478,10 +480,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
attendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
|
||||
}
|
||||
//只要请假,直接归为请假
|
||||
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
if (leaveService.isLeave(localDateTime, userId)) {
|
||||
attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
}
|
||||
//LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
//if (leaveService.isLeave(localDateTime, userId)) {
|
||||
// attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
//}
|
||||
|
||||
// 填充信息
|
||||
attendance.setUserId(userId);
|
||||
@ -532,10 +534,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
|
||||
}
|
||||
//只要请假,直接归为请假
|
||||
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
if (leaveService.isLeave(localDateTime, userId)) {
|
||||
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
}
|
||||
//LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
//if (leaveService.isLeave(localDateTime, userId)) {
|
||||
// busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
//}
|
||||
|
||||
busAttendance.setSource(req.getSource());
|
||||
busAttendance.setSn(req.getSn());
|
||||
@ -576,10 +578,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
busAttendance.setMinuteCount(0);
|
||||
}
|
||||
//只要请假,直接归为请假
|
||||
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
if (leaveService.isLeave(localDateTime, userId)) {
|
||||
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
}
|
||||
//LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
//if (leaveService.isLeave(localDateTime, userId)) {
|
||||
// busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
//}
|
||||
updateById(busAttendance);
|
||||
} else {
|
||||
BusAttendance attendance = new BusAttendance();
|
||||
@ -594,10 +596,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
|
||||
attendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
|
||||
}
|
||||
//只要请假,直接归为请假
|
||||
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
if (leaveService.isLeave(localDateTime, userId)) {
|
||||
attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
}
|
||||
//LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
|
||||
//if (leaveService.isLeave(localDateTime, userId)) {
|
||||
// attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
|
||||
//}
|
||||
// 填充信息
|
||||
attendance.setUserId(userId);
|
||||
attendance.setProjectId(req.getProjectId());
|
||||
|
||||
@ -216,6 +216,7 @@ public class BusConstructionUserExitServiceImpl extends ServiceImpl<BusConstruct
|
||||
LambdaUpdateWrapper<SubConstructionUser> constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class)
|
||||
.eq(SubConstructionUser::getId, constructionUser.getId())
|
||||
.set(SubConstructionUser::getTeamId, null)
|
||||
.set(SubConstructionUser::getStatus, "1")
|
||||
.set(SubConstructionUser::getLeaveDate, new Date());
|
||||
if (StringUtils.isNotBlank(salaryVoucherFile) && StringUtils.isNotBlank(salaryConfirmationFile)) {
|
||||
constructionUserLuw.set(SubConstructionUser::getExitStatus, "2");
|
||||
|
||||
@ -190,6 +190,7 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
|
||||
.set(SubConstructionUser::getLeaveDate, null)
|
||||
.set(SubConstructionUser::getExitStatus, "0")
|
||||
.set(SubConstructionUser::getUserRole, "0")
|
||||
.set(SubConstructionUser::getStatus, "0")
|
||||
.set(StrUtil.isNotBlank(req.getTypeOfWork()), SubConstructionUser::getTypeOfWork, req.getTypeOfWork())
|
||||
.set(constructionUser.getFirstDate() == null, SubConstructionUser::getFirstDate, LocalDate.now());
|
||||
constructionUserService.update(constructionUserLuw);
|
||||
@ -366,6 +367,7 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
|
||||
.eq(SubConstructionUser::getId, constructionUser.getId())
|
||||
.set(SubConstructionUser::getExitStatus, exitStatus)
|
||||
.set(SubConstructionUser::getTeamId, null)
|
||||
.set(SubConstructionUser::getStatus, "1")
|
||||
.set(SubConstructionUser::getLeaveDate, new Date());
|
||||
constructionUserService.update(constructionUserLuw);
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import org.dromara.common.oss.core.OssClient;
|
||||
import org.dromara.common.oss.exception.OssException;
|
||||
import org.dromara.common.oss.factory.OssFactory;
|
||||
import org.dromara.common.utils.DocumentUtil;
|
||||
import org.dromara.project.domain.BusProject;
|
||||
import org.dromara.project.service.IBusProjectService;
|
||||
import org.dromara.quality.constant.QltQualityConstant;
|
||||
import org.dromara.quality.domain.QltQualityConstructionLog;
|
||||
@ -31,6 +32,7 @@ import org.dromara.quality.domain.vo.qualityconstructionlog.QltQualityConstructi
|
||||
import org.dromara.quality.mapper.QltQualityConstructionLogMapper;
|
||||
import org.dromara.quality.service.IQltQualityConstructionLogService;
|
||||
import org.dromara.system.domain.vo.SysOssVo;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
import org.dromara.system.service.ISysOssService;
|
||||
import org.dromara.system.service.ISysUserService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@ -336,11 +338,25 @@ public class QltQualityConstructionLogServiceImpl extends ServiceImpl<QltQuality
|
||||
*/
|
||||
public Map<String, String> getReplacementMap(QltQualityConstructionLog qualityConstructionLog) {
|
||||
Map<String, String> replacementMap = new HashMap<>();
|
||||
String createName = userService.selectUserById(qualityConstructionLog.getCreateBy()).getNickName();
|
||||
Long createBy = qualityConstructionLog.getCreateBy();
|
||||
String createName = "";
|
||||
if (createBy != null) {
|
||||
SysUserVo userVo = userService.selectUserById(createBy);
|
||||
if (userVo != null) {
|
||||
createName = userVo.getNickName();
|
||||
}
|
||||
}
|
||||
replacementMap.put("${createName}", createName);
|
||||
Date createTime = qualityConstructionLog.getCreateTime();
|
||||
replacementMap.put("${createTime}", createTime != null ? DateUtils.formatDateTime(createTime) : "");
|
||||
String projectName = projectService.getById(qualityConstructionLog.getProjectId()).getProjectName();
|
||||
Long projectId = qualityConstructionLog.getProjectId();
|
||||
String projectName = "";
|
||||
if (projectId != null) {
|
||||
BusProject project = projectService.getById(projectId);
|
||||
if (project != null) {
|
||||
projectName = project.getProjectName();
|
||||
}
|
||||
}
|
||||
replacementMap.put("${projectName}", projectName);
|
||||
LocalDate happenDate = qualityConstructionLog.getHappenDate();
|
||||
replacementMap.put("${happenDate}", happenDate != null ? happenDate.toString() : "");
|
||||
|
||||
@ -391,51 +391,33 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
* @return 生成的Excel文件对象
|
||||
* @throws Exception 异常抛出
|
||||
*/
|
||||
public File generateWeeklyReportTemplate(HseSafetyWeeklyReport report,Integer weekOfYear) throws Exception {
|
||||
public File generateWeeklyReportTemplate(HseSafetyWeeklyReport report, Integer weekOfYear) throws Exception {
|
||||
FileOutputStream outputStream = null;
|
||||
File targetFile = null;
|
||||
|
||||
try {
|
||||
// // 1. 确定目标文件
|
||||
// if (outputFilePath != null && !outputFilePath.trim().isEmpty()) {
|
||||
// // 保存到指定路径
|
||||
// targetFile = new File(outputFilePath);
|
||||
// if (targetFile.exists()) {
|
||||
// if (!targetFile.delete()) {
|
||||
// throw new IOException("无法删除旧文件,请检查文件权限:" + outputFilePath);
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// // 创建临时文件
|
||||
// targetFile = File.createTempFile("周报模板_", ".xlsx");
|
||||
// targetFile.deleteOnExit();
|
||||
// }
|
||||
targetFile = File.createTempFile("周报_"+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss")), ".xlsx");
|
||||
targetFile = File.createTempFile("周报_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss")), ".xlsx");
|
||||
|
||||
// 2. 使用POI直接创建复杂格式
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
// Sheet sheet = workbook.createSheet("9.13");
|
||||
Sheet sheet = workbook.createSheet(LocalDate.now().toString());
|
||||
|
||||
// 3. 构建完整模板结构
|
||||
setupSheetBasicStyle(sheet); // 设置基础样式
|
||||
buildTemplateFullStructure(sheet, workbook,report,weekOfYear); // 创建所有内容
|
||||
buildTemplateFullStructure(sheet, workbook, report, weekOfYear); // 创建所有内容
|
||||
setKeyRowHeights(sheet); // 设置行高
|
||||
|
||||
// 4. 写入文件
|
||||
// 4. 设置条件格式 - 使用最简化版本确保能工作
|
||||
// setupMinimalConditionalFormatting(sheet);
|
||||
|
||||
// 5. 写入文件
|
||||
outputStream = new FileOutputStream(targetFile);
|
||||
workbook.write(outputStream);
|
||||
outputStream.flush();
|
||||
|
||||
// 5. 关闭资源
|
||||
// 6. 关闭资源
|
||||
workbook.close();
|
||||
|
||||
// if (outputFilePath != null) {
|
||||
// System.out.println("项目周报模板生成完成,文件路径:" + targetFile.getAbsolutePath());
|
||||
// } else {
|
||||
// System.out.println("项目周报模板生成完成,临时文件路径:" + targetFile.getAbsolutePath());
|
||||
// }
|
||||
|
||||
return targetFile;
|
||||
|
||||
} catch (Exception e) {
|
||||
@ -890,7 +872,7 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
}
|
||||
|
||||
/**
|
||||
* 施工进度统计表(第11-18行)- 修正数据赋值问题
|
||||
* 施工进度统计表(第11-18行)- 修正数据赋值和条件格式准备
|
||||
*/
|
||||
private void createConstructionProgressTable(Sheet sheet, Workbook workbook, int startRow,
|
||||
CellStyle headerStyle, CellStyle contentStyle,
|
||||
@ -932,15 +914,15 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
l11Cell.setCellValue("备注");
|
||||
l11Cell.setCellStyle(tableHeaderStyle);
|
||||
|
||||
// 数据行(第12-18行,共7行)- 修正数据位置和赋值
|
||||
// 数据行(第12-18行,共7行)- 修正:确保I列(累计完成率)有数值数据用于数据条显示
|
||||
String[][] progressData = {
|
||||
{"基础", "光伏区", "个", "164728", "3955", "104434", "63.4%", "6000", "设计值为根据7.18日最新电子版图纸统计,包含未开工的五工区,总设计容量约为357.5Mpw。"},
|
||||
{"支架", "", "组", "20591", "644", "6412", "31.1%", "1050", ""},
|
||||
{"组件", "", "组", "20591", "409", "4902", "23.8%", "850", ""},
|
||||
{"清表", "", "亩", "4517", "0", "4104", "90.8%", "100", ""},
|
||||
{"塔基", "线路工程", "", "", "", "", "", "", ""},
|
||||
{"组塔", "", "", "", "", "", "", "", ""},
|
||||
{"放线", "", "", "", "", "", "", "", ""}
|
||||
{"基础", "光伏区", "个", "164728", "3955", "104434", "0.634", "6000", "设计值为根据7.18日最新电子版图纸统计,包含未开工的五工区,总设计容量约为357.5Mpw。"},
|
||||
{"支架", "", "组", "20591", "644", "6412", "0.311", "1050", ""},
|
||||
{"组件", "", "组", "20591", "409", "4902", "0.238", "850", ""},
|
||||
{"清表", "", "亩", "4517", "0", "4104", "0.908", "100", ""},
|
||||
{"塔基", "线路工程", "个", "1000", "50", "200", "0.200", "80", ""},
|
||||
{"组塔", "", "座", "500", "25", "100", "0.200", "40", ""},
|
||||
{"放线", "", "km", "200", "10", "40", "0.200", "15", ""}
|
||||
};
|
||||
|
||||
for (int i = 0; i < progressData.length; i++) {
|
||||
@ -953,7 +935,16 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
for (int j = 0; j < 7; j++) { // 只设置前7列数据(C-I列)
|
||||
Cell cell = row.createCell(j + 2); // C列开始
|
||||
if (j < progressData[i].length) {
|
||||
cell.setCellValue(progressData[i][j]);
|
||||
// 对于累计完成率列(I列,索引8),确保是数值格式
|
||||
if (j == 6 && !progressData[i][j].isEmpty()) {
|
||||
try {
|
||||
cell.setCellValue(Double.parseDouble(progressData[i][j]));
|
||||
} catch (NumberFormatException e) {
|
||||
cell.setCellValue(progressData[i][j]);
|
||||
}
|
||||
} else {
|
||||
cell.setCellValue(progressData[i][j]);
|
||||
}
|
||||
}
|
||||
cell.setCellStyle(contentStyle);
|
||||
}
|
||||
@ -992,7 +983,7 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备材料表格(第19-23行)- 修正数据赋值问题
|
||||
* 设备材料表格(第19-23行)- 修正数据赋值和条件格式准备
|
||||
*/
|
||||
private void createEquipmentMaterialTable(Sheet sheet, Workbook workbook, int startRow,
|
||||
CellStyle headerStyle, CellStyle contentStyle,
|
||||
@ -1034,12 +1025,12 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
l19Cell.setCellValue("备注");
|
||||
l19Cell.setCellStyle(tableHeaderStyle);
|
||||
|
||||
// 数据行 - 从第20行开始(共4行数据)- 修正数据位置和赋值
|
||||
// 数据行 - 从第20行开始(共4行数据)- 修正:确保I列(累计到货率)有数值数据用于数据条显示
|
||||
String[][] materialData = {
|
||||
{"檩条、斜撑", "", "根", "131728", "3752", "106745", "81.0%", "", ""},
|
||||
{"立杆", "", "根", "133841", "5549", "53372", "39.9%", "", ""},
|
||||
{"光伏组件", "", "块", "576548", "25880", "177360", "30.8%", "", ""},
|
||||
{"预埋件", "", "套", "164728", "0", "113000", "68.6%", "", ""}
|
||||
{"檩条、斜撑", "", "根", "131728", "3752", "106745", "0.810", "", ""},
|
||||
{"立杆", "", "根", "133841", "5549", "53372", "0.399", "", ""},
|
||||
{"光伏组件", "", "块", "576548", "25880", "177360", "0.308", "", ""},
|
||||
{"预埋件", "", "套", "164728", "0", "113000", "0.686", "", ""}
|
||||
};
|
||||
|
||||
for (int i = 0; i < materialData.length; i++) {
|
||||
@ -1052,7 +1043,16 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
for (int j = 0; j < 7; j++) { // 只设置前7列数据(C-I列)
|
||||
Cell cell = row.createCell(j + 2); // C列开始
|
||||
if (j < materialData[i].length) {
|
||||
cell.setCellValue(materialData[i][j]);
|
||||
// 对于累计到货率列(I列,索引6),确保是数值格式
|
||||
if (j == 6 && !materialData[i][j].isEmpty()) {
|
||||
try {
|
||||
cell.setCellValue(Double.parseDouble(materialData[i][j]));
|
||||
} catch (NumberFormatException e) {
|
||||
cell.setCellValue(materialData[i][j]);
|
||||
}
|
||||
} else {
|
||||
cell.setCellValue(materialData[i][j]);
|
||||
}
|
||||
}
|
||||
cell.setCellStyle(contentStyle);
|
||||
}
|
||||
@ -1484,4 +1484,37 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 最简化的条件格式设置(确保能工作)
|
||||
*/
|
||||
private void setupMinimalConditionalFormatting(Sheet sheet) {
|
||||
try {
|
||||
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
|
||||
|
||||
// 创建一个简单的条件格式规则
|
||||
ConditionalFormattingRule rule = sheetCF.createConditionalFormattingRule(
|
||||
"I12>=0" // 简单的条件
|
||||
);
|
||||
|
||||
// 设置填充颜色
|
||||
PatternFormatting fill = rule.createPatternFormatting();
|
||||
fill.setFillBackgroundColor(IndexedColors.LIGHT_BLUE.getIndex());
|
||||
fill.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
|
||||
|
||||
// 应用规则
|
||||
CellRangeAddress[] regions = {
|
||||
CellRangeAddress.valueOf("I12:I18"),
|
||||
CellRangeAddress.valueOf("I20:I23")
|
||||
};
|
||||
|
||||
sheetCF.addConditionalFormatting(regions, rule);
|
||||
System.out.println("最简化条件格式设置成功");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("最简化条件格式设置失败: " + e.getMessage());
|
||||
// 如果连这个都失败,可能是POI版本问题,跳过条件格式
|
||||
System.out.println("跳过条件格式设置");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,11 +2,13 @@ package org.dromara.websocket.websocket.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.websocket.*;
|
||||
import jakarta.websocket.server.ServerEndpoint;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.utils.AsyncUtil;
|
||||
import org.dromara.mobileAttendanceMachine.KqjEntity;
|
||||
import org.dromara.project.service.IBusAttendanceMachineService;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -33,6 +35,9 @@ public class DeviceWebSocketServer {
|
||||
|
||||
private final static IBusAttendanceMachineService attendanceMachineService = SpringUtils.getBean(IBusAttendanceMachineService.class);
|
||||
|
||||
private final static AsyncUtil asyncUtil = SpringUtils.getBean(AsyncUtil.class);
|
||||
|
||||
|
||||
// ------------------------------ 常量定义 ------------------------------
|
||||
public static final String DECLARE = "declare"; // 设备注册消息
|
||||
public static final String PING = "ping"; // 心跳消息
|
||||
@ -388,6 +393,8 @@ public class DeviceWebSocketServer {
|
||||
// 示例:BusAttendanceMachineService.register(sn);
|
||||
if (attendanceMachineService != null) {
|
||||
attendanceMachineService.insertBySn(sn);
|
||||
asyncUtil.repeatSend(sn);
|
||||
asyncUtil.repeatDelete(sn);
|
||||
} else {
|
||||
log.error("IBusAttendanceMachineService 为空,无法进行设备注册");
|
||||
}
|
||||
|
||||
@ -52,6 +52,9 @@ public class XzdBxBxsqController extends BaseController {
|
||||
private final IXzdProjectService xzdProjectService;
|
||||
private final IXzdSupplierOpenBankService xzdSupplierOpenBankService;
|
||||
private final IXzdBxBxsqBxlxService xzdBxBxsqBxlxService;
|
||||
private final IXzdYhxxService xzdYhxxService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询报销-报销申请列表
|
||||
*/
|
||||
@ -61,8 +64,6 @@ public class XzdBxBxsqController extends BaseController {
|
||||
return xzdBxBxsqService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
private final IXzdYhxxService xzdYhxxService;
|
||||
|
||||
/**
|
||||
* 查询银行数据关联列表
|
||||
*/
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
package org.dromara.xzd.bx.bxsq.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.dromara.common.mybatis.annotation.DataColumn;
|
||||
import org.dromara.common.mybatis.annotation.DataPermission;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.dromara.xzd.bx.bxsq.domain.XzdBxBxsq;
|
||||
import org.dromara.xzd.bx.bxsq.domain.vo.XzdBxBxsqVo;
|
||||
@ -12,4 +17,13 @@ import org.dromara.xzd.bx.bxsq.domain.vo.XzdBxBxsqVo;
|
||||
*/
|
||||
public interface XzdBxBxsqMapper extends BaseMapperPlus<XzdBxBxsq, XzdBxBxsqVo> {
|
||||
|
||||
|
||||
@DataPermission({
|
||||
@DataColumn(key = "deptName", value = "dept_id"),
|
||||
@DataColumn(key = "userName", value = "bxr")
|
||||
})
|
||||
default Page<XzdBxBxsqVo> selectPage(IPage<XzdBxBxsq> page, LambdaQueryWrapper<XzdBxBxsq> wrapper) {
|
||||
return this.selectVoPage(page, wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -29,9 +29,7 @@ import org.dromara.xzd.bx.bxsq.fymx.service.impl.XzdBxBxsqFymxServiceImpl;
|
||||
import org.dromara.xzd.bx.bxsq.mapper.XzdBxBxsqMapper;
|
||||
import org.dromara.xzd.bx.bxsq.service.IXzdBxBxsqService;
|
||||
import org.dromara.xzd.domain.XzdProject;
|
||||
import org.dromara.xzd.domain.XzdSupplierOpenBank;
|
||||
import org.dromara.xzd.domain.XzdYhxx;
|
||||
import org.dromara.xzd.domain.bo.XzdYhxxBo;
|
||||
import org.dromara.xzd.service.impl.XzdProjectServiceImpl;
|
||||
import org.dromara.xzd.service.impl.XzdSupplierOpenBankServiceImpl;
|
||||
import org.dromara.xzd.service.impl.XzdYhxxServiceImpl;
|
||||
@ -81,7 +79,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
* @return 报销-报销申请
|
||||
*/
|
||||
@Override
|
||||
public XzdBxBxsqVo queryById(Long id){
|
||||
public XzdBxBxsqVo queryById(Long id) {
|
||||
XzdBxBxsqVo xzdBxBxsqVo = baseMapper.selectVoById(id);
|
||||
List<XzdBxBxsqVo> xzdBxBxsqVo1 = List.of(xzdBxBxsqVo);
|
||||
setValue(xzdBxBxsqVo1);
|
||||
@ -97,6 +95,11 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<XzdBxBxsqVo> queryPageList(XzdBxBxsqBo bo, PageQuery pageQuery) {
|
||||
//暂时定为只能看见自己的报销
|
||||
if (bo.getBxr() == null && !LoginHelper.isSuperAdmin()) {
|
||||
bo.setBxr(LoginHelper.getUserId());
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<XzdBxBxsq> lqw = buildQueryWrapper(bo);
|
||||
Page<XzdBxBxsqVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
setValue(result.getRecords());
|
||||
@ -164,12 +167,12 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
add.setBm(LoginHelper.getDeptId());
|
||||
//公司
|
||||
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(LoginHelper.getDeptId());
|
||||
if (sysDeptVo != null && !sysDeptVo.getParentId().equals(100L)){
|
||||
if (sysDeptVo != null && !sysDeptVo.getParentId().equals(100L)) {
|
||||
SysDeptVo sysDeptVo1 = getCompanyByDeptId(sysDeptVo);
|
||||
if (sysDeptVo1 != null) {
|
||||
add.setGs(sysDeptVo1.getDeptId());
|
||||
}
|
||||
}else if ((sysDeptVo != null && sysDeptVo.getParentId().equals(100L)) || (sysDeptVo != null && sysDeptVo.getDeptId() == 100L)){
|
||||
} else if ((sysDeptVo != null && sysDeptVo.getParentId().equals(100L)) || (sysDeptVo != null && sysDeptVo.getDeptId() == 100L)) {
|
||||
add.setGs(sysDeptVo.getDeptId());
|
||||
}
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
@ -177,7 +180,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
|
||||
if (bo.getFymx() != null && !bo.getFymx().isEmpty()){
|
||||
if (bo.getFymx() != null && !bo.getFymx().isEmpty()) {
|
||||
for (XzdBxBxsqFymx fymx : bo.getFymx()) {
|
||||
fymx.setBxId(add.getId());
|
||||
}
|
||||
@ -215,16 +218,16 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
|
||||
XzdBxBxsqVo old = queryById(bo.getId());
|
||||
//费用明细
|
||||
if (bo.getFymx() != null && !bo.getFymx().isEmpty()){
|
||||
if (old.getFymx() != null && !old.getFymx().isEmpty()){
|
||||
if (bo.getFymx() != null && !bo.getFymx().isEmpty()) {
|
||||
if (old.getFymx() != null && !old.getFymx().isEmpty()) {
|
||||
xzdBxBxsqFymxService.removeByIds(old.getFymx());
|
||||
}
|
||||
for (XzdBxBxsqFymx businessChange : bo.getFymx()) {
|
||||
businessChange.setBxId(update.getId());
|
||||
}
|
||||
xzdBxBxsqFymxService.saveBatch(bo.getFymx());
|
||||
}else {
|
||||
if (old.getFymx() != null && !old.getFymx().isEmpty()){
|
||||
} else {
|
||||
if (old.getFymx() != null && !old.getFymx().isEmpty()) {
|
||||
xzdBxBxsqFymxService.removeByIds(old.getFymx());
|
||||
}
|
||||
}
|
||||
@ -271,7 +274,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(XzdBxBxsq entity){
|
||||
private void validEntityBeforeSave(XzdBxBxsq entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
@ -284,7 +287,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
|
||||
@ -300,7 +303,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
public void setValue(List<XzdBxBxsqVo> vos){
|
||||
public void setValue(List<XzdBxBxsqVo> vos) {
|
||||
for (XzdBxBxsqVo vo : vos) {
|
||||
//费用明细
|
||||
LambdaQueryWrapper<XzdBxBxsqFymx> lqw = new LambdaQueryWrapper<>();
|
||||
@ -308,7 +311,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
List<XzdBxBxsqFymx> list = xzdBxBxsqFymxService.list(lqw);
|
||||
//费用明细处理
|
||||
List<XzdBxBxsqFymxVo> voList = new ArrayList<>();
|
||||
if (list != null && !list.isEmpty()){
|
||||
if (list != null && !list.isEmpty()) {
|
||||
for (XzdBxBxsqFymx fymx : list) {
|
||||
XzdBxBxsqFymxVo fymxVo = new XzdBxBxsqFymxVo();
|
||||
BeanUtils.copyProperties(fymx, fymxVo);
|
||||
@ -327,7 +330,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
}
|
||||
}
|
||||
//费用承担部门
|
||||
if (fymx.getFycdbm() != null){
|
||||
if (fymx.getFycdbm() != null) {
|
||||
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(fymx.getFycdbm());
|
||||
if (sysDeptVo != null) {
|
||||
fymxVo.setFycdbmmc(sysDeptVo.getDeptName());
|
||||
@ -338,9 +341,9 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
vo.setFymx(voList);
|
||||
}
|
||||
//报销人名称
|
||||
if (vo.getBxr() != null){
|
||||
if (vo.getBxr() != null) {
|
||||
SysUserVo sysUserVo = sysUserService.selectUserById(vo.getBxr());
|
||||
if (sysUserVo != null){
|
||||
if (sysUserVo != null) {
|
||||
vo.setBxrmc(sysUserVo.getNickName());
|
||||
}
|
||||
}
|
||||
@ -376,10 +379,10 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
|
||||
}
|
||||
|
||||
//通过部门查询出公司
|
||||
private SysDeptVo getCompanyByDeptId(SysDeptVo deptVo){
|
||||
if (!deptVo.getParentId().equals(100L)){
|
||||
private SysDeptVo getCompanyByDeptId(SysDeptVo deptVo) {
|
||||
if (!deptVo.getParentId().equals(100L)) {
|
||||
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(deptVo.getParentId());
|
||||
if (sysDeptVo == null){
|
||||
if (sysDeptVo == null) {
|
||||
return null;
|
||||
}
|
||||
getCompanyByDeptId(sysDeptVo);
|
||||
|
||||
@ -215,7 +215,7 @@ public class XzdCsContractInformationVo implements Serializable {
|
||||
*/
|
||||
@ExcelProperty(value = "签约组织")
|
||||
private Long signOrganization;
|
||||
@Translation(type = TransConstant.XZD_KHXX_ID_TO_NAME, mapper = "signOrganization")
|
||||
@Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "signOrganization")
|
||||
private String signOrganizationName;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
package org.dromara.xzd.domain.bo;
|
||||
|
||||
import org.dromara.xzd.domain.XzdContractAdvanceInfo;
|
||||
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.*;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.xzd.domain.XzdContractAdvanceInfo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@ -30,13 +27,13 @@ public class XzdContractAdvanceInfoBo extends BaseEntity {
|
||||
/**
|
||||
* 表名
|
||||
*/
|
||||
@NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 承包合同信息ID
|
||||
*/
|
||||
@NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long contractDetailsId;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
package org.dromara.xzd.domain.bo;
|
||||
|
||||
import org.dromara.xzd.domain.XzdContractClause;
|
||||
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.*;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.xzd.domain.XzdContractClause;
|
||||
|
||||
/**
|
||||
* 合同条款-合同条款业务对象 xzd_contract_clause
|
||||
@ -28,13 +25,13 @@ public class XzdContractClauseBo extends BaseEntity {
|
||||
/**
|
||||
* 表名
|
||||
*/
|
||||
@NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 承包合同信息ID
|
||||
*/
|
||||
@NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long contractDetailsId;
|
||||
|
||||
/**
|
||||
|
||||
@ -110,7 +110,7 @@ public class XzdContractDetailsBo extends BaseEntity {
|
||||
/**
|
||||
* 开票单位
|
||||
*/
|
||||
@NotNull(message = "开票单位不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotNull(message = "开票单位不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long invoicingUnit;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,12 +1,8 @@
|
||||
package org.dromara.xzd.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.xzd.domain.XzdDeductionItems;
|
||||
|
||||
@ -32,13 +28,13 @@ public class XzdDeductionItemsBo extends BaseEntity {
|
||||
/**
|
||||
* 表名
|
||||
*/
|
||||
@NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 承包合同信息ID
|
||||
*/
|
||||
@NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
// @NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private Long contractDetailsId;
|
||||
|
||||
/**
|
||||
|
||||
@ -147,7 +147,7 @@ public class XzdContractDetailsVo implements Serializable {
|
||||
private BigDecimal contractAmount;
|
||||
|
||||
/**
|
||||
* 开票单位(供应商)
|
||||
* 开票单位(供应商,现改为部门公司)
|
||||
*/
|
||||
@ExcelProperty(value = "开票单位")
|
||||
private Long invoicingUnit;
|
||||
@ -155,7 +155,7 @@ public class XzdContractDetailsVo implements Serializable {
|
||||
/**
|
||||
* 开票单位名称
|
||||
*/
|
||||
@Translation(type = TransConstant.XZD_KHXX_ID_TO_NAME, mapper = "invoicingUnit")
|
||||
// @Translation(type = TransConstant.XZD_KHXX_ID_TO_NAME, mapper = "invoicingUnit")
|
||||
private String invoicingUnitName;
|
||||
|
||||
/**
|
||||
|
||||
@ -100,7 +100,8 @@ public class XzdContractAgreementServiceImpl extends ServiceImpl<XzdContractAgre
|
||||
private LambdaQueryWrapper<XzdContractAgreement> buildQueryWrapper(XzdContractAgreementBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<XzdContractAgreement> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByDesc(XzdContractAgreement::getId);
|
||||
lqw.orderByDesc(XzdContractAgreement::getCreateTime);
|
||||
lqw.eq(bo.getCompanyId() != null, XzdContractAgreement::getCompanyId, bo.getCompanyId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getContractCode()), XzdContractAgreement::getContractCode, bo.getContractCode());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getContractName()), XzdContractAgreement::getContractName, bo.getContractName());
|
||||
lqw.eq(bo.getDocumentDate() != null, XzdContractAgreement::getDocumentDate, bo.getDocumentDate());
|
||||
|
||||
@ -185,6 +185,17 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
add.setContractCode(banBen);
|
||||
add.setHtzt("正常");
|
||||
|
||||
//开票单位(部门) 要获取到顶级(公司)
|
||||
// if (bo.getInvoicingUnit() != null) {
|
||||
// SysDeptVo sysDeptVo = sysDeptService.selectDeptById(bo.getInvoicingUnit());
|
||||
// while (sysDeptVo != null && sysDeptVo.getParentId() != 100){
|
||||
// sysDeptVo = sysDeptService.selectDeptById(sysDeptVo.getParentId());
|
||||
// }
|
||||
// if (sysDeptVo != null) {
|
||||
// add.setInvoicingUnit(sysDeptVo.getDeptId());
|
||||
// }
|
||||
// }
|
||||
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (!flag) {
|
||||
return false;
|
||||
@ -251,24 +262,6 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
throw new RuntimeException("该合同已被终止!");
|
||||
}
|
||||
|
||||
// List<XzdContractDetailsVo> old1 = List.of(old);
|
||||
// setValue(old1);
|
||||
// old = old1.getFirst();
|
||||
|
||||
// if (bo.getSealInfo() != null && !bo.getSealInfo().isEmpty()){
|
||||
// if (old.getSealInfo() != null && !old.getSealInfo().isEmpty()){
|
||||
// xzdBusinessChangeService.removeByIds(old.getSealInfo());
|
||||
// }
|
||||
// for (XzdBusinessChange businessChange : bo.getSealInfo()) {
|
||||
// businessChange.setContractChangeId(update.getId());
|
||||
// }
|
||||
// xzdBusinessChangeService.saveBatch(bo.getSealInfo());
|
||||
// }else {
|
||||
// if (old.getSealInfo() != null && !old.getSealInfo().isEmpty()){
|
||||
// xzdBusinessChangeService.removeByIds(old.getSealInfo());
|
||||
// }
|
||||
// }
|
||||
|
||||
//合同文本-预收款项
|
||||
if (bo.getYskx() != null && !bo.getYskx().isEmpty()){
|
||||
if (old.getYskx() != null && !old.getYskx().isEmpty()){
|
||||
@ -286,15 +279,6 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
}
|
||||
|
||||
//合同条款-扣款与奖励项
|
||||
// for (XzdDeductionItems advanceInfo : bo.getKkyjlx()) {
|
||||
// if (!old.getKkyjlx().contains(advanceInfo)){
|
||||
// xzdDeductionItemsService.removeById(advanceInfo);
|
||||
// }
|
||||
// advanceInfo.setContractDetailsId(update.getId());
|
||||
// advanceInfo.setTableName(tableName);
|
||||
// }
|
||||
// xzdDeductionItemsService.saveOrUpdateBatch(bo.getKkyjlx());
|
||||
|
||||
if (bo.getKkyjlx() != null && !bo.getKkyjlx().isEmpty()){
|
||||
if (old.getKkyjlx() != null && !old.getKkyjlx().isEmpty()){
|
||||
xzdDeductionItemsService.removeByIds(old.getKkyjlx());
|
||||
@ -305,20 +289,15 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
}
|
||||
xzdDeductionItemsService.saveBatch(bo.getKkyjlx());
|
||||
}else {
|
||||
if (old.getYskx() != null && !old.getYskx().isEmpty()){
|
||||
xzdDeductionItemsService.removeByIds(old.getYskx());
|
||||
if (old.getKkyjlx() != null && !old.getKkyjlx().isEmpty()){
|
||||
boolean b = xzdDeductionItemsService.removeByIds(old.getKkyjlx());
|
||||
if (!b){
|
||||
log.error("删除老数据kkyjlx失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//合同条款-合同条款
|
||||
// for (XzdContractClause advanceInfo : bo.getHttk()) {
|
||||
// if (!old.getHttk().contains(advanceInfo)){
|
||||
// xzdContractClauseService.removeById(advanceInfo);
|
||||
// }
|
||||
// advanceInfo.setContractDetailsId(update.getId());
|
||||
// advanceInfo.setTableName(tableName);
|
||||
// }
|
||||
// xzdContractClauseService.saveOrUpdateBatch(bo.getHttk());
|
||||
if (bo.getHttk() != null && !bo.getHttk().isEmpty()){
|
||||
if (old.getHttk() != null && !old.getHttk().isEmpty()){
|
||||
xzdContractClauseService.removeByIds(old.getHttk());
|
||||
@ -329,20 +308,12 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
}
|
||||
xzdContractClauseService.saveBatch(bo.getHttk());
|
||||
}else {
|
||||
if (old.getYskx() != null && !old.getYskx().isEmpty()){
|
||||
if (old.getHttk() != null && !old.getHttk().isEmpty()){
|
||||
xzdContractClauseService.removeByIds(old.getHttk());
|
||||
}
|
||||
}
|
||||
|
||||
//支付条款
|
||||
// for (XzdSettlementRules advanceInfo : bo.getZftk()) {
|
||||
// if (!old.getZftk().contains(advanceInfo)){
|
||||
// xzdSettlementRulesService.removeById(advanceInfo);
|
||||
// }
|
||||
// advanceInfo.setContractDetailsId(update.getId());
|
||||
// }
|
||||
// xzdSettlementRulesService.saveOrUpdateBatch(bo.getZftk());
|
||||
|
||||
if (bo.getZftk() != null && !bo.getZftk().isEmpty()){
|
||||
if (old.getZftk() != null && !old.getZftk().isEmpty()){
|
||||
xzdSettlementRulesService.removeByIds(old.getZftk());
|
||||
@ -352,7 +323,7 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
}
|
||||
xzdSettlementRulesService.saveBatch(bo.getZftk());
|
||||
}else {
|
||||
if (old.getYskx() != null && !old.getYskx().isEmpty()){
|
||||
if (old.getZftk() != null && !old.getZftk().isEmpty()){
|
||||
xzdSettlementRulesService.removeByIds(old.getZftk());
|
||||
}
|
||||
}
|
||||
@ -371,22 +342,22 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
}
|
||||
|
||||
//更新文件
|
||||
if (bo.getFileId() != null && !bo.getFileId().isEmpty()){
|
||||
if (old.getFileId() != null && !old.getFileId().isEmpty()) {
|
||||
List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
for (Long l : oldFileId) {
|
||||
if (!nowFileId.contains(l)) {
|
||||
sysOssService.deleteWithValidByIds(List.of(l), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (old.getFileId()!= null && !old.getFileId().isEmpty()){
|
||||
List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
sysOssService.deleteWithValidByIds(deleteIds, false);
|
||||
}
|
||||
}
|
||||
// if (bo.getFileId() != null && !bo.getFileId().isEmpty()){
|
||||
// if (old.getFileId() != null && !old.getFileId().isEmpty()) {
|
||||
// List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
// List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
// for (Long l : oldFileId) {
|
||||
// if (!nowFileId.contains(l)) {
|
||||
// sysOssService.deleteWithValidByIds(List.of(l), false);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }else {
|
||||
// if (old.getFileId()!= null && !old.getFileId().isEmpty()){
|
||||
// List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
// sysOssService.deleteWithValidByIds(deleteIds, false);
|
||||
// }
|
||||
// }
|
||||
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
@ -565,6 +536,11 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
|
||||
info.setContractAmount(changeVo.getPostChangeTotalCost());
|
||||
}
|
||||
|
||||
//获取开票单位(部门公司)
|
||||
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(info.getInvoicingUnit());
|
||||
if (sysDeptVo != null){
|
||||
info.setInvoicingUnitName(sysDeptVo.getDeptName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,26 +1,27 @@
|
||||
package org.dromara.xzd.spykp.spdj.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 jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.xzd.spykp.spdj.domain.vo.XzdSpykpSpdjVo;
|
||||
import org.dromara.xzd.spykp.spdj.domain.bo.XzdSpykpSpdjBo;
|
||||
import org.dromara.xzd.spykp.spdj.service.IXzdSpykpSpdjService;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.xzd.spykp.spdj.domain.bo.XzdSpykpSpdjBo;
|
||||
import org.dromara.xzd.spykp.spdj.domain.vo.XzdSpykpSpdjVo;
|
||||
import org.dromara.xzd.spykp.spdj.service.IXzdSpykpSpdjService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 收票登记
|
||||
@ -31,7 +32,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/spdj/spdj")
|
||||
@RequestMapping("/xzd/spdj/spdj")
|
||||
public class XzdSpykpSpdjController extends BaseController {
|
||||
|
||||
private final IXzdSpykpSpdjService xzdSpykpSpdjService;
|
||||
|
||||
@ -252,5 +252,9 @@ public class XzdSpykpSpdj extends BaseEntity {
|
||||
*/
|
||||
private Long contractId;
|
||||
|
||||
/**
|
||||
* 审核状态
|
||||
*/
|
||||
private String shzt;
|
||||
|
||||
}
|
||||
|
||||
@ -250,5 +250,8 @@ public class XzdSpykpSpdjBo extends BaseEntity {
|
||||
*/
|
||||
private Long contractId;
|
||||
|
||||
|
||||
/**
|
||||
* 审核状态
|
||||
*/
|
||||
private String shzt;
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.translation.annotation.Translation;
|
||||
import org.dromara.common.translation.constant.TransConstant;
|
||||
import org.dromara.xzd.spykp.spdj.domain.XzdSpykpSpdj;
|
||||
|
||||
import java.io.Serial;
|
||||
@ -190,6 +192,7 @@ public class XzdSpykpSpdjVo implements Serializable {
|
||||
/**
|
||||
* 销方(客户)名称
|
||||
*/
|
||||
@Translation(type = TransConstant.XZD_KHXX_ID_TO_NAME,mapper = "xfId")
|
||||
private String xfmc;
|
||||
|
||||
/**
|
||||
@ -323,4 +326,8 @@ public class XzdSpykpSpdjVo implements Serializable {
|
||||
*/
|
||||
private String contractName;
|
||||
|
||||
/**
|
||||
* 审核状态
|
||||
*/
|
||||
private String shzt;
|
||||
}
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
package org.dromara.xzd.spykp.spdj.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.dromara.common.core.domain.R;
|
||||
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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessEvent;
|
||||
import org.dromara.common.core.domain.event.ProcessTaskEvent;
|
||||
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.system.domain.vo.SysDeptVo;
|
||||
import org.dromara.system.domain.vo.SysUserVo;
|
||||
import org.dromara.system.service.impl.SysDeptServiceImpl;
|
||||
@ -17,22 +20,23 @@ import org.dromara.system.service.impl.SysOssServiceImpl;
|
||||
import org.dromara.system.service.impl.SysUserServiceImpl;
|
||||
import org.dromara.xzd.domain.XzdContractDetails;
|
||||
import org.dromara.xzd.domain.XzdProject;
|
||||
import org.dromara.xzd.domain.dto.QuerCorrespondentDto;
|
||||
import org.dromara.xzd.service.IXzdCorrespondentList;
|
||||
import org.dromara.xzd.service.impl.XzdContractDetailsServiceImpl;
|
||||
import org.dromara.xzd.service.impl.XzdProjectServiceImpl;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.dromara.xzd.spykp.spdj.domain.XzdSpykpSpdj;
|
||||
import org.dromara.xzd.spykp.spdj.domain.bo.XzdSpykpSpdjBo;
|
||||
import org.dromara.xzd.spykp.spdj.domain.vo.XzdSpykpSpdjVo;
|
||||
import org.dromara.xzd.spykp.spdj.domain.XzdSpykpSpdj;
|
||||
import org.dromara.xzd.spykp.spdj.mapper.XzdSpykpSpdjMapper;
|
||||
import org.dromara.xzd.spykp.spdj.service.IXzdSpykpSpdjService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 收票登记Service业务层处理
|
||||
@ -42,6 +46,7 @@ import java.util.Collection;
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
@Slf4j
|
||||
public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, XzdSpykpSpdj> implements IXzdSpykpSpdjService {
|
||||
|
||||
private final XzdSpykpSpdjMapper baseMapper;
|
||||
@ -173,44 +178,44 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, Xzd
|
||||
XzdSpykpSpdj update = MapstructUtils.convert(bo, XzdSpykpSpdj.class);
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
XzdSpykpSpdj old = baseMapper.selectById(update.getId());
|
||||
// XzdSpykpSpdj old = baseMapper.selectById(update.getId());
|
||||
//更新文件
|
||||
if (bo.getFileId() != null && !bo.getFileId().isEmpty()){
|
||||
if (old.getFileId() != null && !old.getFileId().isEmpty()) {
|
||||
List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
for (Long l : oldFileId) {
|
||||
if (!nowFileId.contains(l)) {
|
||||
sysOssService.deleteWithValidByIds(List.of(l), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (old.getFileId()!= null && !old.getFileId().isEmpty()){
|
||||
List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
sysOssService.deleteWithValidByIds(deleteIds, false);
|
||||
}
|
||||
}
|
||||
//发票图片
|
||||
if (bo.getFptp() != null){
|
||||
if (!bo.getFptp().equals(old.getFptp())){
|
||||
sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false);
|
||||
}
|
||||
}else {
|
||||
if (old.getFptp()!= null){
|
||||
sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false);
|
||||
}
|
||||
}
|
||||
//证明信息文件
|
||||
if (bo.getZmxxwj() != null){
|
||||
if (!bo.getZmxxwj().equals(old.getZmxxwj())){
|
||||
sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false);
|
||||
}
|
||||
}else {
|
||||
if (old.getZmxxwj()!= null){
|
||||
sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false);
|
||||
}
|
||||
}
|
||||
// if (bo.getFileId() != null && !bo.getFileId().isEmpty()){
|
||||
// if (old.getFileId() != null && !old.getFileId().isEmpty()) {
|
||||
// List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
// List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
// for (Long l : oldFileId) {
|
||||
// if (!nowFileId.contains(l)) {
|
||||
// sysOssService.deleteWithValidByIds(List.of(l), false);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }else {
|
||||
// if (old.getFileId()!= null && !old.getFileId().isEmpty()){
|
||||
// List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
|
||||
// sysOssService.deleteWithValidByIds(deleteIds, false);
|
||||
// }
|
||||
// }
|
||||
// //发票图片
|
||||
// if (bo.getFptp() != null){
|
||||
// if (!bo.getFptp().equals(old.getFptp())){
|
||||
// sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false);
|
||||
// }
|
||||
// }else {
|
||||
// if (old.getFptp()!= null){
|
||||
// sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false);
|
||||
// }
|
||||
// }
|
||||
// //证明信息文件
|
||||
// if (bo.getZmxxwj() != null){
|
||||
// if (!bo.getZmxxwj().equals(old.getZmxxwj())){
|
||||
// sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false);
|
||||
// }
|
||||
// }else {
|
||||
// if (old.getZmxxwj()!= null){
|
||||
// sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false);
|
||||
// }
|
||||
// }
|
||||
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
@ -269,14 +274,14 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, Xzd
|
||||
}
|
||||
}
|
||||
//销方(客户id)
|
||||
if (vo.getXfId() != null){
|
||||
R<QuerCorrespondentDto> byid2 = iXzdCorrespondentList.getCustomerByid(vo.getXfId());
|
||||
if (byid2 != null) {
|
||||
if (byid2.getData().getXzdCustomerinformation() != null) {
|
||||
vo.setXfmc(byid2.getData().getXzdCustomerinformation().getUnitName());
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (vo.getXfId() != null){
|
||||
// R<QuerCorrespondentDto> byid2 = iXzdCorrespondentList.getCustomerByid(vo.getXfId());
|
||||
// if (byid2 != null) {
|
||||
// if (byid2.getData().getXzdCustomerinformation() != null) {
|
||||
// vo.setXfmc(byid2.getData().getXzdCustomerinformation().getUnitName());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//经办人
|
||||
if (vo.getJbrId() != null){
|
||||
SysUserVo sysUserVo = sysUserService.selectUserById(vo.getJbrId());
|
||||
@ -308,4 +313,51 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, Xzd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
|
||||
* 正常使用只需#processEvent.flowCode=='leave1'
|
||||
* 示例为了方便则使用startsWith匹配了全部示例key
|
||||
*
|
||||
* @param processEvent 参数
|
||||
*/
|
||||
@EventListener(condition = "#processEvent.flowCode.endsWith('XzdSpykpSpdj')")
|
||||
@Transactional
|
||||
public void processPlansHandler(ProcessEvent processEvent) {
|
||||
log.info("收票登记审核任务执行了{}", processEvent.toString());
|
||||
String id = processEvent.getBusinessId();
|
||||
XzdSpykpSpdj byId = this.getById(Long.valueOf(id));
|
||||
byId.setShzt(processEvent.getStatus());
|
||||
boolean b = this.updateById(byId);
|
||||
if (!b) {
|
||||
log.error("收票登记审核任务更新状态失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行任务创建监听
|
||||
* 示例:也可通过 @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")进行判断
|
||||
* 在方法中判断流程节点key
|
||||
* if ("xxx".equals(processTaskEvent.getNodeCode())) {
|
||||
* //执行业务逻辑
|
||||
* }
|
||||
*
|
||||
* @param processTaskEvent 参数
|
||||
*/
|
||||
@org.springframework.context.event.EventListener(condition = "#processTaskEvent.flowCode.endsWith('XzdSpykpSpdj')")
|
||||
public void processTaskPlansHandlerEquipmentList(ProcessTaskEvent processTaskEvent) {
|
||||
log.info("收票登记审核任务创建了{}", processTaskEvent.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听删除流程事件
|
||||
* 正常使用只需#processDeleteEvent.flowCode=='leave1'
|
||||
* 示例为了方便则使用startsWith匹配了全部示例key
|
||||
*
|
||||
* @param processDeleteEvent 参数
|
||||
*/
|
||||
@EventListener(condition = "#processDeleteEvent.flowCode.endsWith('XzdSpykpSpdj')")
|
||||
public void processDeletePlansHandlerEquipmentList(ProcessDeleteEvent processDeleteEvent) {
|
||||
log.info("承包合同计划删除流程事件{}", processDeleteEvent.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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.gps.mapper.GpsSafetyUserRecordMapper">
|
||||
|
||||
</mapper>
|
||||
@ -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.project.mapper.BusAttendanceMachineRepeatMapper">
|
||||
|
||||
</mapper>
|
||||
@ -8,8 +8,6 @@
|
||||
SELECT
|
||||
info.id,info.unit_code,info.unit_name,info.unified_social_credit_code,
|
||||
supplement.belonging_organization as sszz,
|
||||
# settlement.opening_bank as khyh,
|
||||
# settlement.account_number as khhzh,
|
||||
info.city_code as cityCode,
|
||||
info.shzt as shzt,
|
||||
yhxx.open_bank as khyh,
|
||||
@ -23,7 +21,6 @@
|
||||
supplement.responsible_salesman as fgywy,
|
||||
supplement.supplier_status as gyszt,
|
||||
(select ct.customer_type from (select info.id,ti.type,ti.primary_class,ti.customertype_id,info.unit_code from xzd_customertype_info ti left join xzd_supplier_info info on ti.customerinformation_id = info.id and ti.type like '2' where info.id is not NULL) as temp left join xzd_customertype ct on temp.customertype_id = ct.id where temp.id = info.id and temp.primary_class like '1') as gyslx,
|
||||
# type.customer_type as gyslx,
|
||||
supplement.supplier_level as gysdj,
|
||||
info.is_group_supplier as isGroupSupplier,
|
||||
info.is_blacklist as isBlacklist,
|
||||
@ -104,9 +101,6 @@
|
||||
|
||||
</where>
|
||||
ORDER BY info.create_time DESC
|
||||
<!-- <if test='bo.pageNum != null and bo.pageSize != null'>-->
|
||||
<!-- LIMIT #{bo.pageSize} OFFSET #{bo.offset}-->
|
||||
<!-- </if>-->
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
@ -1953,3 +1953,24 @@ CREATE TABLE `ai_chat_memory`
|
||||
INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id'
|
||||
) comment = 'AI 对话记录信息';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS gps_safety_user_record;
|
||||
CREATE TABLE `gps_safety_user_record`
|
||||
(
|
||||
`id` bigint not null auto_increment comment '主键',
|
||||
`project_id` bigint not null comment '项目id',
|
||||
`user_id` bigint not null comment '人员id',
|
||||
`client_id` varchar(20) not null comment '设备id',
|
||||
`user_name` varchar(64) null comment '人员名称',
|
||||
`record_date` date not null comment '记录时间',
|
||||
`entry_time` datetime null comment '入场时间',
|
||||
`exit_time` datetime null comment '退场时间',
|
||||
`remark` varchar(512) null comment '备注',
|
||||
`create_by` bigint null comment '创建者',
|
||||
`update_by` bigint null comment '更新者',
|
||||
`create_dept` bigint null comment '创建部门',
|
||||
`create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间',
|
||||
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id'
|
||||
) comment '安全员轨迹信息';
|
||||
|
||||
Reference in New Issue
Block a user