Merge branch 'refs/heads/dev' into updateMenu

This commit is contained in:
zt
2025-11-27 18:47:51 +08:00
65 changed files with 2281 additions and 313 deletions

View File

@ -5,6 +5,8 @@ import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator; import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -76,7 +78,7 @@ public class CaptchaController {
SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, map); SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, map);
if (!smsResponse.isSuccess()) { if (!smsResponse.isSuccess()) {
log.error("验证码短信发送异常 => {}", smsResponse); log.error("验证码短信发送异常 => {}", smsResponse);
return R.fail(smsResponse.getData().toString()); return R.fail(parseData(smsResponse));
} }
return R.ok(); return R.ok();
} }
@ -140,4 +142,35 @@ public class CaptchaController {
return R.ok(captchaVo); 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 -> "短信发送未知错误";
};
}
} }

View File

@ -41,10 +41,10 @@ snail-job:
spring: spring:
ai: ai:
dashscope: dashscope:
api-key: xxx api-key: sk-8d8df92fcbac4bd2922edba30b0bb8fa
chat: chat:
options: options:
model: qwen-plus model: qwen3-max
datasource: datasource:
type: com.zaxxer.hikari.HikariDataSource type: com.zaxxer.hikari.HikariDataSource
# 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content

View File

@ -76,9 +76,9 @@ spring:
servlet: servlet:
multipart: multipart:
# 单个文件大小 # 单个文件大小
max-file-size: 200MB max-file-size: 1024MB
# 设置总上传的文件大小 # 设置总上传的文件大小
max-request-size: 200MB max-request-size: 1024MB
mvc: mvc:
# 设置静态资源路径 防止所有请求都去查静态资源 # 设置静态资源路径 防止所有请求都去查静态资源
static-path-pattern: /static/** static-path-pattern: /static/**

View File

@ -1,14 +1,23 @@
package org.dromara.test; package org.dromara.test;
import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.manager.recognizermanager.RecognizerManager; import org.dromara.manager.recognizermanager.RecognizerManager;
import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum; import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum;
import org.dromara.manager.recognizermanager.vo.RecognizeVo; 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.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* @author lilemy * @author lilemy
@ -21,6 +30,12 @@ public class RecognizerTest {
@Resource @Resource
private RecognizerManager recognizerManager; private RecognizerManager recognizerManager;
@Resource
private IPgsProgressPlanDetailService progressPlanDetailService;
@Resource
private IPgsProgressPlanService progressPlanService;
@Test @Test
void test() { void test() {
RecognizeVo recognize = recognizerManager.recognize("http://xny.yj-3d.com:7363/file/tif/20250625160218orthophoto.png", List.of(RecognizerTypeEnum.PANEL)); 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() { void testChange() {
recognizerManager.convertCoordinate("http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/11/11/d48767a62bc04867a552e06ba6712004.tif", List.of()); 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());
}
}
}
} }

View File

@ -59,6 +59,18 @@ public class AsyncConfig implements AsyncConfigurer {
return executor; 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;
}
/** /**
* 异步执行异常处理 * 异步执行异常处理
*/ */

View File

@ -91,7 +91,7 @@ public class PlusDataPermissionHandler {
DataPermissionHelper.setVariable("user", currentUser); DataPermissionHelper.setVariable("user", currentUser);
} }
// 如果是超级管理员或租户管理员,则不过滤数据 // 如果是超级管理员或租户管理员,则不过滤数据
if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) { if (LoginHelper.isSuperAdmin()) {
return where; return where;
} }
// 构造数据过滤条件的 SQL 片段 // 构造数据过滤条件的 SQL 片段

View File

@ -1,5 +1,6 @@
package org.dromara.common.utils; package org.dromara.common.utils;
import cn.hutool.core.collection.CollectionUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MessageUtils; 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.DeviceMessageSender;
import org.dromara.mobileAttendanceMachine.KqjEntity; import org.dromara.mobileAttendanceMachine.KqjEntity;
import org.dromara.project.domain.BusAttendanceMachine; 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.project.service.IBusAttendanceMachineService;
import org.dromara.sms4j.api.SmsBlend; import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse; 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.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -36,6 +40,9 @@ public class AsyncUtil {
@Lazy @Lazy
private IBusAttendanceMachineService attendanceMachineService; private IBusAttendanceMachineService attendanceMachineService;
@Resource
private IBusAttendanceMachineRepeatService busAttendanceMachineRepeatService;
//发送短信 //发送短信
@Async @Async
public void sendSms(List<String> mobileList, String config) { public void sendSms(List<String> mobileList, String config) {
@ -63,22 +70,107 @@ public class AsyncUtil {
public void sendPersonnel(Long teamId, SubConstructionUser constructionUser) { public void sendPersonnel(Long teamId, SubConstructionUser constructionUser) {
SysOssVo byId = ossService.getById(Long.valueOf(constructionUser.getFacePic())); SysOssVo byId = ossService.getById(Long.valueOf(constructionUser.getFacePic()));
List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", teamId).list(); List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", teamId).list();
ArrayList<BusAttendanceMachineRepeat> repeats = new ArrayList<>();
for (BusAttendanceMachine machine : list) { 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 @Async
public void deletePersonnel(SubConstructionUser constructionUser) { public void deletePersonnel(SubConstructionUser constructionUser) {
ArrayList<BusAttendanceMachineRepeat> repeats = new ArrayList<>();
List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", constructionUser.getTeamId()).list(); List<BusAttendanceMachine> list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", constructionUser.getTeamId()).list();
for (BusAttendanceMachine machine : list) { for (BusAttendanceMachine machine : list) {
try { 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) { } catch (Exception e) {
log.error("删除考勤人员异常", e); log.error("删除考勤人员异常", e);
} }
} }
if (CollectionUtil.isNotEmpty(repeatIds)) {
busAttendanceMachineRepeatService.removeByIds(repeatIds);
}
} }
} }

View File

@ -8,6 +8,7 @@ import org.dromara.common.constant.GeoJsonConstant;
import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.domain.GeoPoint; import org.dromara.common.domain.GeoPoint;
import org.dromara.facility.domain.FacMatrix;
import org.dromara.facility.domain.FacPhotovoltaicPanel; import org.dromara.facility.domain.FacPhotovoltaicPanel;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane; import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint; import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
@ -338,6 +339,29 @@ public class JSTUtil {
return null; 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 * 将 FacPhotovoltaicPanel.positions 转成 Polygon
*/ */
@ -376,7 +400,7 @@ public class JSTUtil {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
list.add(s); list.add(s);
List<GeoPoint> matchingRange = findMatchingRange("30.247348", "105.729797", list); List<GeoPoint> matchingRange = findMatchingRange("30.247348", "105.729797", list);
System.out.println(matchingRange==null); System.out.println(matchingRange == null);
} }

View File

@ -92,7 +92,7 @@ public class SubAttendanceMachineUserServiceImpl implements ISubAttendanceMachin
vo.setMachineId(req.getMachineId()); vo.setMachineId(req.getMachineId());
vo.setContractorId(req.getContractorId()); vo.setContractorId(req.getContractorId());
vo.setUserId(userVo.getUserId()); vo.setUserId(userVo.getUserId());
vo.setUserName(userVo.getUserName()); vo.setUserName(userVo.getNickName());
if (CollUtil.isEmpty(finalUserIdList)) { if (CollUtil.isEmpty(finalUserIdList)) {
vo.setIdentifying(0); vo.setIdentifying(0);
} else if (finalUserIdList.contains(userVo.getUserId().toString())) { } else if (finalUserIdList.contains(userVo.getUserId().toString())) {

View File

@ -257,6 +257,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
constructionUser.setTypeOfWork(dto.getTypeOfWork()); constructionUser.setTypeOfWork(dto.getTypeOfWork());
constructionUser.setEntryDate(new Date()); constructionUser.setEntryDate(new Date());
constructionUser.setFirstDate(LocalDate.now()); constructionUser.setFirstDate(LocalDate.now());
constructionUser.setStatus("0");
int i = baseMapper.updateById(constructionUser); int i = baseMapper.updateById(constructionUser);

View File

@ -20,6 +20,7 @@ import org.dromara.drone.domain.vo.DroDroneBigPictureVo;
import org.dromara.drone.service.IDroDroneBigPictureService; import org.dromara.drone.service.IDroDroneBigPictureService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -57,6 +58,16 @@ public class DroDroneBigPictureController extends BaseController {
ExcelUtil.exportExcel(list, "无人机大图信息", DroDroneBigPictureVo.class, response); 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() @RepeatSubmit()
@PostMapping() @PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody DroDroneBigPictureBo bo) { public R<Void> add(@Validated(AddGroup.class) @RequestBody DroDroneBigPictureBo bo) {
return toAjax(droDroneBigPictureService.insertByBo(bo)); return toAjax(droDroneBigPictureService.insertByBo(bo, true));
} }
/** /**

View File

@ -73,6 +73,11 @@ public class DroDroneBigPicture extends BaseEntity {
*/ */
private String tifFile; private String tifFile;
/**
* 来源类型
*/
private String sourceType;
/** /**
* 状态 * 状态
*/ */

View File

@ -74,6 +74,11 @@ public class DroDroneBigPictureBo extends BaseEntity {
*/ */
private String tifFile; private String tifFile;
/**
* 来源类型
*/
private String sourceType;
/** /**
* 状态 * 状态
*/ */

View File

@ -91,12 +91,23 @@ public class DroDroneBigPictureVo implements Serializable {
*/ */
private String recognizeResult; private String recognizeResult;
/**
* 识别结果列表
*/
private String recognizeResultStr;
/** /**
* tif文件 * tif文件
*/ */
@ExcelProperty(value = "tif文件") @ExcelProperty(value = "tif文件")
private String tifFile; private String tifFile;
/**
* 来源类型
*/
@ExcelProperty(value = "来源类型")
private String sourceType;
/** /**
* 状态 * 状态
*/ */

View File

@ -7,7 +7,9 @@ import org.dromara.drone.domain.DroDroneBigPicture;
import org.dromara.drone.domain.bo.DroDroneBigPictureBo; import org.dromara.drone.domain.bo.DroDroneBigPictureBo;
import org.dromara.drone.domain.bo.DroDroneBigPictureProgressVo; import org.dromara.drone.domain.bo.DroDroneBigPictureProgressVo;
import org.dromara.drone.domain.vo.DroDroneBigPictureVo; import org.dromara.drone.domain.vo.DroDroneBigPictureVo;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -48,10 +50,11 @@ public interface IDroDroneBigPictureService extends IService<DroDroneBigPicture>
/** /**
* 新增无人机大图信息 * 新增无人机大图信息
* *
* @param bo 无人机大图信息 * @param bo 无人机大图信息
* @param isNew 是否创建新记录
* @return 是否新增成功 * @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); 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 是否成功 * @return 是否成功
*/ */
CompletableFuture<Boolean> asyncUpdateCompressPicture(DroDroneBigPicture pic, DroDroneBigPicture oldPic); 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);
} }

View File

@ -2,6 +2,10 @@ package org.dromara.drone.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; 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.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.DroneManager;
import org.dromara.manager.dronemanager.vo.DroneImgMergeProgressVo; import org.dromara.manager.dronemanager.vo.DroneImgMergeProgressVo;
import org.dromara.manager.dronemanager.vo.DroneImgMergeUrlVo; 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.dto.progressplandetail.PgsProgressPlanDetailAINumberReq;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailRecognizerVo;
import org.dromara.progress.service.IPgsProgressPlanDetailService; import org.dromara.progress.service.IPgsProgressPlanDetailService;
import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService; 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.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -54,7 +62,8 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictureMapper, DroDroneBigPicture> public
class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictureMapper, DroDroneBigPicture>
implements IDroDroneBigPictureService { implements IDroDroneBigPictureService {
@Lazy @Lazy
@ -90,11 +99,34 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
BigDecimal p = progressVo.getProgress() BigDecimal p = progressVo.getProgress()
.multiply(new BigDecimal("100")); .multiply(new BigDecimal("100"));
pictureVo.setProgress(p.compareTo(BigDecimal.valueOf(100)) == 0 ? 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) { } catch (Exception e) {
log.error("查询图片合成进度异常", 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; return pictureVo;
} }
@ -123,13 +155,36 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
BigDecimal p = progressVo.getProgress() BigDecimal p = progressVo.getProgress()
.multiply(new BigDecimal("100")); .multiply(new BigDecimal("100"));
pictureVo.setProgress(p.compareTo(BigDecimal.valueOf(100)) == 0 ? 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) { } catch (Exception e) {
pictureVo.setStatus("4"); pictureVo.setStatus("4");
pictureVo.setRemark(e.getMessage()); pictureVo.setRemark(e.getMessage());
log.error("查询图片合成进度异常", 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);
}
}
} }
} }
result.setRecords(records); 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(StringUtils.isNotBlank(bo.getBigPic()), DroDroneBigPicture::getBigPic, bo.getBigPic());
lqw.eq(bo.getRecognizePic() != null, DroDroneBigPicture::getRecognizePic, bo.getRecognizePic()); lqw.eq(bo.getRecognizePic() != null, DroDroneBigPicture::getRecognizePic, bo.getRecognizePic());
lqw.eq(StringUtils.isNotBlank(bo.getTifFile()), DroDroneBigPicture::getTifFile, bo.getTifFile()); 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()); lqw.eq(StringUtils.isNotBlank(bo.getStatus()), DroDroneBigPicture::getStatus, bo.getStatus());
return lqw; return lqw;
} }
@ -164,19 +220,27 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
/** /**
* 新增无人机大图信息 * 新增无人机大图信息
* *
* @param bo 无人机大图信息 * @param bo 无人机大图信息
* @param isNew 是否创建新记录
* @return 是否新增成功 * @return 是否新增成功
*/ */
@Override @Override
public Boolean insertByBo(DroDroneBigPictureBo bo) { public Boolean insertByBo(DroDroneBigPictureBo bo, Boolean isNew) {
DroDroneBigPicture add = MapstructUtils.convert(bo, DroDroneBigPicture.class); DroDroneBigPicture add = MapstructUtils.convert(bo, DroDroneBigPicture.class);
if (add == null) { if (add == null) {
return false; return false;
} }
boolean save = this.save(add); if (isNew) {
if (!save) { if (StringUtils.isNotBlank(add.getBigPic()) && StringUtils.isNotBlank(add.getTifFile())) {
throw new ServiceException("新增无人机大图信息失败"); add.setStatus("3");
}
add.setSourceType("1");
boolean save = this.save(add);
if (!save) {
throw new ServiceException("新增无人机大图信息失败");
}
} }
Long id = add.getId();
// 压缩图片 // 压缩图片
String smallPic = add.getSmallPic(); String smallPic = add.getSmallPic();
if (StringUtils.isNotBlank(smallPic)) { if (StringUtils.isNotBlank(smallPic)) {
@ -188,7 +252,7 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
.map(String::valueOf) .map(String::valueOf)
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
DroDroneBigPicture update = new DroDroneBigPicture(); DroDroneBigPicture update = new DroDroneBigPicture();
update.setId(add.getId()); update.setId(id);
update.setCompressPic(ossIds); update.setCompressPic(ossIds);
this.updateById(update); this.updateById(update);
}).exceptionally(ex -> { }).exceptionally(ex -> {
@ -196,6 +260,30 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
return null; 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; return true;
} }
@ -254,8 +342,26 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
fileUrl = mergeUrlVo.getPngUrl(); fileUrl = mergeUrlVo.getPngUrl();
tifUrl = mergeUrlVo.getTifUrl(); tifUrl = mergeUrlVo.getTifUrl();
} else { } else {
fileUrl = bigPicture.getBigPic(); String bigPic = bigPicture.getBigPic();
tifUrl = bigPicture.getTifFile(); 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(); PgsProgressPlanDetailAINumberReq ai = new PgsProgressPlanDetailAINumberReq();
@ -317,6 +423,32 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
throw new ServiceException("图片删除异常"); 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); return this.removeBatchByIds(ids);
} }
@ -342,7 +474,12 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
if (!status.equals("2")) { if (!status.equals("2")) {
return vo; 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) { if (imgMergeProgress == null) {
return vo; 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) { } else if (msg != null && msg.compareTo(BigDecimal.ZERO) >= 0 && msg.compareTo(BigDecimal.ONE) < 0) {
return vo; return vo;
} else { } else {
vo.setProgress(BigDecimal.ZERO);
newStatus = "4"; newStatus = "4";
picture.setStatus(newStatus); picture.setStatus(newStatus);
} }
@ -413,6 +551,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
return true; 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); 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是否相同 * 判断两个Ids是否相同
* *
@ -516,4 +797,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl<DroDroneBigPictur
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return set1.equals(set2); 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;
}
}
} }

View File

@ -773,11 +773,11 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
// 获取项目下的所有未完成的光伏板 // 获取项目下的所有未完成的光伏板
List<FacPhotovoltaicPanel> panelList = this.lambdaQuery() List<FacPhotovoltaicPanel> panelList = this.lambdaQuery()
.in(FacPhotovoltaicPanel::getProjectId, projectIds) .in(FacPhotovoltaicPanel::getProjectId, projectIds)
.ne(FacPhotovoltaicPanel::getStatus, FacFinishStatusEnum.FINISH.getValue())
.eq(type.equals(RecognizerTypeEnum.BRACKET.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "支架安装") .eq(type.equals(RecognizerTypeEnum.BRACKET.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "支架安装")
.eq(type.equals(RecognizerTypeEnum.PANEL.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "组件安装") .eq(type.equals(RecognizerTypeEnum.PANEL.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "组件安装")
.list(); .list();
if (CollUtil.isEmpty(panelList)) { if (CollUtil.isEmpty(panelList)) {
log.info("没有需要更新的光伏板");
return recognizeVoList; return recognizeVoList;
} }
// 判断识别出来的坐标是否包含在某个面内 // 判断识别出来的坐标是否包含在某个面内
@ -792,7 +792,9 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
vo.setName(containingPanel.getName()); vo.setName(containingPanel.getName());
vo.setType(type); vo.setType(type);
recognizeVoList.add(vo); recognizeVoList.add(vo);
finishPanelList.add(containingPanel); if (!containingPanel.getStatus().equals(FacFinishStatusEnum.FINISH.getValue())) {
finishPanelList.add(containingPanel);
}
} }
} }
if (CollUtil.isNotEmpty(finishPanelList)) { if (CollUtil.isNotEmpty(finishPanelList)) {

View File

@ -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));
}
}

View File

@ -1,9 +1,8 @@
package org.dromara.gps.domain; package org.dromara.gps.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
@ -29,12 +28,12 @@ public class GpsManmachine implements Serializable {
private String clientId; private String clientId;
/** /**
* 绑定id * 绑定id
*/ */
private Long userId; private Long userId;
/** /**
* 类型绑定id类型1车辆2人员 * 类型绑定id类型1车辆 2人员 3安全员
*/ */
private Integer type; private Integer type;

View File

@ -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;
}

View File

@ -1,13 +1,12 @@
package org.dromara.gps.domain.bo; 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 io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; 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; import java.util.List;
@ -25,7 +24,7 @@ public class GpsEquipmentBo extends BaseEntity {
/** /**
* 主键ID * 主键ID
*/ */
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) @NotNull(message = "主键ID不能为空", groups = {EditGroup.class})
private Long id; private Long id;
/** /**
@ -88,7 +87,7 @@ public class GpsEquipmentBo extends BaseEntity {
private Integer gpsType; private Integer gpsType;
/** /**
* 设备类型0人员设备1、车辆设备) * 设备类型0人员设备 1车辆设备 2安全员设备)
*/ */
private Integer clientType; private Integer clientType;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,12 +1,10 @@
package org.dromara.gps.mapper; package org.dromara.gps.mapper;
import jakarta.validation.constraints.NotNull;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; 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.GpsEquipment;
import org.dromara.gps.domain.vo.GpsEquipmentVo; import org.dromara.gps.domain.vo.GpsEquipmentVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.gps.domain.vo.GpsUserVo; import org.dromara.gps.domain.vo.GpsUserVo;
import java.util.List; import java.util.List;
@ -21,7 +19,7 @@ public interface GpsEquipmentMapper extends BaseMapperPlus<GpsEquipment, GpsEqui
@Select("SELECT\n" + @Select("SELECT\n" +
" gm.user_id AS userId,\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" + " gm.project_id AS projectId,\n" +
" bp.project_name AS projectName \n" + " bp.project_name AS projectName \n" +
"FROM\n" + "FROM\n" +

View File

@ -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> {
}

View File

@ -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);
}

View File

@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException; 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.mapper.GpsManmachineMapper;
import org.dromara.gps.service.IGpsEquipmentService; import org.dromara.gps.service.IGpsEquipmentService;
import org.dromara.gps.service.IGpsEquipmentSonService; import org.dromara.gps.service.IGpsEquipmentSonService;
import org.dromara.gps.service.IGpsSafetyUserRecordService;
import org.dromara.project.domain.vo.project.BusProjectVo; import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.domain.vo.SysUserVo;
@ -81,6 +83,9 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
@Autowired @Autowired
private IVehVehicleTripService iVehVehicleTripService; private IVehVehicleTripService iVehVehicleTripService;
@Resource
private IGpsSafetyUserRecordService safetyUserRecordService;
/** /**
* 查询GPS设备详细 * 查询GPS设备详细
* *
@ -265,7 +270,9 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
gpsEquipmentSonService.insertByBo(gpsEquipmentSon); gpsEquipmentSonService.insertByBo(gpsEquipmentSon);
// 记录安全员轨迹
safetyUserRecordService.validTrackByEquipment(gpsEquipmentSon.getClientId(), gpsEquipmentSon.getProjectId(),
gpsEquipmentSon.getUserId(), location.getStr("longitude"), location.getStr("latitude"));
//保存到redis如果存在则更新存活时间 //保存到redis如果存在则更新存活时间
// -------------------------- // --------------------------
@ -465,7 +472,13 @@ public class GpsEquipmentServiceImpl extends ServiceImpl<GpsEquipmentMapper, Gps
GpsManmachine gpsManmachine = new GpsManmachine(); GpsManmachine gpsManmachine = new GpsManmachine();
gpsManmachine.setClientId(bo.getClientId()); gpsManmachine.setClientId(bo.getClientId());
gpsManmachine.setUserId(bo.getUserId()); 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) { if (bo.getClientType() == 1) {
iVehVehicleInfoService.update(new LambdaUpdateWrapper<VehVehicleInfo>().set(VehVehicleInfo::getClientId, bo.getClientId()).eq(VehVehicleInfo::getId, bo.getUserId())); iVehVehicleInfoService.update(new LambdaUpdateWrapper<VehVehicleInfo>().set(VehVehicleInfo::getClientId, bo.getClientId()).eq(VehVehicleInfo::getId, bo.getUserId()));
} }

View File

@ -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);
}
}

View File

@ -34,6 +34,7 @@ public class DroneManager {
* *
* @param businessName 业务名称 * @param businessName 业务名称
* @param imageUrls 图片URL列表 * @param imageUrls 图片URL列表
* @return 任务ID
*/ */
public String createImageMergeTask(String businessName, List<String> imageUrls) { public String createImageMergeTask(String businessName, List<String> imageUrls) {
return DroneRequestUtils.createImgMergeTask(droneProperties.getUrl(), businessName, imageUrls); return DroneRequestUtils.createImgMergeTask(droneProperties.getUrl(), businessName, imageUrls);

View File

@ -67,6 +67,7 @@ public class DroneRequestUtils {
* *
* @param businessName 业务名称 * @param businessName 业务名称
* @param imageUrls 图片URL列表 * @param imageUrls 图片URL列表
* @return 任务ID
*/ */
public static String createImgMergeTask(String url, String businessName, List<String> imageUrls) { public static String createImgMergeTask(String url, String businessName, List<String> imageUrls) {
if (StringUtils.isBlank(businessName) || CollUtil.isEmpty(imageUrls)) { if (StringUtils.isBlank(businessName) || CollUtil.isEmpty(imageUrls)) {
@ -97,17 +98,17 @@ public class DroneRequestUtils {
} }
/** /**
* 下载图片合成结果 * 获取图片合成结果
* *
* @param taskId 任务ID * @param taskId 任务ID
*/ */
public static DroneImgMergeUrlVo getMergedFileUrl(String url, String taskId) { public static DroneImgMergeUrlVo getMergedFileUrl(String url, String taskId) {
if (StringUtils.isAnyBlank(taskId)) { if (StringUtils.isAnyBlank(taskId)) {
throw new ServiceException("下载图片合成结果请求参数错误", HttpStatus.BAD_REQUEST); throw new ServiceException("获取图片合成结果请求参数错误", HttpStatus.BAD_REQUEST);
} }
// 完整 URL // 完整 URL
String fullUrl = url + DroneConstant.GET_MERGED_FILE_URL + "/" + taskId; String fullUrl = url + DroneConstant.GET_MERGED_FILE_URL + "/" + taskId;
String errorMsg = "下载图片合成结果请求失败"; String errorMsg = "获取图片合成结果请求失败";
try (HttpResponse response = HttpRequest.get(fullUrl).execute()) { try (HttpResponse response = HttpRequest.get(fullUrl).execute()) {
if (!response.isOk()) { if (!response.isOk()) {
log.error("{}{}", errorMsg, response.getStatus()); log.error("{}{}", errorMsg, response.getStatus());
@ -121,7 +122,7 @@ public class DroneRequestUtils {
} }
String data = obj.getStr("data"); String data = obj.getStr("data");
DroneImgMergeUrlVo mergeUrlVo = JSONUtil.toBean(data, DroneImgMergeUrlVo.class); DroneImgMergeUrlVo mergeUrlVo = JSONUtil.toBean(data, DroneImgMergeUrlVo.class);
log.info("下载图片合成结果请求成功:{}", mergeUrlVo); log.info("获取图片合成结果请求成功:{}", mergeUrlVo);
return mergeUrlVo; return mergeUrlVo;
} }
} }
@ -148,7 +149,14 @@ public class DroneRequestUtils {
JSONObject obj = JSONUtil.parseObj(body); JSONObject obj = JSONUtil.parseObj(body);
if (!obj.getStr("code").equals("200")) { if (!obj.getStr("code").equals("200")) {
log.error("{},状态码:{},错误信息:{}", errorMsg, obj.get("code"), obj.get("msg")); 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); DroneImgMergeProgressVo progress = JSONUtil.toBean(obj, DroneImgMergeProgressVo.class);
if (progress == null) { if (progress == null) {

View File

@ -453,7 +453,7 @@ public class OutTableController extends BaseController {
BigDecimal monthCompletionValue = BigDecimal.ZERO; BigDecimal monthCompletionValue = BigDecimal.ZERO;
for (BusProcurement busProcurement : busProcurements1) { 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)); monthCompletionValue = monthCompletionValue.add(busProcurement.getAcceptedQuantity().multiply(busProcurement.getUnitPrice()).setScale(4, RoundingMode.HALF_UP));
} }
} }

View File

@ -1184,6 +1184,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
droDroneBigPicture.setProjectId(projectId); droDroneBigPicture.setProjectId(projectId);
droDroneBigPicture.setBigPic(fileUrl); droDroneBigPicture.setBigPic(fileUrl);
droDroneBigPicture.setTifFile(tifUrl); droDroneBigPicture.setTifFile(tifUrl);
droDroneBigPicture.setSourceType("2");
droDroneBigPicture.setStatus("5"); droDroneBigPicture.setStatus("5");
boolean save = droDroneBigPictureService.save(droDroneBigPicture); boolean save = droDroneBigPictureService.save(droDroneBigPicture);
if (!save) { if (!save) {
@ -1230,7 +1231,12 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
} }
if (recognizeVo.getHasTarget().equals(RecognizerHasTargetEnum.NO.getValue())) { if (recognizeVo.getHasTarget().equals(RecognizerHasTargetEnum.NO.getValue())) {
log.info("没有识别到设施"); 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); String fileName = FileNameUtil.getName(fileUrl);
List<RecognizeTargetVo> targets = recognizeVo.getTargets(); List<RecognizeTargetVo> targets = recognizeVo.getTargets();
@ -1281,6 +1287,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
recognizePic = drawnVo.getOssId(); recognizePic = drawnVo.getOssId();
} }
} catch (IOException | URISyntaxException e) { } catch (IOException | URISyntaxException e) {
log.error("将识别数据同步到图片上失败", e);
throw new ServiceException("将识别数据同步到图片上失败", HttpStatus.ERROR); throw new ServiceException("将识别数据同步到图片上失败", HttpStatus.ERROR);
} }
String recognizerStr = JSONUtil.toJsonStr(recognizerVoList); String recognizerStr = JSONUtil.toJsonStr(recognizerVoList);

View File

@ -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));
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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> {
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -409,6 +409,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
if (!checkInRange(req)) { if (!checkInRange(req)) {
throw new ServiceException("打卡位置不在范围内", HttpStatus.ERROR); throw new ServiceException("打卡位置不在范围内", HttpStatus.ERROR);
} }
} }
//用户信息校验 //用户信息校验
SubConstructionUser constructionUser = constructionUserService.getBySysUserId(userId); SubConstructionUser constructionUser = constructionUserService.getBySysUserId(userId);
@ -429,15 +430,16 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
// 判断用户是否已经被拉黑 // 判断用户是否已经被拉黑
constructionBlacklistService.validUserInBlacklist(constructionUser.getSysUserId(), req.getProjectId()); constructionBlacklistService.validUserInBlacklist(constructionUser.getSysUserId(), req.getProjectId());
Boolean result = false; Boolean result = false;
// 进行人脸比对 // 进行人脸比对 考勤机过来不需进行这一步
try { if (!"1".equals(req.getSource())) {
result = constructionUserService.faceComparison(file, userId); try {
} catch (Exception e) { result = constructionUserService.faceComparison(file, userId);
throw new ServiceException(e.getMessage(), HttpStatus.ERROR); } catch (Exception e) {
} throw new ServiceException(e.getMessage(), HttpStatus.ERROR);
}
if (!result) { if (!result) {
throw new ServiceException("人脸识别失败,请重新识别", HttpStatus.ERROR); throw new ServiceException("人脸识别失败,请重新识别", HttpStatus.ERROR);
}
} }
//打卡规则 //打卡规则
@ -478,10 +480,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
attendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue()); attendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
} }
//只要请假,直接归为请假 //只要请假,直接归为请假
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime()); //LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
if (leaveService.isLeave(localDateTime, userId)) { //if (leaveService.isLeave(localDateTime, userId)) {
attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue()); // attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
} //}
// 填充信息 // 填充信息
attendance.setUserId(userId); attendance.setUserId(userId);
@ -532,10 +534,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue()); busAttendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
} }
//只要请假,直接归为请假 //只要请假,直接归为请假
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime()); //LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
if (leaveService.isLeave(localDateTime, userId)) { //if (leaveService.isLeave(localDateTime, userId)) {
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue()); // busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
} //}
busAttendance.setSource(req.getSource()); busAttendance.setSource(req.getSource());
busAttendance.setSn(req.getSn()); busAttendance.setSn(req.getSn());
@ -576,10 +578,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
busAttendance.setMinuteCount(0); busAttendance.setMinuteCount(0);
} }
//只要请假,直接归为请假 //只要请假,直接归为请假
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime()); //LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
if (leaveService.isLeave(localDateTime, userId)) { //if (leaveService.isLeave(localDateTime, userId)) {
busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue()); // busAttendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
} //}
updateById(busAttendance); updateById(busAttendance);
} else { } else {
BusAttendance attendance = new BusAttendance(); BusAttendance attendance = new BusAttendance();
@ -594,10 +596,10 @@ public class BusAttendanceServiceImpl extends ServiceImpl<BusAttendanceMapper, B
attendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue()); attendance.setClockStatus(BusAttendanceClockStatusEnum.NORMAL.getValue());
} }
//只要请假,直接归为请假 //只要请假,直接归为请假
LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime()); //LocalDateTime localDateTime = localDate.atTime(busAttendanceRuleVo.getClockInTime());
if (leaveService.isLeave(localDateTime, userId)) { //if (leaveService.isLeave(localDateTime, userId)) {
attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue()); // attendance.setClockStatus(BusAttendanceClockStatusEnum.LEAVE.getValue());
} //}
// 填充信息 // 填充信息
attendance.setUserId(userId); attendance.setUserId(userId);
attendance.setProjectId(req.getProjectId()); attendance.setProjectId(req.getProjectId());

View File

@ -216,6 +216,7 @@ public class BusConstructionUserExitServiceImpl extends ServiceImpl<BusConstruct
LambdaUpdateWrapper<SubConstructionUser> constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class) LambdaUpdateWrapper<SubConstructionUser> constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class)
.eq(SubConstructionUser::getId, constructionUser.getId()) .eq(SubConstructionUser::getId, constructionUser.getId())
.set(SubConstructionUser::getTeamId, null) .set(SubConstructionUser::getTeamId, null)
.set(SubConstructionUser::getStatus, "1")
.set(SubConstructionUser::getLeaveDate, new Date()); .set(SubConstructionUser::getLeaveDate, new Date());
if (StringUtils.isNotBlank(salaryVoucherFile) && StringUtils.isNotBlank(salaryConfirmationFile)) { if (StringUtils.isNotBlank(salaryVoucherFile) && StringUtils.isNotBlank(salaryConfirmationFile)) {
constructionUserLuw.set(SubConstructionUser::getExitStatus, "2"); constructionUserLuw.set(SubConstructionUser::getExitStatus, "2");

View File

@ -190,6 +190,7 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
.set(SubConstructionUser::getLeaveDate, null) .set(SubConstructionUser::getLeaveDate, null)
.set(SubConstructionUser::getExitStatus, "0") .set(SubConstructionUser::getExitStatus, "0")
.set(SubConstructionUser::getUserRole, "0") .set(SubConstructionUser::getUserRole, "0")
.set(SubConstructionUser::getStatus, "0")
.set(StrUtil.isNotBlank(req.getTypeOfWork()), SubConstructionUser::getTypeOfWork, req.getTypeOfWork()) .set(StrUtil.isNotBlank(req.getTypeOfWork()), SubConstructionUser::getTypeOfWork, req.getTypeOfWork())
.set(constructionUser.getFirstDate() == null, SubConstructionUser::getFirstDate, LocalDate.now()); .set(constructionUser.getFirstDate() == null, SubConstructionUser::getFirstDate, LocalDate.now());
constructionUserService.update(constructionUserLuw); constructionUserService.update(constructionUserLuw);
@ -366,6 +367,7 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl<BusProjectTeamM
.eq(SubConstructionUser::getId, constructionUser.getId()) .eq(SubConstructionUser::getId, constructionUser.getId())
.set(SubConstructionUser::getExitStatus, exitStatus) .set(SubConstructionUser::getExitStatus, exitStatus)
.set(SubConstructionUser::getTeamId, null) .set(SubConstructionUser::getTeamId, null)
.set(SubConstructionUser::getStatus, "1")
.set(SubConstructionUser::getLeaveDate, new Date()); .set(SubConstructionUser::getLeaveDate, new Date());
constructionUserService.update(constructionUserLuw); constructionUserService.update(constructionUserLuw);

View File

@ -21,6 +21,7 @@ import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.exception.OssException; import org.dromara.common.oss.exception.OssException;
import org.dromara.common.oss.factory.OssFactory; import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.utils.DocumentUtil; import org.dromara.common.utils.DocumentUtil;
import org.dromara.project.domain.BusProject;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.quality.constant.QltQualityConstant; import org.dromara.quality.constant.QltQualityConstant;
import org.dromara.quality.domain.QltQualityConstructionLog; 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.mapper.QltQualityConstructionLogMapper;
import org.dromara.quality.service.IQltQualityConstructionLogService; import org.dromara.quality.service.IQltQualityConstructionLogService;
import org.dromara.system.domain.vo.SysOssVo; 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.ISysOssService;
import org.dromara.system.service.ISysUserService; import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -336,11 +338,25 @@ public class QltQualityConstructionLogServiceImpl extends ServiceImpl<QltQuality
*/ */
public Map<String, String> getReplacementMap(QltQualityConstructionLog qualityConstructionLog) { public Map<String, String> getReplacementMap(QltQualityConstructionLog qualityConstructionLog) {
Map<String, String> replacementMap = new HashMap<>(); 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); replacementMap.put("${createName}", createName);
Date createTime = qualityConstructionLog.getCreateTime(); Date createTime = qualityConstructionLog.getCreateTime();
replacementMap.put("${createTime}", createTime != null ? DateUtils.formatDateTime(createTime) : ""); 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); replacementMap.put("${projectName}", projectName);
LocalDate happenDate = qualityConstructionLog.getHappenDate(); LocalDate happenDate = qualityConstructionLog.getHappenDate();
replacementMap.put("${happenDate}", happenDate != null ? happenDate.toString() : ""); replacementMap.put("${happenDate}", happenDate != null ? happenDate.toString() : "");

View File

@ -391,51 +391,33 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
* @return 生成的Excel文件对象 * @return 生成的Excel文件对象
* @throws Exception 异常抛出 * @throws Exception 异常抛出
*/ */
public File generateWeeklyReportTemplate(HseSafetyWeeklyReport report,Integer weekOfYear) throws Exception { public File generateWeeklyReportTemplate(HseSafetyWeeklyReport report, Integer weekOfYear) throws Exception {
FileOutputStream outputStream = null; FileOutputStream outputStream = null;
File targetFile = null; File targetFile = null;
try { try {
// // 1. 确定目标文件 targetFile = File.createTempFile("周报_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss")), ".xlsx");
// 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");
// 2. 使用POI直接创建复杂格式 // 2. 使用POI直接创建复杂格式
Workbook workbook = new XSSFWorkbook(); Workbook workbook = new XSSFWorkbook();
// Sheet sheet = workbook.createSheet("9.13");
Sheet sheet = workbook.createSheet(LocalDate.now().toString()); Sheet sheet = workbook.createSheet(LocalDate.now().toString());
// 3. 构建完整模板结构 // 3. 构建完整模板结构
setupSheetBasicStyle(sheet); // 设置基础样式 setupSheetBasicStyle(sheet); // 设置基础样式
buildTemplateFullStructure(sheet, workbook,report,weekOfYear); // 创建所有内容 buildTemplateFullStructure(sheet, workbook, report, weekOfYear); // 创建所有内容
setKeyRowHeights(sheet); // 设置行高 setKeyRowHeights(sheet); // 设置行高
// 4. 写入文件 // 4. 设置条件格式 - 使用最简化版本确保能工作
// setupMinimalConditionalFormatting(sheet);
// 5. 写入文件
outputStream = new FileOutputStream(targetFile); outputStream = new FileOutputStream(targetFile);
workbook.write(outputStream); workbook.write(outputStream);
outputStream.flush(); outputStream.flush();
// 5. 关闭资源 // 6. 关闭资源
workbook.close(); workbook.close();
// if (outputFilePath != null) {
// System.out.println("项目周报模板生成完成,文件路径:" + targetFile.getAbsolutePath());
// } else {
// System.out.println("项目周报模板生成完成,临时文件路径:" + targetFile.getAbsolutePath());
// }
return targetFile; return targetFile;
} catch (Exception e) { } 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, private void createConstructionProgressTable(Sheet sheet, Workbook workbook, int startRow,
CellStyle headerStyle, CellStyle contentStyle, CellStyle headerStyle, CellStyle contentStyle,
@ -932,15 +914,15 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
l11Cell.setCellValue("备注"); l11Cell.setCellValue("备注");
l11Cell.setCellStyle(tableHeaderStyle); l11Cell.setCellStyle(tableHeaderStyle);
// 数据行第12-18行共7行- 修正数据位置和赋值 // 数据行第12-18行共7行- 修正确保I列累计完成率有数值数据用于数据条显示
String[][] progressData = { String[][] progressData = {
{"基础", "光伏区", "", "164728", "3955", "104434", "63.4%", "6000", "设计值为根据7.18日最新电子版图纸统计包含未开工的五工区总设计容量约为357.5Mpw。"}, {"基础", "光伏区", "", "164728", "3955", "104434", "0.634", "6000", "设计值为根据7.18日最新电子版图纸统计包含未开工的五工区总设计容量约为357.5Mpw。"},
{"支架", "", "", "20591", "644", "6412", "31.1%", "1050", ""}, {"支架", "", "", "20591", "644", "6412", "0.311", "1050", ""},
{"组件", "", "", "20591", "409", "4902", "23.8%", "850", ""}, {"组件", "", "", "20591", "409", "4902", "0.238", "850", ""},
{"清表", "", "", "4517", "0", "4104", "90.8%", "100", ""}, {"清表", "", "", "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++) { 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列 for (int j = 0; j < 7; j++) { // 只设置前7列数据C-I列
Cell cell = row.createCell(j + 2); // C列开始 Cell cell = row.createCell(j + 2); // C列开始
if (j < progressData[i].length) { 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); 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, private void createEquipmentMaterialTable(Sheet sheet, Workbook workbook, int startRow,
CellStyle headerStyle, CellStyle contentStyle, CellStyle headerStyle, CellStyle contentStyle,
@ -1034,12 +1025,12 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl<HseSafetyWeekl
l19Cell.setCellValue("备注"); l19Cell.setCellValue("备注");
l19Cell.setCellStyle(tableHeaderStyle); l19Cell.setCellStyle(tableHeaderStyle);
// 数据行 - 从第20行开始共4行数据- 修正数据位置和赋值 // 数据行 - 从第20行开始共4行数据- 修正确保I列累计到货率有数值数据用于数据条显示
String[][] materialData = { String[][] materialData = {
{"檩条、斜撑", "", "", "131728", "3752", "106745", "81.0%", "", ""}, {"檩条、斜撑", "", "", "131728", "3752", "106745", "0.810", "", ""},
{"立杆", "", "", "133841", "5549", "53372", "39.9%", "", ""}, {"立杆", "", "", "133841", "5549", "53372", "0.399", "", ""},
{"光伏组件", "", "", "576548", "25880", "177360", "30.8%", "", ""}, {"光伏组件", "", "", "576548", "25880", "177360", "0.308", "", ""},
{"预埋件", "", "", "164728", "0", "113000", "68.6%", "", ""} {"预埋件", "", "", "164728", "0", "113000", "0.686", "", ""}
}; };
for (int i = 0; i < materialData.length; i++) { 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列 for (int j = 0; j < 7; j++) { // 只设置前7列数据C-I列
Cell cell = row.createCell(j + 2); // C列开始 Cell cell = row.createCell(j + 2); // C列开始
if (j < materialData[i].length) { 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); 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("跳过条件格式设置");
}
}
} }

View File

@ -2,11 +2,13 @@ package org.dromara.websocket.websocket.service;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.websocket.*; import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint; import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.utils.AsyncUtil;
import org.dromara.mobileAttendanceMachine.KqjEntity; import org.dromara.mobileAttendanceMachine.KqjEntity;
import org.dromara.project.service.IBusAttendanceMachineService; import org.dromara.project.service.IBusAttendanceMachineService;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -33,6 +35,9 @@ public class DeviceWebSocketServer {
private final static IBusAttendanceMachineService attendanceMachineService = SpringUtils.getBean(IBusAttendanceMachineService.class); 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 DECLARE = "declare"; // 设备注册消息
public static final String PING = "ping"; // 心跳消息 public static final String PING = "ping"; // 心跳消息
@ -388,6 +393,8 @@ public class DeviceWebSocketServer {
// 示例BusAttendanceMachineService.register(sn); // 示例BusAttendanceMachineService.register(sn);
if (attendanceMachineService != null) { if (attendanceMachineService != null) {
attendanceMachineService.insertBySn(sn); attendanceMachineService.insertBySn(sn);
asyncUtil.repeatSend(sn);
asyncUtil.repeatDelete(sn);
} else { } else {
log.error("IBusAttendanceMachineService 为空,无法进行设备注册"); log.error("IBusAttendanceMachineService 为空,无法进行设备注册");
} }

View File

@ -52,6 +52,9 @@ public class XzdBxBxsqController extends BaseController {
private final IXzdProjectService xzdProjectService; private final IXzdProjectService xzdProjectService;
private final IXzdSupplierOpenBankService xzdSupplierOpenBankService; private final IXzdSupplierOpenBankService xzdSupplierOpenBankService;
private final IXzdBxBxsqBxlxService xzdBxBxsqBxlxService; private final IXzdBxBxsqBxlxService xzdBxBxsqBxlxService;
private final IXzdYhxxService xzdYhxxService;
/** /**
* 查询报销-报销申请列表 * 查询报销-报销申请列表
*/ */
@ -61,8 +64,6 @@ public class XzdBxBxsqController extends BaseController {
return xzdBxBxsqService.queryPageList(bo, pageQuery); return xzdBxBxsqService.queryPageList(bo, pageQuery);
} }
private final IXzdYhxxService xzdYhxxService;
/** /**
* 查询银行数据关联列表 * 查询银行数据关联列表
*/ */

View File

@ -1,5 +1,10 @@
package org.dromara.xzd.bx.bxsq.mapper; 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.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.xzd.bx.bxsq.domain.XzdBxBxsq; import org.dromara.xzd.bx.bxsq.domain.XzdBxBxsq;
import org.dromara.xzd.bx.bxsq.domain.vo.XzdBxBxsqVo; 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> { 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);
}
} }

View File

@ -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.mapper.XzdBxBxsqMapper;
import org.dromara.xzd.bx.bxsq.service.IXzdBxBxsqService; import org.dromara.xzd.bx.bxsq.service.IXzdBxBxsqService;
import org.dromara.xzd.domain.XzdProject; import org.dromara.xzd.domain.XzdProject;
import org.dromara.xzd.domain.XzdSupplierOpenBank;
import org.dromara.xzd.domain.XzdYhxx; 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.XzdProjectServiceImpl;
import org.dromara.xzd.service.impl.XzdSupplierOpenBankServiceImpl; import org.dromara.xzd.service.impl.XzdSupplierOpenBankServiceImpl;
import org.dromara.xzd.service.impl.XzdYhxxServiceImpl; import org.dromara.xzd.service.impl.XzdYhxxServiceImpl;
@ -81,7 +79,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
* @return 报销-报销申请 * @return 报销-报销申请
*/ */
@Override @Override
public XzdBxBxsqVo queryById(Long id){ public XzdBxBxsqVo queryById(Long id) {
XzdBxBxsqVo xzdBxBxsqVo = baseMapper.selectVoById(id); XzdBxBxsqVo xzdBxBxsqVo = baseMapper.selectVoById(id);
List<XzdBxBxsqVo> xzdBxBxsqVo1 = List.of(xzdBxBxsqVo); List<XzdBxBxsqVo> xzdBxBxsqVo1 = List.of(xzdBxBxsqVo);
setValue(xzdBxBxsqVo1); setValue(xzdBxBxsqVo1);
@ -97,6 +95,11 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
*/ */
@Override @Override
public TableDataInfo<XzdBxBxsqVo> queryPageList(XzdBxBxsqBo bo, PageQuery pageQuery) { public TableDataInfo<XzdBxBxsqVo> queryPageList(XzdBxBxsqBo bo, PageQuery pageQuery) {
//暂时定为只能看见自己的报销
if (bo.getBxr() == null && !LoginHelper.isSuperAdmin()) {
bo.setBxr(LoginHelper.getUserId());
}
LambdaQueryWrapper<XzdBxBxsq> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<XzdBxBxsq> lqw = buildQueryWrapper(bo);
Page<XzdBxBxsqVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<XzdBxBxsqVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
setValue(result.getRecords()); setValue(result.getRecords());
@ -164,12 +167,12 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
add.setBm(LoginHelper.getDeptId()); add.setBm(LoginHelper.getDeptId());
//公司 //公司
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(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); SysDeptVo sysDeptVo1 = getCompanyByDeptId(sysDeptVo);
if (sysDeptVo1 != null) { if (sysDeptVo1 != null) {
add.setGs(sysDeptVo1.getDeptId()); 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()); add.setGs(sysDeptVo.getDeptId());
} }
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
@ -177,7 +180,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
bo.setId(add.getId()); bo.setId(add.getId());
} }
if (bo.getFymx() != null && !bo.getFymx().isEmpty()){ if (bo.getFymx() != null && !bo.getFymx().isEmpty()) {
for (XzdBxBxsqFymx fymx : bo.getFymx()) { for (XzdBxBxsqFymx fymx : bo.getFymx()) {
fymx.setBxId(add.getId()); fymx.setBxId(add.getId());
} }
@ -215,16 +218,16 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
XzdBxBxsqVo old = queryById(bo.getId()); XzdBxBxsqVo old = queryById(bo.getId());
//费用明细 //费用明细
if (bo.getFymx() != null && !bo.getFymx().isEmpty()){ if (bo.getFymx() != null && !bo.getFymx().isEmpty()) {
if (old.getFymx() != null && !old.getFymx().isEmpty()){ if (old.getFymx() != null && !old.getFymx().isEmpty()) {
xzdBxBxsqFymxService.removeByIds(old.getFymx()); xzdBxBxsqFymxService.removeByIds(old.getFymx());
} }
for (XzdBxBxsqFymx businessChange : bo.getFymx()) { for (XzdBxBxsqFymx businessChange : bo.getFymx()) {
businessChange.setBxId(update.getId()); businessChange.setBxId(update.getId());
} }
xzdBxBxsqFymxService.saveBatch(bo.getFymx()); xzdBxBxsqFymxService.saveBatch(bo.getFymx());
}else { } else {
if (old.getFymx() != null && !old.getFymx().isEmpty()){ if (old.getFymx() != null && !old.getFymx().isEmpty()) {
xzdBxBxsqFymxService.removeByIds(old.getFymx()); 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 做一些数据校验,如唯一约束 //TODO 做一些数据校验,如唯一约束
} }
@ -284,7 +287,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验 //TODO 做一些业务上的校验,判断是否需要校验
} }
@ -300,7 +303,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
public void setValue(List<XzdBxBxsqVo> vos){ public void setValue(List<XzdBxBxsqVo> vos) {
for (XzdBxBxsqVo vo : vos) { for (XzdBxBxsqVo vo : vos) {
//费用明细 //费用明细
LambdaQueryWrapper<XzdBxBxsqFymx> lqw = new LambdaQueryWrapper<>(); LambdaQueryWrapper<XzdBxBxsqFymx> lqw = new LambdaQueryWrapper<>();
@ -308,7 +311,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
List<XzdBxBxsqFymx> list = xzdBxBxsqFymxService.list(lqw); List<XzdBxBxsqFymx> list = xzdBxBxsqFymxService.list(lqw);
//费用明细处理 //费用明细处理
List<XzdBxBxsqFymxVo> voList = new ArrayList<>(); List<XzdBxBxsqFymxVo> voList = new ArrayList<>();
if (list != null && !list.isEmpty()){ if (list != null && !list.isEmpty()) {
for (XzdBxBxsqFymx fymx : list) { for (XzdBxBxsqFymx fymx : list) {
XzdBxBxsqFymxVo fymxVo = new XzdBxBxsqFymxVo(); XzdBxBxsqFymxVo fymxVo = new XzdBxBxsqFymxVo();
BeanUtils.copyProperties(fymx, fymxVo); 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()); SysDeptVo sysDeptVo = sysDeptService.selectDeptById(fymx.getFycdbm());
if (sysDeptVo != null) { if (sysDeptVo != null) {
fymxVo.setFycdbmmc(sysDeptVo.getDeptName()); fymxVo.setFycdbmmc(sysDeptVo.getDeptName());
@ -338,9 +341,9 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
vo.setFymx(voList); vo.setFymx(voList);
} }
//报销人名称 //报销人名称
if (vo.getBxr() != null){ if (vo.getBxr() != null) {
SysUserVo sysUserVo = sysUserService.selectUserById(vo.getBxr()); SysUserVo sysUserVo = sysUserService.selectUserById(vo.getBxr());
if (sysUserVo != null){ if (sysUserVo != null) {
vo.setBxrmc(sysUserVo.getNickName()); vo.setBxrmc(sysUserVo.getNickName());
} }
} }
@ -376,10 +379,10 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl<XzdBxBxsqMapper, XzdBxBxsq
} }
//通过部门查询出公司 //通过部门查询出公司
private SysDeptVo getCompanyByDeptId(SysDeptVo deptVo){ private SysDeptVo getCompanyByDeptId(SysDeptVo deptVo) {
if (!deptVo.getParentId().equals(100L)){ if (!deptVo.getParentId().equals(100L)) {
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(deptVo.getParentId()); SysDeptVo sysDeptVo = sysDeptService.selectDeptById(deptVo.getParentId());
if (sysDeptVo == null){ if (sysDeptVo == null) {
return null; return null;
} }
getCompanyByDeptId(sysDeptVo); getCompanyByDeptId(sysDeptVo);

View File

@ -215,7 +215,7 @@ public class XzdCsContractInformationVo implements Serializable {
*/ */
@ExcelProperty(value = "签约组织") @ExcelProperty(value = "签约组织")
private Long signOrganization; 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; private String signOrganizationName;
/** /**

View File

@ -1,13 +1,10 @@
package org.dromara.xzd.domain.bo; 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 io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; 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; 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; private String tableName;
/** /**
* 承包合同信息ID * 承包合同信息ID
*/ */
@NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class }) // @NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long contractDetailsId; private Long contractDetailsId;
/** /**

View File

@ -1,13 +1,10 @@
package org.dromara.xzd.domain.bo; 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 io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*; import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.xzd.domain.XzdContractClause;
/** /**
* 合同条款-合同条款业务对象 xzd_contract_clause * 合同条款-合同条款业务对象 xzd_contract_clause
@ -21,20 +18,20 @@ import jakarta.validation.constraints.*;
public class XzdContractClauseBo extends BaseEntity { public class XzdContractClauseBo extends BaseEntity {
/** /**
* *
*/ */
private Long id; private Long id;
/** /**
* 表名 * 表名
*/ */
@NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class }) // @NotBlank(message = "表名不能为空", groups = { AddGroup.class, EditGroup.class })
private String tableName; private String tableName;
/** /**
* 承包合同信息ID * 承包合同信息ID
*/ */
@NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class }) // @NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long contractDetailsId; private Long contractDetailsId;
/** /**

View File

@ -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; private Long invoicingUnit;
/** /**

View File

@ -1,12 +1,8 @@
package org.dromara.xzd.domain.bo; package org.dromara.xzd.domain.bo;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; 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.common.mybatis.core.domain.BaseEntity;
import org.dromara.xzd.domain.XzdDeductionItems; 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; private String tableName;
/** /**
* 承包合同信息ID * 承包合同信息ID
*/ */
@NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class }) // @NotNull(message = "承包合同信息ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long contractDetailsId; private Long contractDetailsId;
/** /**

View File

@ -147,7 +147,7 @@ public class XzdContractDetailsVo implements Serializable {
private BigDecimal contractAmount; private BigDecimal contractAmount;
/** /**
* 开票单位(供应商) * 开票单位(供应商,现改为部门公司)
*/ */
@ExcelProperty(value = "开票单位") @ExcelProperty(value = "开票单位")
private Long invoicingUnit; 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; private String invoicingUnitName;
/** /**

View File

@ -100,7 +100,8 @@ public class XzdContractAgreementServiceImpl extends ServiceImpl<XzdContractAgre
private LambdaQueryWrapper<XzdContractAgreement> buildQueryWrapper(XzdContractAgreementBo bo) { private LambdaQueryWrapper<XzdContractAgreement> buildQueryWrapper(XzdContractAgreementBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<XzdContractAgreement> lqw = Wrappers.lambdaQuery(); 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.eq(StringUtils.isNotBlank(bo.getContractCode()), XzdContractAgreement::getContractCode, bo.getContractCode());
lqw.like(StringUtils.isNotBlank(bo.getContractName()), XzdContractAgreement::getContractName, bo.getContractName()); lqw.like(StringUtils.isNotBlank(bo.getContractName()), XzdContractAgreement::getContractName, bo.getContractName());
lqw.eq(bo.getDocumentDate() != null, XzdContractAgreement::getDocumentDate, bo.getDocumentDate()); lqw.eq(bo.getDocumentDate() != null, XzdContractAgreement::getDocumentDate, bo.getDocumentDate());

View File

@ -185,6 +185,17 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
add.setContractCode(banBen); add.setContractCode(banBen);
add.setHtzt("正常"); 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; boolean flag = baseMapper.insert(add) > 0;
if (!flag) { if (!flag) {
return false; return false;
@ -251,24 +262,6 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
throw new RuntimeException("该合同已被终止!"); 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 (bo.getYskx() != null && !bo.getYskx().isEmpty()){
if (old.getYskx() != null && !old.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 (bo.getKkyjlx() != null && !bo.getKkyjlx().isEmpty()){
if (old.getKkyjlx() != null && !old.getKkyjlx().isEmpty()){ if (old.getKkyjlx() != null && !old.getKkyjlx().isEmpty()){
xzdDeductionItemsService.removeByIds(old.getKkyjlx()); xzdDeductionItemsService.removeByIds(old.getKkyjlx());
@ -305,20 +289,15 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
} }
xzdDeductionItemsService.saveBatch(bo.getKkyjlx()); xzdDeductionItemsService.saveBatch(bo.getKkyjlx());
}else { }else {
if (old.getYskx() != null && !old.getYskx().isEmpty()){ if (old.getKkyjlx() != null && !old.getKkyjlx().isEmpty()){
xzdDeductionItemsService.removeByIds(old.getYskx()); 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 (bo.getHttk() != null && !bo.getHttk().isEmpty()){
if (old.getHttk() != null && !old.getHttk().isEmpty()){ if (old.getHttk() != null && !old.getHttk().isEmpty()){
xzdContractClauseService.removeByIds(old.getHttk()); xzdContractClauseService.removeByIds(old.getHttk());
@ -329,20 +308,12 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
} }
xzdContractClauseService.saveBatch(bo.getHttk()); xzdContractClauseService.saveBatch(bo.getHttk());
}else { }else {
if (old.getYskx() != null && !old.getYskx().isEmpty()){ if (old.getHttk() != null && !old.getHttk().isEmpty()){
xzdContractClauseService.removeByIds(old.getHttk()); 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 (bo.getZftk() != null && !bo.getZftk().isEmpty()){
if (old.getZftk() != null && !old.getZftk().isEmpty()){ if (old.getZftk() != null && !old.getZftk().isEmpty()){
xzdSettlementRulesService.removeByIds(old.getZftk()); xzdSettlementRulesService.removeByIds(old.getZftk());
@ -352,7 +323,7 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
} }
xzdSettlementRulesService.saveBatch(bo.getZftk()); xzdSettlementRulesService.saveBatch(bo.getZftk());
}else { }else {
if (old.getYskx() != null && !old.getYskx().isEmpty()){ if (old.getZftk() != null && !old.getZftk().isEmpty()){
xzdSettlementRulesService.removeByIds(old.getZftk()); xzdSettlementRulesService.removeByIds(old.getZftk());
} }
} }
@ -371,22 +342,22 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
} }
//更新文件 //更新文件
if (bo.getFileId() != null && !bo.getFileId().isEmpty()){ // if (bo.getFileId() != null && !bo.getFileId().isEmpty()){
if (old.getFileId() != null && !old.getFileId().isEmpty()) { // if (old.getFileId() != null && !old.getFileId().isEmpty()) {
List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); // List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList(); // List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList();
for (Long l : oldFileId) { // for (Long l : oldFileId) {
if (!nowFileId.contains(l)) { // if (!nowFileId.contains(l)) {
sysOssService.deleteWithValidByIds(List.of(l), false); // sysOssService.deleteWithValidByIds(List.of(l), false);
} // }
} // }
} // }
}else { // }else {
if (old.getFileId()!= null && !old.getFileId().isEmpty()){ // if (old.getFileId()!= null && !old.getFileId().isEmpty()){
List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); // List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
sysOssService.deleteWithValidByIds(deleteIds, false); // sysOssService.deleteWithValidByIds(deleteIds, false);
} // }
} // }
validEntityBeforeSave(update); validEntityBeforeSave(update);
@ -565,6 +536,11 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl<XzdContractDetail
info.setContractAmount(changeVo.getPostChangeTotalCost()); info.setContractAmount(changeVo.getPostChangeTotalCost());
} }
//获取开票单位(部门公司)
SysDeptVo sysDeptVo = sysDeptService.selectDeptById(info.getInvoicingUnit());
if (sysDeptVo != null){
info.setInvoicingUnitName(sysDeptVo.getDeptName());
}
} }
} }

View File

@ -1,26 +1,27 @@
package org.dromara.xzd.spykp.spdj.controller; 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 cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.validation.annotation.Validated; import jakarta.validation.constraints.NotEmpty;
import org.dromara.common.idempotent.annotation.RepeatSubmit; import jakarta.validation.constraints.NotNull;
import org.dromara.common.log.annotation.Log; import lombok.RequiredArgsConstructor;
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.domain.R;
import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup; import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.xzd.spykp.spdj.domain.vo.XzdSpykpSpdjVo; import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.xzd.spykp.spdj.domain.bo.XzdSpykpSpdjBo; import org.dromara.common.log.annotation.Log;
import org.dromara.xzd.spykp.spdj.service.IXzdSpykpSpdjService; 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.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 @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/spdj/spdj") @RequestMapping("/xzd/spdj/spdj")
public class XzdSpykpSpdjController extends BaseController { public class XzdSpykpSpdjController extends BaseController {
private final IXzdSpykpSpdjService xzdSpykpSpdjService; private final IXzdSpykpSpdjService xzdSpykpSpdjService;

View File

@ -252,5 +252,9 @@ public class XzdSpykpSpdj extends BaseEntity {
*/ */
private Long contractId; private Long contractId;
/**
* 审核状态
*/
private String shzt;
} }

View File

@ -250,5 +250,8 @@ public class XzdSpykpSpdjBo extends BaseEntity {
*/ */
private Long contractId; private Long contractId;
/**
* 审核状态
*/
private String shzt;
} }

View File

@ -4,6 +4,8 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; 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 org.dromara.xzd.spykp.spdj.domain.XzdSpykpSpdj;
import java.io.Serial; 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; private String xfmc;
/** /**
@ -323,4 +326,8 @@ public class XzdSpykpSpdjVo implements Serializable {
*/ */
private String contractName; private String contractName;
/**
* 审核状态
*/
private String shzt;
} }

View File

@ -1,15 +1,18 @@
package org.dromara.xzd.spykp.spdj.service.impl; 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.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; 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.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.SysDeptVo;
import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.impl.SysDeptServiceImpl; 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.system.service.impl.SysUserServiceImpl;
import org.dromara.xzd.domain.XzdContractDetails; import org.dromara.xzd.domain.XzdContractDetails;
import org.dromara.xzd.domain.XzdProject; import org.dromara.xzd.domain.XzdProject;
import org.dromara.xzd.domain.dto.QuerCorrespondentDto;
import org.dromara.xzd.service.IXzdCorrespondentList; import org.dromara.xzd.service.IXzdCorrespondentList;
import org.dromara.xzd.service.impl.XzdContractDetailsServiceImpl; import org.dromara.xzd.service.impl.XzdContractDetailsServiceImpl;
import org.dromara.xzd.service.impl.XzdProjectServiceImpl; import org.dromara.xzd.service.impl.XzdProjectServiceImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.dromara.xzd.spykp.spdj.domain.XzdSpykpSpdj;
import org.springframework.stereotype.Service;
import org.dromara.xzd.spykp.spdj.domain.bo.XzdSpykpSpdjBo; 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.vo.XzdSpykpSpdjVo;
import org.dromara.xzd.spykp.spdj.domain.XzdSpykpSpdj;
import org.dromara.xzd.spykp.spdj.mapper.XzdSpykpSpdjMapper; import org.dromara.xzd.spykp.spdj.mapper.XzdSpykpSpdjMapper;
import org.dromara.xzd.spykp.spdj.service.IXzdSpykpSpdjService; 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.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection;
/** /**
* 收票登记Service业务层处理 * 收票登记Service业务层处理
@ -42,6 +46,7 @@ import java.util.Collection;
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@Slf4j
public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, XzdSpykpSpdj> implements IXzdSpykpSpdjService { public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, XzdSpykpSpdj> implements IXzdSpykpSpdjService {
private final XzdSpykpSpdjMapper baseMapper; private final XzdSpykpSpdjMapper baseMapper;
@ -173,44 +178,44 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, Xzd
XzdSpykpSpdj update = MapstructUtils.convert(bo, XzdSpykpSpdj.class); XzdSpykpSpdj update = MapstructUtils.convert(bo, XzdSpykpSpdj.class);
validEntityBeforeSave(update); validEntityBeforeSave(update);
XzdSpykpSpdj old = baseMapper.selectById(update.getId()); // XzdSpykpSpdj old = baseMapper.selectById(update.getId());
//更新文件 //更新文件
if (bo.getFileId() != null && !bo.getFileId().isEmpty()){ // if (bo.getFileId() != null && !bo.getFileId().isEmpty()){
if (old.getFileId() != null && !old.getFileId().isEmpty()) { // if (old.getFileId() != null && !old.getFileId().isEmpty()) {
List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); // List<Long> oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList(); // List<Long> nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList();
for (Long l : oldFileId) { // for (Long l : oldFileId) {
if (!nowFileId.contains(l)) { // if (!nowFileId.contains(l)) {
sysOssService.deleteWithValidByIds(List.of(l), false); // sysOssService.deleteWithValidByIds(List.of(l), false);
} // }
} // }
} // }
}else { // }else {
if (old.getFileId()!= null && !old.getFileId().isEmpty()){ // if (old.getFileId()!= null && !old.getFileId().isEmpty()){
List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); // List<Long> deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList();
sysOssService.deleteWithValidByIds(deleteIds, false); // sysOssService.deleteWithValidByIds(deleteIds, false);
} // }
} // }
//发票图片 // //发票图片
if (bo.getFptp() != null){ // if (bo.getFptp() != null){
if (!bo.getFptp().equals(old.getFptp())){ // if (!bo.getFptp().equals(old.getFptp())){
sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false); // sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false);
} // }
}else { // }else {
if (old.getFptp()!= null){ // if (old.getFptp()!= null){
sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false); // sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false);
} // }
} // }
//证明信息文件 // //证明信息文件
if (bo.getZmxxwj() != null){ // if (bo.getZmxxwj() != null){
if (!bo.getZmxxwj().equals(old.getZmxxwj())){ // if (!bo.getZmxxwj().equals(old.getZmxxwj())){
sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false); // sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false);
} // }
}else { // }else {
if (old.getZmxxwj()!= null){ // if (old.getZmxxwj()!= null){
sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false); // sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false);
} // }
} // }
return baseMapper.updateById(update) > 0; return baseMapper.updateById(update) > 0;
} }
@ -269,14 +274,14 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl<XzdSpykpSpdjMapper, Xzd
} }
} }
//销方(客户id) //销方(客户id)
if (vo.getXfId() != null){ // if (vo.getXfId() != null){
R<QuerCorrespondentDto> byid2 = iXzdCorrespondentList.getCustomerByid(vo.getXfId()); // R<QuerCorrespondentDto> byid2 = iXzdCorrespondentList.getCustomerByid(vo.getXfId());
if (byid2 != null) { // if (byid2 != null) {
if (byid2.getData().getXzdCustomerinformation() != null) { // if (byid2.getData().getXzdCustomerinformation() != null) {
vo.setXfmc(byid2.getData().getXzdCustomerinformation().getUnitName()); // vo.setXfmc(byid2.getData().getXzdCustomerinformation().getUnitName());
} // }
} // }
} // }
//经办人 //经办人
if (vo.getJbrId() != null){ if (vo.getJbrId() != null){
SysUserVo sysUserVo = sysUserService.selectUserById(vo.getJbrId()); 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());
}
} }

View File

@ -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>

View File

@ -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>

View File

@ -8,8 +8,6 @@
SELECT SELECT
info.id,info.unit_code,info.unit_name,info.unified_social_credit_code, info.id,info.unit_code,info.unit_name,info.unified_social_credit_code,
supplement.belonging_organization as sszz, supplement.belonging_organization as sszz,
# settlement.opening_bank as khyh,
# settlement.account_number as khhzh,
info.city_code as cityCode, info.city_code as cityCode,
info.shzt as shzt, info.shzt as shzt,
yhxx.open_bank as khyh, yhxx.open_bank as khyh,
@ -23,7 +21,6 @@
supplement.responsible_salesman as fgywy, supplement.responsible_salesman as fgywy,
supplement.supplier_status as gyszt, 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, (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, supplement.supplier_level as gysdj,
info.is_group_supplier as isGroupSupplier, info.is_group_supplier as isGroupSupplier,
info.is_blacklist as isBlacklist, info.is_blacklist as isBlacklist,
@ -104,9 +101,6 @@
</where> </where>
ORDER BY info.create_time DESC ORDER BY info.create_time DESC
<!-- <if test='bo.pageNum != null and bo.pageSize != null'>-->
<!-- LIMIT #{bo.pageSize} OFFSET #{bo.offset}-->
<!-- </if>-->
</select> </select>

View File

@ -1953,3 +1953,24 @@ CREATE TABLE `ai_chat_memory`
INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id' INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id'
) comment = 'AI 对话记录信息'; ) 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 '安全员轨迹信息';