[update] 修改app实名,修改施工进度计划和填报逻辑

This commit is contained in:
lcj
2025-08-03 00:55:12 +08:00
parent 9cc4ce105e
commit 0b3652ff70
26 changed files with 541 additions and 310 deletions

View File

@ -9,6 +9,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.concurrent.TimeUnit;
@ -341,4 +342,22 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
return Date.from(combinedInstant);
}
/**
* 校验日期范围
*
* @param startStr 开始日期字符串,格式为 "yyyy-MM-dd"
* @param endStr 结束日期字符串,格式为 "yyyy-MM-dd"
* @return true 表示日期范围有效false 表示日期范围无效
*/
public static boolean isValidDateRange(String startStr, String endStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
LocalDate startDate = LocalDate.parse(startStr, formatter);
LocalDate endDate = LocalDate.parse(endStr, formatter);
return !startDate.isAfter(endDate); // start <= end
} catch (DateTimeParseException e) {
return false; // 格式非法
}
}
}

View File

@ -339,4 +339,16 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
return false;
}
/**
* 判断字符串是否全为数字
*
* @param str 字符串
* @return 是否为数字
*/
public static boolean isAllDigits(String str) {
if (str == null) return false;
String noSpaces = str.replaceAll(" ", "");
return noSpaces.matches("\\d+");
}
}

View File

@ -18,7 +18,7 @@ public class BigDecimalUtil {
*/
public static BigDecimal toPercentage(BigDecimal dividend, BigDecimal divisor) {
if (dividend == null || divisor == null || divisor.compareTo(BigDecimal.ZERO) == 0) {
return new BigDecimal(0);
return BigDecimal.ZERO;
}
return dividend.divide(divisor, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
}

View File

@ -1,7 +1,7 @@
package org.dromara.common.utils.baiduUtil;
import cn.hutool.json.JSONUtil;
import com.google.gson.Gson;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.utils.baiduUtil.entity.AccessTokenResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -40,8 +40,6 @@ public class BaiDuCommon {
private static final String TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token?client_id=%s&client_secret=%s&grant_type=client_credentials";
private static final Gson gson = new Gson();
/**
* 获取百度AccessToken优先从Redis缓存中获取
*/
@ -85,18 +83,18 @@ public class BaiDuCommon {
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response;
try {
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
AccessTokenResponse tokenResponse = JSONUtil.toBean(response.body(), AccessTokenResponse.class);
return tokenResponse.getAccessToken();
} else {
throw new IOException("获取AccessToken失败状态码: " + response.statusCode());
}
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("调用百度API获取AccessToken失败", e);
}
if (response.statusCode() == 200) {
AccessTokenResponse tokenResponse = JSONUtil.toBean(response.body(), AccessTokenResponse.class);
return tokenResponse.getAccessToken();
} else {
throw new ServiceException("获取AccessToken失败状态码: " + response.statusCode());
}
}
}

View File

@ -39,9 +39,9 @@ public class BaiDuFace {
private static final String FACE_COMPARE_URL = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=%s";
/**
* 人脸识别+人脸检测
*
* @param request 人脸请求参数
* @throws RuntimeException 检测失败时抛出异常由Spring统一处理
*/
@ -54,93 +54,99 @@ public class BaiDuFace {
// 2. 构建请求URL
String requestUrl = String.format(FACE_DETECT_URL, URLEncoder.encode(accessToken, StandardCharsets.UTF_8));
// 3. 序列化请求参数
String requestBody;
try {
// 3. 序列化请求参数
String requestBody = objectMapper.writeValueAsString(request);
requestBody = objectMapper.writeValueAsString(request);
} catch (JsonProcessingException e) {
throw new RuntimeException("请求参数序列化失败:" + e.getMessage(), e);
}
// 4. 构建HTTP请求
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
// 4. 构建HTTP请求
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
// 5. 发送请求并获取响应
HttpResponse<String> response = httpClient.send(
// 5. 发送请求并获取响应
HttpResponse<String> response;
try {
response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString()
);
// 6. 解析响应结果
HumanFaceRes faceRep = objectMapper.readValue(response.body(), HumanFaceRes.class);
// 7. 处理API返回错误
if (faceRep.getErrorCode() != 0) {
throw new RuntimeException("错误码说明:" + faceRep.getErrorMsg());
}
// 8. 验证人脸信息(无人脸时抛出异常)
if (faceRep.getResult() == null
|| faceRep.getResult().getFaceList() == null
|| faceRep.getResult().getFaceList().isEmpty()) {
throw new RuntimeException("未检测到有效人脸信息");
}
// 9. 人脸质量校验
HumanFaceRes.FaceList faceInfo = faceRep.getResult().getFaceList().get(0);
// 9.1 人脸置信度校验必须为1.0
if (faceInfo.getFaceProbability() != 1.0) {
throw new RuntimeException("人脸置信度过低,请重新拍摄!");
}
// 9.2 真实人脸校验(排除卡通人脸)
HumanFaceRes.FaceType faceType = faceInfo.getFaceType();
if (faceType == null) {
throw new RuntimeException("无法判断人脸类型");
}
if ("cartoon".equals(faceType.getType())) {
throw new RuntimeException("请传入真实人脸,勿使用卡通图像");
}
// 校验真实人脸置信度需≥0.8
if (faceType.getProbability() < 0.8) {
throw new RuntimeException("人脸识别不清晰,请换个角度拍摄");
}
// 9.3 人脸模糊度校验模糊度≥0.1视为模糊)
HumanFaceRes.Quality quality = faceInfo.getQuality();
if (quality == null) {
throw new RuntimeException("无法获取人脸质量信息");
}
if (quality.getBlur() != 0) {
throw new RuntimeException("人脸过于模糊,请保持镜头稳定");
}
// 9.4 光线校验(光线值<100视为过暗
if (quality.getIllumination() < 100.0) {
throw new RuntimeException("光线太暗,请在光线充足的环境下拍摄");
}
// 9.5 人脸完整性校验1为完整0为不完整
if (quality.getCompleteness() != 1) {
throw new RuntimeException("人脸未完全显示,请确保面部在框内");
}
} catch (JsonProcessingException e) {
throw new RuntimeException("请求参数序列化失败:" + e.getMessage(), e);
} catch (IOException e) {
throw new RuntimeException("IO处理异常" + e.getMessage(), e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断状态
throw new RuntimeException("请求被中断:" + e.getMessage(), e);
}
}
// 6. 解析响应结果
HumanFaceRes faceRep;
try {
faceRep = objectMapper.readValue(response.body(), HumanFaceRes.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("请求参数序列化失败:" + e.getMessage(), e);
}
// 7. 处理API返回错误
if (faceRep.getErrorCode() != 0) {
throw new RuntimeException("错误码说明:" + faceRep.getErrorMsg());
}
// 8. 验证人脸信息(无人脸时抛出异常)
if (faceRep.getResult() == null
|| faceRep.getResult().getFaceList() == null
|| faceRep.getResult().getFaceList().isEmpty()) {
throw new RuntimeException("未检测到有效人脸信息");
}
// 9. 人脸质量校验
HumanFaceRes.FaceList faceInfo = faceRep.getResult().getFaceList().get(0);
// 9.1 人脸置信度校验必须为1.0
if (faceInfo.getFaceProbability() != 1.0) {
throw new RuntimeException("人脸置信度过低,请重新拍摄!");
}
// 9.2 真实人脸校验(排除卡通人脸)
HumanFaceRes.FaceType faceType = faceInfo.getFaceType();
if (faceType == null) {
throw new RuntimeException("无法判断人脸类型");
}
if ("cartoon".equals(faceType.getType())) {
throw new RuntimeException("请传入真实人脸,勿使用卡通图像");
}
// 校验真实人脸置信度需≥0.8
if (faceType.getProbability() < 0.8) {
throw new RuntimeException("人脸识别不清晰,请换个角度拍摄");
}
// 9.3 人脸模糊度校验模糊度≥0.1视为模糊)
HumanFaceRes.Quality quality = faceInfo.getQuality();
if (quality == null) {
throw new RuntimeException("无法获取人脸质量信息");
}
if (quality.getBlur() != 0) {
throw new RuntimeException("人脸过于模糊,请保持镜头稳定");
}
// 9.4 光线校验(光线值<100视为过暗
if (quality.getIllumination() < 100.0) {
throw new RuntimeException("光线太暗,请在光线充足的环境下拍摄");
}
// 9.5 人脸完整性校验1为完整0为不完整
if (quality.getCompleteness() != 1) {
throw new RuntimeException("人脸未完全显示,请确保面部在框内");
}
}
/**
* 人脸对比(计算人脸相似度)
*
* @param requestList 人脸请求参数列表至少包含2个人脸
* @return 人脸相似度得分
* @throws RuntimeException 对比失败时抛出异常
@ -160,46 +166,54 @@ public class BaiDuFace {
// 3. 构建请求URL
String requestUrl = String.format(FACE_COMPARE_URL, URLEncoder.encode(accessToken, StandardCharsets.UTF_8));
// 4. 序列化请求参数
String requestBody;
try {
// 4. 序列化请求参数
String requestBody = objectMapper.writeValueAsString(requestList);
requestBody = objectMapper.writeValueAsString(requestList);
} catch (JsonProcessingException e) {
throw new RuntimeException("请求参数序列化失败:" + e.getMessage(), e);
}
// 5. 构建HTTP请求
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
// 5. 构建HTTP请求
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
// 6. 发送请求并获取响应
HttpResponse<String> response = httpClient.send(
// 6. 发送请求并获取响应
HttpResponse<String> response;
try {
response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString()
);
// 7. 解析响应结果
ComparisonRes comparisonRep = objectMapper.readValue(response.body(), ComparisonRes.class);
// 8. 处理API返回错误
if (comparisonRep.getErrorCode() != 0) {
throw new RuntimeException("人脸对比失败:" + comparisonRep.getErrorMsg()
+ "(错误码:" + comparisonRep.getErrorCode() + "");
}
// 9. 校验对比结果
if (comparisonRep.getResult() == null) {
throw new RuntimeException("人脸对比结果为空");
}
return comparisonRep.getResult().getScore();
} catch (JsonProcessingException e) {
throw new RuntimeException("请求参数序列化失败:" + e.getMessage(), e);
} catch (IOException e) {
throw new RuntimeException("IO处理异常" + e.getMessage(), e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("请求被中断:" + e.getMessage(), e);
}
// 7. 解析响应结果
ComparisonRes comparisonRep;
try {
comparisonRep = objectMapper.readValue(response.body(), ComparisonRes.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("请求参数序列化失败:" + e.getMessage(), e);
}
// 8. 处理API返回错误
if (comparisonRep.getErrorCode() != 0) {
throw new RuntimeException("人脸对比失败:" + comparisonRep.getErrorMsg()
+ "(错误码:" + comparisonRep.getErrorCode() + "");
}
// 9. 校验对比结果
if (comparisonRep.getResult() == null) {
throw new RuntimeException("人脸对比结果为空");
}
return comparisonRep.getResult().getScore();
}
}

View File

@ -1,8 +1,11 @@
package org.dromara.common.utils.baiduUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.utils.baiduUtil.entity.ocr.IDCardInfo;
import org.dromara.common.utils.baiduUtil.entity.ocr.OcrReq;
import org.dromara.common.utils.baiduUtil.entity.ocr.Result;
@ -10,9 +13,7 @@ import org.dromara.common.utils.baiduUtil.entity.ocr.WordsResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.nio.charset.StandardCharsets;
/**
@ -28,8 +29,6 @@ public class BaiDuOCR {
@Autowired
private BaiDuCommon baiDuCommon;
@Autowired
private HttpClient httpClient;
@Autowired
private ObjectMapper objectMapper; //ObjectMapper 是 Java 处理 JSON 的核心工具,项目中使用它进行 JSON 与 Java 对象的相互转换。
@ -50,34 +49,28 @@ public class BaiDuOCR {
if (atStr == null || atStr.trim().isEmpty()) {
throw new RuntimeException("获取访问令牌失败token为空");
}
try {
String param;
if (vr.getImage() != null) {
String imgParam = URLEncoder.encode(vr.getImage(), StandardCharsets.UTF_8);
param = "image=" + imgParam;
} else if (vr.getUrl() != null) {
param = "url=" + vr.getUrl();
} else {
throw new RuntimeException("请传入图片或图片URL");
}
// 构建HTTP请求
String resultStr = HttpUtil.post(baseUrlTemplate, atStr, param);
log.info("百度OCR识别结果{}", resultStr);
Result result = JSON.parseObject(resultStr, Result.class);
if (result == null) {
throw new RuntimeException("未识别到银行卡信息");
}
return result;
} catch (IOException e) {
// IO异常如序列化失败、网络IO错误
throw new RuntimeException("IO处理异常" + e.getMessage(), e);
} catch (Exception e) {
throw new RuntimeException(e);
String param;
if (vr.getImage() != null) {
String imgParam = URLEncoder.encode(vr.getImage(), StandardCharsets.UTF_8);
param = "image=" + imgParam;
} else if (vr.getUrl() != null) {
param = "url=" + vr.getUrl();
} else {
throw new RuntimeException("请传入图片或图片URL");
}
// 构建HTTP请求
String resultStr;
try {
resultStr = HttpUtil.post(baseUrlTemplate, atStr, param);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
log.info("百度OCR识别结果{}", resultStr);
Result result = JSON.parseObject(resultStr, Result.class);
if (result == null) {
throw new RuntimeException("未识别到银行卡信息");
}
return result;
}
@ -94,46 +87,45 @@ public class BaiDuOCR {
if (accessToken == null || accessToken.trim().isEmpty()) {
throw new RuntimeException("获取访问令牌失败token为空");
}
// 准备请求体(序列化失败抛异常)
String requestBody;
try {
// 准备请求体(序列化失败抛异常)
String requestBody = objectMapper.writeValueAsString(request);
if (requestBody == null) {
throw new RuntimeException("请求参数序列化失败");
}
String param = "id_card_side=" + request.getIdCardSide();
if (request.getImage() != null) {
String imgParam = URLEncoder.encode(request.getImage(), StandardCharsets.UTF_8);
param = param + "&image=" + imgParam;
} else if (request.getUrl() != null) {
param = param + "&url=" + request.getUrl();
} else {
throw new RuntimeException("请传入图片或图片URL");
}
// 构建HTTP请求
String result = HttpUtil.post(BASE_URL, accessToken, param);
// 处理响应内容
IDCardInfo idCardInfo = JSON.parseObject(result, IDCardInfo.class);
if (idCardInfo == null) {
throw new RuntimeException("响应结果解析失败");
}
// 检查身份证状态状态异常由validateImageStatus抛异常
validateImageStatus(idCardInfo.getImageStatus());
// 提取识别结果(结果为空抛异常)
WordsResult wordsResult = idCardInfo.getWordsResult();
if (wordsResult == null) {
throw new RuntimeException("未识别到身份证信息");
}
return wordsResult;
} catch (IOException e) {
// IO异常序列化、网络IO等
throw new RuntimeException("IO处理异常" + e.getMessage(), e);
requestBody = objectMapper.writeValueAsString(request);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
if (requestBody == null) {
throw new RuntimeException("请求参数序列化失败");
}
String param = "id_card_side=" + request.getIdCardSide();
if (request.getImage() != null) {
String imgParam = URLEncoder.encode(request.getImage(), StandardCharsets.UTF_8);
param = param + "&image=" + imgParam;
} else if (request.getUrl() != null) {
param = param + "&url=" + request.getUrl();
} else {
throw new RuntimeException("请传入图片或图片URL");
}
// 构建HTTP请求
String result;
try {
result = HttpUtil.post(BASE_URL, accessToken, param);
} catch (Exception e) {
throw new RuntimeException(e);
}
// 处理响应内容
IDCardInfo idCardInfo = JSON.parseObject(result, IDCardInfo.class);
if (idCardInfo == null) {
throw new RuntimeException("响应结果解析失败");
}
// 检查身份证状态状态异常由validateImageStatus抛异常
validateImageStatus(idCardInfo.getImageStatus());
// 提取识别结果(结果为空抛异常)
WordsResult wordsResult = idCardInfo.getWordsResult();
if (wordsResult == null) {
throw new RuntimeException("未识别到身份证信息");
}
return wordsResult;
}
@ -160,7 +152,7 @@ public class BaiDuOCR {
default -> "未知错误:" + imageStatus;
};
throw new RuntimeException(errorMessage);
throw new ServiceException(errorMessage, HttpStatus.BAD_REQUEST);
}

View File

@ -69,11 +69,6 @@ public class SubConstructionUser extends BaseEntity {
*/
private String status;
/**
* 是否代打
*/
private String isPinch;
/**
* 联系电话
*/

View File

@ -1,9 +1,7 @@
package org.dromara.contractor.domain.dto.constructionuser;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import org.dromara.common.core.constant.RegexConstants;
import java.io.Serial;
import java.io.Serializable;
@ -111,22 +109,6 @@ public class SubConstructionUserAuthenticationReq implements Serializable {
*/
private String yhkCardholder;
/**
* 工种
*/
@NotBlank(message = "工种不能为空")
private String typeOfWork;
/**
* 工资计量单位
*/
private String wageMeasureUnit;
/**
* 特种工作证图片
*/
private String specialWorkPic;
/**
* 备注
*/

View File

@ -40,11 +40,6 @@ public class SubConstructionUserCreateReq implements Serializable {
*/
private String status;
/**
* 是否代打
*/
private String isPinch;
/**
* 联系电话
*/

View File

@ -15,11 +15,6 @@ public class SubConstructionUserQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = 3252651952758479341L;
/**
* 主键id
*/
private Long id;
/**
* 人员姓名
*/
@ -55,11 +50,6 @@ public class SubConstructionUserQueryReq implements Serializable {
*/
private String status;
/**
* 是否代打
*/
private String isPinch;
/**
* 0:保密 1:男 2女
*/
@ -75,21 +65,11 @@ public class SubConstructionUserQueryReq implements Serializable {
*/
private String nativePlace;
/**
* 开户行
*/
private String yhkOpeningBank;
/**
* 工种(字典type_of_work)
*/
private String typeOfWork;
/**
* 工资计量单位
*/
private String wageMeasureUnit;
/**
* 打卡(0启用打卡 1禁止打卡)
*/

View File

@ -47,11 +47,6 @@ public class SubConstructionUserUpdateReq implements Serializable {
*/
private String status;
/**
* 是否代打
*/
private String isPinch;
/**
* 联系电话
*/

View File

@ -88,12 +88,6 @@ public class SubConstructionUserVo implements Serializable {
@ExcelDictFormat(readConverterExp = "0=在职,1=离职")
private String status;
/**
* 是否代打
*/
@ExcelProperty(value = "是否代打")
private String isPinch;
/**
* 联系电话
*/

View File

@ -705,7 +705,6 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
return lqw;
}
// 从对象中取值
Long id = req.getId();
String userName = req.getUserName();
Long projectId = req.getProjectId();
Long contractorId = req.getContractorId();
@ -713,13 +712,10 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
Long notTeamId = req.getNotTeamId();
String teamName = req.getTeamName();
String status = req.getStatus();
String isPinch = req.getIsPinch();
String sex = req.getSex();
String nation = req.getNation();
String nativePlace = req.getNativePlace();
String yhkOpeningBank = req.getYhkOpeningBank();
String typeOfWork = req.getTypeOfWork();
String wageMeasureUnit = req.getWageMeasureUnit();
String clock = req.getClock();
String userRole = req.getUserRole();
String notUserRole = req.getNotUserRole();
@ -727,19 +723,15 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
lqw.like(StringUtils.isNotBlank(userName), SubConstructionUser::getUserName, userName);
lqw.like(StringUtils.isNotBlank(nation), SubConstructionUser::getNation, nation);
lqw.like(StringUtils.isNotBlank(nativePlace), SubConstructionUser::getNativePlace, nativePlace);
lqw.like(StringUtils.isNotBlank(yhkOpeningBank), SubConstructionUser::getYhkOpeningBank, yhkOpeningBank);
lqw.like(StringUtils.isNotBlank(teamName), SubConstructionUser::getTeamName, teamName);
// 精确查询
lqw.eq(StringUtils.isNotBlank(status), SubConstructionUser::getStatus, status);
lqw.eq(ObjectUtils.isNotEmpty(id), SubConstructionUser::getId, id);
lqw.eq(ObjectUtils.isNotEmpty(projectId), SubConstructionUser::getProjectId, projectId);
lqw.eq(ObjectUtils.isNotEmpty(contractorId), SubConstructionUser::getContractorId, contractorId);
lqw.eq(ObjectUtils.isNotEmpty(teamId), SubConstructionUser::getTeamId, teamId);
lqw.eq(StringUtils.isNotBlank(isPinch), SubConstructionUser::getIsPinch, isPinch);
lqw.eq(StringUtils.isNotBlank(sex), SubConstructionUser::getSex, sex);
lqw.eq(ObjectUtils.isNotEmpty(typeOfWork), SubConstructionUser::getTypeOfWork, typeOfWork);
lqw.eq(ObjectUtils.isNotEmpty(clock), SubConstructionUser::getClock, clock);
lqw.eq(StringUtils.isNotBlank(wageMeasureUnit), SubConstructionUser::getWageMeasureUnit, wageMeasureUnit);
lqw.eq(StringUtils.isNotBlank(userRole), SubConstructionUser::getUserRole, userRole);
// 精准查询,不等于
if (ObjectUtils.isNotEmpty(notTeamId)) {
@ -1084,27 +1076,28 @@ public class SubConstructionUserServiceImpl extends ServiceImpl<SubConstructionU
*/
@Override
public Long insertByAuthentication(SubConstructionUserAuthenticationReq req) {
/* // 先进行人脸识别
if (file == null) {
throw new ServiceException("请上传图片", HttpStatus.BAD_REQUEST);
// 数据校验
String phone = req.getPhone();
String sfzNumber = req.getSfzNumber();
if (StringUtils.isNotEmpty(phone) && !PhoneUtil.isPhone(phone)) {
throw new ServiceException("手机号码格式不正确", HttpStatus.BAD_REQUEST);
}
String base64;
try {
// 获取文件字节数组
byte[] bytes = file.getBytes();
// Base64 编码
base64 = URLEncoder.encode(Base64.getEncoder().encodeToString(bytes), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new ServiceException("图片转换失败,请重新上传");
if (StringUtils.isNotEmpty(sfzNumber) && !IdcardUtil.isValidCard(sfzNumber)) {
throw new ServiceException("身份证号码格式不正确", HttpStatus.BAD_REQUEST);
}
String sfzStart = req.getSfzStart();
String sfzEnd = req.getSfzEnd();
if (!DateUtils.isValidDateRange(sfzStart, sfzEnd)) {
throw new ServiceException("身份证有效期格式错误", HttpStatus.BAD_REQUEST);
}
if (!StringUtils.isAllDigits(req.getYhkNumber())) {
throw new ServiceException("银行卡号格式错误", HttpStatus.BAD_REQUEST);
}
HumanFaceReq request = new HumanFaceReq();
request.setImage(base64);
baiDuFace.humanFace(request);*/
// 人脸识别成功,保存人脸数据
SubConstructionUser user = new SubConstructionUser();
BeanUtils.copyProperties(req, user);
// 对身份证号码进行加密
String encrypt = idCardEncryptorUtil.encrypt(req.getSfzNumber());
String encrypt = idCardEncryptorUtil.encrypt(sfzNumber);
user.setSfzNumber(encrypt);
// 关联系统用户
Long userId = LoginHelper.getUserId();

View File

@ -105,4 +105,10 @@ public class FacPhotovoltaicPanelPointController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(facPhotovoltaicPanelPointService.deleteWithValidByIds(List.of(ids), true));
}
@GetMapping("/test")
public R<Void> test() {
facPhotovoltaicPanelPointService.test();
return toAjax(true);
}
}

View File

@ -1,8 +1,12 @@
package org.dromara.facility.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.facility.domain.FacPhotovoltaicPanelPoint;
import org.dromara.facility.domain.vo.photovoltaicpanelpoint.FacPhotovoltaicPanelPointVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.Map;
/**
* 设施-光伏板桩点Mapper接口
@ -12,4 +16,23 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
*/
public interface FacPhotovoltaicPanelPointMapper extends BaseMapperPlus<FacPhotovoltaicPanelPoint, FacPhotovoltaicPanelPointVo> {
/**
* 按 code 的前三段(即取到第 3 个 "." 之前)做前缀分组,
* 并分页返回每组的 prefix前缀和 cnt该组记录数
* <p>
* 例如:
* G11101.06.22.05 → G11101.06.22
* G11008.02.05#2.01 → G11008.02.05#2
*/
default <P extends IPage<Map<String, Object>>> P selectNameGroups(P page, Long progressCategoryId) {
return this.selectMapsPage(page,
new QueryWrapper<FacPhotovoltaicPanelPoint>()
.select("SUBSTRING_INDEX(name, '.', 3) AS prefix",
"COUNT(*) AS cnt")
.in("status", "0", "1")
.eq("progress_category_id", progressCategoryId)
.groupBy("prefix")
);
}
}

View File

@ -96,4 +96,5 @@ public interface IFacPhotovoltaicPanelPointService extends IService<FacPhotovolt
*/
Page<FacPhotovoltaicPanelPointVo> getVoPage(Page<FacPhotovoltaicPanelPoint> photovoltaicPanelPointPage);
void test();
}

View File

@ -13,6 +13,7 @@ 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.satoken.utils.LoginHelper;
import org.dromara.common.utils.JSTUtil;
import org.dromara.facility.domain.FacBoxTransformer;
import org.dromara.facility.domain.FacMatrix;
import org.dromara.facility.domain.dto.boxtransformer.FacBoxTransformerCreateByGeoJsonReq;
@ -30,7 +31,6 @@ import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.common.utils.JSTUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -240,11 +240,16 @@ public class FacBoxTransformerServiceImpl extends ServiceImpl<FacBoxTransformerM
.stream().collect(Collectors.groupingBy(FacBoxTransformer::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
BigDecimal unitPrice = progressCategory.getUnitPrice();
int total = 0;
if (countMap.containsKey(progressCategoryId)) {
total = countMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
// 如果单价不为 0 则计算产值
if (unitPrice.compareTo(BigDecimal.ZERO) != 0) {
progressCategory.setOutputValue(unitPrice.multiply(BigDecimal.valueOf(total)));
}
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {

View File

@ -13,6 +13,7 @@ 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.satoken.utils.LoginHelper;
import org.dromara.common.utils.JSTUtil;
import org.dromara.facility.domain.FacInverter;
import org.dromara.facility.domain.FacMatrix;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
@ -30,7 +31,6 @@ import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.common.utils.JSTUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -240,11 +240,16 @@ public class FacInverterServiceImpl extends ServiceImpl<FacInverterMapper, FacIn
.stream().collect(Collectors.groupingBy(FacInverter::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
BigDecimal unitPrice = progressCategory.getUnitPrice();
int total = 0;
if (countMap.containsKey(progressCategoryId)) {
total = countMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
// 如果单价不为 0 则计算产值
if (unitPrice.compareTo(BigDecimal.ZERO) != 0) {
progressCategory.setOutputValue(unitPrice.multiply(BigDecimal.valueOf(total)));
}
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {

View File

@ -12,6 +12,7 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.utils.JSTUtil;
import org.dromara.facility.constant.FacPhotovoltaicPanelPartsConstant;
import org.dromara.facility.constant.FacRedisKeyConstant;
import org.dromara.facility.domain.FacPhotovoltaicPanel;
@ -28,7 +29,6 @@ import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.common.utils.JSTUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.DataAccessException;
@ -37,6 +37,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
@ -389,6 +390,34 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
CompletableFuture.allOf(insertFutures.toArray(new CompletableFuture[0])).join();
// 关闭线程池
customExecutor.shutdown();
// 更新数量
Map<Long, List<FacPhotovoltaicPanelPoint>> pointCountMap = pointList
.stream().collect(Collectors.groupingBy(FacPhotovoltaicPanelPoint::getProgressCategoryId));
Map<Long, List<FacPhotovoltaicPanelColumn>> columnCountMap = columnList
.stream().collect(Collectors.groupingBy(FacPhotovoltaicPanelColumn::getProgressCategoryId));
Map<Long, List<FacPhotovoltaicPanelSupport>> supportCountMap = supportList
.stream().collect(Collectors.groupingBy(FacPhotovoltaicPanelSupport::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
BigDecimal unitPrice = progressCategory.getUnitPrice();
int total = 0;
if (pointCountMap.containsKey(progressCategoryId)) {
total = pointCountMap.get(progressCategoryId).size();
} else if (columnCountMap.containsKey(progressCategoryId)) {
total = columnCountMap.get(progressCategoryId).size();
} else if (supportCountMap.containsKey(progressCategoryId)) {
total = supportCountMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
// 如果单价不为 0 则计算产值
if (unitPrice.compareTo(BigDecimal.ZERO) != 0) {
progressCategory.setOutputValue(unitPrice.multiply(BigDecimal.valueOf(total)));
}
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {
throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR);
}
}
/**

View File

@ -3,6 +3,7 @@ package org.dromara.facility.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
@ -28,6 +29,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 设施-光伏板桩点Service业务层处理
@ -277,4 +279,11 @@ public class FacPhotovoltaicPanelPointServiceImpl extends ServiceImpl<FacPhotovo
return photovoltaicPanelPointVoPage;
}
@Override
public void test() {
Page<Map<String, Object>> page = new Page<>(1, 20);
IPage<Map<String, Object>> result = baseMapper.selectNameGroups(page, 1951552040378360699L);
System.out.println(result);
}
}

View File

@ -367,11 +367,16 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
.stream().collect(Collectors.groupingBy(FacPhotovoltaicPanel::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
BigDecimal unitPrice = progressCategory.getUnitPrice();
int total = 0;
if (countMap.containsKey(progressCategoryId)) {
total = countMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
// 如果单价不为 0 则计算产值
if (unitPrice.compareTo(BigDecimal.ZERO) != 0) {
progressCategory.setOutputValue(unitPrice.multiply(BigDecimal.valueOf(total)));
}
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {

View File

@ -37,9 +37,6 @@ public interface PgsProgressCategoryConstant {
* 光伏板进度类别名称
*/
List<String> PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE = List.of(
"12",
"13",
"14",
"15",
"16",
"17"

View File

@ -95,6 +95,14 @@ public interface IPgsProgressPlanService extends IService<PgsProgressPlan> {
*/
void validPlanNumber(BigDecimal planNumber, PgsProgressCategory progressCategory);
/**
* 获取当前计划数量和完成数量
*
* @param progressCategory 进度类别
* @return 当前计划数量和完成数量
*/
BigDecimal getCurrentPlanAndFinishedNumber(PgsProgressCategory progressCategory);
/**
* 校验计划是否延迟
*

View File

@ -115,7 +115,7 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
public List<PgsProgressCategoryVo> queryList(PgsProgressCategoryQueryReq req) {
Long matrixId = req.getMatrixId();
if (matrixService.getById(matrixId) == null) {
throw new ServiceException("方阵不存在", HttpStatus.BAD_REQUEST);
return List.of();
}
List<PgsProgressCategory> list = this.lambdaQuery()
.eq(PgsProgressCategory::getMatrixId, matrixId)
@ -135,10 +135,12 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
if (progressCategory == null) {
throw new ServiceException("进度类别信息不存在", HttpStatus.NOT_FOUND);
}
// 获取当前进度数量和完成数量总和
BigDecimal allNumber = progressPlanService.getCurrentPlanAndFinishedNumber(progressCategory);
PgsProgressCategoryLastTimeVo lastTimeVo = new PgsProgressCategoryLastTimeVo();
BigDecimal total = progressCategory.getTotal();
BigDecimal completed = progressCategory.getCompleted();
BigDecimal planTotal = total.subtract(completed);
// 剩余数量
BigDecimal planTotal = total.subtract(allNumber);
lastTimeVo.setLeftNum(planTotal);
PgsProgressPlan progressPlan = progressPlanService.lambdaQuery()
.eq(PgsProgressPlan::getProgressCategoryId, id)
@ -175,7 +177,11 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
progressCategory.setTotal(req.getTotal());
outputValue = req.getTotal().multiply(unitPrice);
} else if (progressCategory.getUnitType().equals(PgsProgressUnitTypeEnum.NUMBER.getValue())) {
outputValue = progressCategory.getTotal().multiply(unitPrice);
BigDecimal total = progressCategory.getTotal();
if (total.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException("请导入分项工程数量后再添加单价", HttpStatus.BAD_REQUEST);
}
outputValue = total.multiply(unitPrice);
}
// 填入数据
progressCategory.setUnit(req.getUnit());
@ -448,7 +454,6 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
newCategory.setIsDelay(oldPercentageCategory.getIsDelay());
newCategory.setStatus(oldPercentageCategory.getStatus());
}
newCategory.setTotal(BigDecimal.valueOf(100));
FacPercentageFacility percentageFacility = new FacPercentageFacility();
percentageFacility.setProjectId(projectId);
percentageFacility.setMatrixId(matrix.getId());
@ -761,9 +766,9 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
@Override
public List<PgsProgressCategory> queryListByProjectIds(List<Long> projectIds) {
List<BusProject> projects = projectService.lambdaQuery().in(BusProject::getPId, projectIds).list();
List<BusProject> projects = projectService.lambdaQuery().in(BusProject::getPId, projectIds).list();
List<Long> list = projects.stream().map(BusProject::getId).toList();
if(CollUtil.isEmpty(list)){
if (CollUtil.isEmpty(list)) {
return new ArrayList<>();
}
return this.lambdaQuery()

View File

@ -16,15 +16,10 @@ import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.utils.PageConvertUtil;
import org.dromara.facility.domain.FacBoxTransformer;
import org.dromara.facility.domain.FacInverter;
import org.dromara.facility.domain.FacPhotovoltaicPanel;
import org.dromara.facility.domain.*;
import org.dromara.facility.domain.enums.FacFinishStatusEnum;
import org.dromara.facility.domain.enums.FacFinishTypeEnum;
import org.dromara.facility.service.IFacBoxTransformerService;
import org.dromara.facility.service.IFacInverterService;
import org.dromara.facility.service.IFacPhotovoltaicPanelPartsService;
import org.dromara.facility.service.IFacPhotovoltaicPanelService;
import org.dromara.facility.service.*;
import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.PgsProgressPlan;
@ -42,7 +37,6 @@ import org.dromara.progress.mapper.PgsProgressPlanDetailMapper;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.progress.service.IPgsProgressPlanDetailService;
import org.dromara.progress.service.IPgsProgressPlanService;
import org.dromara.common.utils.PageConvertUtil;
import org.dromara.project.domain.BusProject;
import org.dromara.project.service.IBusProjectService;
import org.springframework.beans.BeanUtils;
@ -82,10 +76,16 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
private IPgsProgressCategoryService progressCategoryService;
@Resource
private IFacPhotovoltaicPanelPartsService photovoltaicPanelPartsService;
private IBusProjectService projectService;
@Resource
private IBusProjectService projectService;
private IFacPhotovoltaicPanelPointService photovoltaicPanelPointService;
@Resource
private IFacPhotovoltaicPanelSupportService photovoltaicPanelSupportService;
@Resource
private IFacPhotovoltaicPanelColumnService photovoltaicPanelColumnService;
/**
* 分页查询进度计划详情列表
@ -157,20 +157,6 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
FacPhotovoltaicPanel::getStatus
);
finishedDetailList.addAll(finishedVoList);
// 如果是桩点、支柱、立架,则同步更新
if (PgsProgressCategoryConstant.RELEVANCE_PHOTOVOLTAIC_PANEL_WORK_TYPE.contains(workType)) {
Long matrixId = progressCategory.getMatrixId();
List<String> nameList = finishedDetailList.stream().map(PgsProgressPlanDetailFinishedVo::getName).toList();
Boolean result = photovoltaicPanelPartsService.updatePartsFinishStatus(
workType,
planDate,
projectId,
matrixId,
nameList);
if (!result) {
throw new ServiceException("同步更新设施失败", HttpStatus.ERROR);
}
}
} else if (PgsProgressCategoryConstant.INVERTER_PROGRESS_CATEGORY_WORK_TYPE.contains(workType)) {
List<PgsProgressPlanDetailFinishedVo> finishedVoList = handleFacilityFinish(
projectId,
@ -205,6 +191,59 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
FacBoxTransformer::getStatus
);
finishedDetailList.addAll(finishedVoList);
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_POINT_WORK_TYPE.contains(workType)) {
List<PgsProgressPlanDetailFinishedVo> finishedVoList = handleFacilityFinish(
projectId,
progressCategoryId,
finishedDetailIdList,
planDate,
photovoltaicPanelPointService,
FacPhotovoltaicPanelPoint::getId,
FacPhotovoltaicPanelPoint::getName,
FacPhotovoltaicPanelPoint::getFinishType,
FacPhotovoltaicPanelPoint::getFinishDate,
FacPhotovoltaicPanelPoint::getProjectId,
FacPhotovoltaicPanelPoint::getProgressCategoryId,
FacPhotovoltaicPanelPoint::getId,
FacPhotovoltaicPanelPoint::getStatus
);
finishedDetailList.addAll(finishedVoList);
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_COLUMN_WORK_TYPE.contains(workType)) {
List<PgsProgressPlanDetailFinishedVo> finishedVoList = handleFacilityFinish(
projectId,
progressCategoryId,
finishedDetailIdList,
planDate,
photovoltaicPanelColumnService,
FacPhotovoltaicPanelColumn::getId,
FacPhotovoltaicPanelColumn::getName,
FacPhotovoltaicPanelColumn::getFinishType,
FacPhotovoltaicPanelColumn::getFinishDate,
FacPhotovoltaicPanelColumn::getProjectId,
FacPhotovoltaicPanelColumn::getProgressCategoryId,
FacPhotovoltaicPanelColumn::getId,
FacPhotovoltaicPanelColumn::getStatus
);
finishedDetailList.addAll(finishedVoList);
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_SUPPORT_WORK_TYPE.contains(workType)) {
List<PgsProgressPlanDetailFinishedVo> finishedVoList = handleFacilityFinish(
projectId,
progressCategoryId,
finishedDetailIdList,
planDate,
photovoltaicPanelSupportService,
FacPhotovoltaicPanelSupport::getId,
FacPhotovoltaicPanelSupport::getName,
FacPhotovoltaicPanelSupport::getFinishType,
FacPhotovoltaicPanelSupport::getFinishDate,
FacPhotovoltaicPanelSupport::getProjectId,
FacPhotovoltaicPanelSupport::getProgressCategoryId,
FacPhotovoltaicPanelSupport::getId,
FacPhotovoltaicPanelSupport::getStatus
);
finishedDetailList.addAll(finishedVoList);
} else {
throw new ServiceException("未定义的进度计划类别", HttpStatus.BAD_REQUEST);
}
PgsProgressPlanDetail detail = new PgsProgressPlanDetail();
detail.setId(id);
@ -272,10 +311,6 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
}
BigDecimal number = progressPlanDetail.getFinishedNumber();
BigDecimal finishedNumberTotal = progressPlan.getFinishedNumber();
// todo 是否判断完成百分比是否大于计划进度
/* if (finishedNumberTotal + finishedNumber > progressPlan.getPlanNumber()) {
throw new ServiceException("完成百分比不能大于计划进度", HttpStatus.BAD_REQUEST);
}*/
progressPlanDetail.setFinishedNumber(finishedNumber);
// 更新
boolean update = this.updateById(progressPlanDetail);
@ -382,6 +417,51 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
return vo;
});
return TableDataInfo.build(voPage);
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_POINT_WORK_TYPE.contains(workType)) {
LambdaQueryWrapper<FacPhotovoltaicPanelPoint> lqw = new LambdaQueryWrapper<>();
lqw.select(FacPhotovoltaicPanelPoint::getId, FacPhotovoltaicPanelPoint::getName, FacPhotovoltaicPanelPoint::getStatus);
lqw.eq(FacPhotovoltaicPanelPoint::getProjectId, progressPlanDetail.getProjectId());
lqw.eq(FacPhotovoltaicPanelPoint::getProgressCategoryId, progressCategoryId);
lqw.in(FacPhotovoltaicPanelPoint::getStatus, FacFinishStatusEnum.UNFINISH.getValue(), FacFinishStatusEnum.INPROGRESS.getValue());
Page<FacPhotovoltaicPanelPoint> page = photovoltaicPanelPointService.page(pageQuery.build(), lqw);
Page<PgsProgressPlanDetailUnFinishVo> voPage = PageConvertUtil.convert(page, entity -> {
PgsProgressPlanDetailUnFinishVo vo = new PgsProgressPlanDetailUnFinishVo();
vo.setId(entity.getId());
vo.setName(entity.getName());
vo.setStatus(entity.getStatus());
return vo;
});
return TableDataInfo.build(voPage);
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_COLUMN_WORK_TYPE.contains(workType)) {
LambdaQueryWrapper<FacPhotovoltaicPanelColumn> lqw = new LambdaQueryWrapper<>();
lqw.select(FacPhotovoltaicPanelColumn::getId, FacPhotovoltaicPanelColumn::getName, FacPhotovoltaicPanelColumn::getStatus);
lqw.eq(FacPhotovoltaicPanelColumn::getProjectId, progressPlanDetail.getProjectId());
lqw.eq(FacPhotovoltaicPanelColumn::getProgressCategoryId, progressCategoryId);
lqw.in(FacPhotovoltaicPanelColumn::getStatus, FacFinishStatusEnum.UNFINISH.getValue(), FacFinishStatusEnum.INPROGRESS.getValue());
Page<FacPhotovoltaicPanelColumn> page = photovoltaicPanelColumnService.page(pageQuery.build(), lqw);
Page<PgsProgressPlanDetailUnFinishVo> voPage = PageConvertUtil.convert(page, entity -> {
PgsProgressPlanDetailUnFinishVo vo = new PgsProgressPlanDetailUnFinishVo();
vo.setId(entity.getId());
vo.setName(entity.getName());
vo.setStatus(entity.getStatus());
return vo;
});
return TableDataInfo.build(voPage);
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_SUPPORT_WORK_TYPE.contains(workType)) {
LambdaQueryWrapper<FacPhotovoltaicPanelSupport> lqw = new LambdaQueryWrapper<>();
lqw.select(FacPhotovoltaicPanelSupport::getId, FacPhotovoltaicPanelSupport::getName, FacPhotovoltaicPanelSupport::getStatus);
lqw.eq(FacPhotovoltaicPanelSupport::getProjectId, progressPlanDetail.getProjectId());
lqw.eq(FacPhotovoltaicPanelSupport::getProgressCategoryId, progressCategoryId);
lqw.in(FacPhotovoltaicPanelSupport::getStatus, FacFinishStatusEnum.UNFINISH.getValue(), FacFinishStatusEnum.INPROGRESS.getValue());
Page<FacPhotovoltaicPanelSupport> page = photovoltaicPanelSupportService.page(pageQuery.build(), lqw);
Page<PgsProgressPlanDetailUnFinishVo> voPage = PageConvertUtil.convert(page, entity -> {
PgsProgressPlanDetailUnFinishVo vo = new PgsProgressPlanDetailUnFinishVo();
vo.setId(entity.getId());
vo.setName(entity.getName());
vo.setStatus(entity.getStatus());
return vo;
});
return TableDataInfo.build(voPage);
} else {
throw new ServiceException("未定义的进度计划类别", HttpStatus.BAD_REQUEST);
}
@ -473,6 +553,54 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
if (!update) {
throw new ServiceException("修改设施数据失败,数据库异常", HttpStatus.ERROR);
}
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_POINT_WORK_TYPE.contains(workType)) {
List<FacPhotovoltaicPanelPoint> list = photovoltaicPanelPointService.lambdaQuery()
.in(FacPhotovoltaicPanelPoint::getId, detailIdList)
.list();
if (CollUtil.isEmpty(list) || list.size() != removeTotal) {
throw new ServiceException("设施数据丢失", HttpStatus.NOT_FOUND);
}
LambdaUpdateWrapper<FacPhotovoltaicPanelPoint> lqw = new LambdaUpdateWrapper<>();
lqw.in(FacPhotovoltaicPanelPoint::getId, detailIdList);
lqw.set(FacPhotovoltaicPanelPoint::getStatus, FacFinishStatusEnum.UNFINISH.getValue());
lqw.set(FacPhotovoltaicPanelPoint::getFinishType, null);
lqw.set(FacPhotovoltaicPanelPoint::getFinishDate, null);
boolean update = photovoltaicPanelPointService.update(lqw);
if (!update) {
throw new ServiceException("修改设施数据失败,数据库异常", HttpStatus.ERROR);
}
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_COLUMN_WORK_TYPE.contains(workType)) {
List<FacPhotovoltaicPanelColumn> list = photovoltaicPanelColumnService.lambdaQuery()
.in(FacPhotovoltaicPanelColumn::getId, detailIdList)
.list();
if (CollUtil.isEmpty(list) || list.size() != removeTotal) {
throw new ServiceException("设施数据丢失", HttpStatus.NOT_FOUND);
}
LambdaUpdateWrapper<FacPhotovoltaicPanelColumn> lqw = new LambdaUpdateWrapper<>();
lqw.in(FacPhotovoltaicPanelColumn::getId, detailIdList);
lqw.set(FacPhotovoltaicPanelColumn::getStatus, FacFinishStatusEnum.UNFINISH.getValue());
lqw.set(FacPhotovoltaicPanelColumn::getFinishType, null);
lqw.set(FacPhotovoltaicPanelColumn::getFinishDate, null);
boolean update = photovoltaicPanelColumnService.update(lqw);
if (!update) {
throw new ServiceException("修改设施数据失败,数据库异常", HttpStatus.ERROR);
}
} else if (PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_SUPPORT_WORK_TYPE.contains(workType)) {
List<FacPhotovoltaicPanelSupport> list = photovoltaicPanelSupportService.lambdaQuery()
.in(FacPhotovoltaicPanelSupport::getId, detailIdList)
.list();
if (CollUtil.isEmpty(list) || list.size() != removeTotal) {
throw new ServiceException("设施数据丢失", HttpStatus.NOT_FOUND);
}
LambdaUpdateWrapper<FacPhotovoltaicPanelSupport> lqw = new LambdaUpdateWrapper<>();
lqw.in(FacPhotovoltaicPanelSupport::getId, detailIdList);
lqw.set(FacPhotovoltaicPanelSupport::getStatus, FacFinishStatusEnum.UNFINISH.getValue());
lqw.set(FacPhotovoltaicPanelSupport::getFinishType, null);
lqw.set(FacPhotovoltaicPanelSupport::getFinishDate, null);
boolean update = photovoltaicPanelSupportService.update(lqw);
if (!update) {
throw new ServiceException("修改设施数据失败,数据库异常", HttpStatus.ERROR);
}
} else {
throw new ServiceException("未定义的进度计划类别", HttpStatus.BAD_REQUEST);
}
@ -577,7 +705,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
@Override
public List<PgsProgressPlanDetail> queryListByProjectIds(List<Long> projectIds) {
List<BusProject> list = projectService.lambdaQuery().in(BusProject::getPId, projectIds).list();
if(CollUtil.isEmpty(list)){
if (CollUtil.isEmpty(list)) {
return List.of();
}
return this.lambdaQuery()

View File

@ -303,12 +303,11 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
// 获取详情列表
Long id = progressPlan.getId();
List<PgsProgressPlanDetailNumVo> numDetailList = new ArrayList<>();
BigDecimal aiFill = new BigDecimal(0);
BigDecimal aiFill = BigDecimal.ZERO;
if (detailMap.containsKey(id)) {
numDetailList = progressPlanDetailService.getNumVoList(detailMap.get(id));
for (PgsProgressPlanDetailNumVo vo : numDetailList) {
BigDecimal fill = vo.getAiFill() != null ? vo.getAiFill() : BigDecimal.ZERO;
aiFill = aiFill.add(fill);
for (PgsProgressPlanDetailNumVo detailNumVo : numDetailList) {
aiFill = aiFill.add(detailNumVo.getAiFill());
}
}
progressPlanVo.setDetailList(numDetailList);
@ -330,12 +329,54 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
if (progressCategory == null) {
throw new ServiceException("进度类别不存在", HttpStatus.NOT_FOUND);
}
if (planNumber.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException("计划数量不能小于等于0", HttpStatus.BAD_REQUEST);
}
BigDecimal total = progressCategory.getTotal();
BigDecimal completed = progressCategory.getCompleted();
BigDecimal planTotal = total.subtract(completed);
if (planNumber.compareTo(planTotal) > 0) {
throw new ServiceException("计划数量不能大于剩余数量", HttpStatus.BAD_REQUEST);
}
// 如果计划数量大于未完成和计划的数量,则计划数量不合法
BigDecimal planAndFinishedNumberNumber = this.getCurrentPlanAndFinishedNumber(progressCategory);
BigDecimal leftNumber = progressCategory.getTotal().subtract(planAndFinishedNumberNumber);
if (planNumber.compareTo(leftNumber) > 0) {
throw new ServiceException("计划数量不能大于当前完成数量和计划数量总和", HttpStatus.BAD_REQUEST);
}
}
/**
* 获取当前计划数量和完成数量
*
* @param progressCategory 进度类别
* @return 当前计划数量和完成数量
*/
@Override
public BigDecimal getCurrentPlanAndFinishedNumber(PgsProgressCategory progressCategory) {
List<PgsProgressPlan> planList = this.lambdaQuery()
.eq(PgsProgressPlan::getProgressCategoryId, progressCategory.getId())
.list();
// 获取当前时间
Date current = new Date();
// 记录当前完成的和计划的总和
BigDecimal planFinishSum = BigDecimal.ZERO;
for (PgsProgressPlan plan : planList) {
Date endDate = plan.getEndDate();
BigDecimal finishedNumber = plan.getFinishedNumber();
if (endDate.before(current)) {
// 计划结束时间在当前时间之前的,统计 -> 完成数量
planFinishSum = planFinishSum.add(finishedNumber);
} else {
// 计划结束时间在当前时间之后的,统计 -> 计划数量 vs 完成数量
BigDecimal planPlanNumber = plan.getPlanNumber();
// 取较大值
BigDecimal max = finishedNumber.max(planPlanNumber);
// 加入总和
planFinishSum = planFinishSum.add(max);
}
}
return planFinishSum;
}
/**