进度计划同步、大屏摄像头

This commit is contained in:
lcj
2025-09-29 17:06:44 +08:00
parent b0493e7de9
commit a1ba33c06d
5 changed files with 281 additions and 90 deletions

View File

@ -34,9 +34,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -91,7 +89,7 @@ public class DemoTest {
@Test
void testConstructionValue() {
LocalDate today = LocalDate.now();
/* LocalDate today = LocalDate.now();
// 找到本周一
LocalDate thisMonday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
// 上周一 = 本周一 - 1 周
@ -99,7 +97,18 @@ public class DemoTest {
// 上周日 = 上周一 + 6 天
LocalDate lastSunday = lastMonday.plusDays(6);
log.info("执行定时任务:同步 {}至{} 计划详情到施工产值", lastMonday, lastSunday);
Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(lastMonday, lastSunday, null);
Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(lastMonday, lastSunday, null);*/
LocalDate today = LocalDate.of(2025, 9, 16);
LocalDate localDate = today.minusDays(1);
/* // 找到本周一
LocalDate thisMonday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
// 上周一 = 本周一 - 1 周
LocalDate lastMonday = thisMonday.minusWeeks(1);
// 上周日 = 上周一 + 6 天
LocalDate lastSunday = lastMonday.plusDays(6);*/
log.info("执行定时任务:同步 {}至{} 计划详情到施工产值", localDate, localDate);
Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(localDate, localDate, null);
}
@Test

View File

@ -5,15 +5,19 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.bigscreen.domain.dto.Ys7DeviceUpdateReq;
import org.dromara.bigscreen.domain.vo.ProjectImageProgressVo;
import org.dromara.bigscreen.domain.vo.ProjectLandVo;
import org.dromara.bigscreen.domain.vo.ProjectPeopleVo;
import org.dromara.bigscreen.domain.vo.ProjectSafetyInspectionVo;
import org.dromara.bigscreen.service.ProjectBigScreenService;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
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.web.core.BaseController;
import org.dromara.gps.domain.bo.GpsEquipmentBo;
import org.dromara.gps.domain.vo.GpsEquipmentSonVo;
import org.dromara.gps.service.IGpsEquipmentService;
@ -22,6 +26,7 @@ import org.dromara.land.domain.BusLandTransferLedger;
import org.dromara.land.service.IBusLandBlockService;
import org.dromara.land.service.IBusLandTransferLedgerService;
import org.dromara.manager.weathermanager.vo.WeatherVo;
import org.dromara.manager.ys7manager.Ys7Manager;
import org.dromara.other.domain.OthYs7Device;
import org.dromara.other.service.IOthYs7DeviceService;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
@ -34,6 +39,7 @@ import org.dromara.quality.service.IQltQualityInspectionService;
import org.dromara.safety.domain.dto.safetyinspection.HseSafetyInspectionGisReq;
import org.dromara.safety.domain.vo.safetyinspection.HseSafetyInspectionListGisVo;
import org.dromara.safety.service.IHseSafetyInspectionService;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -54,7 +60,7 @@ import java.util.stream.Collectors;
@RestController
@RequiredArgsConstructor
@RequestMapping("/project/big/screen")
public class ProjectBigScreenController {
public class ProjectBigScreenController extends BaseController {
@Resource
private ProjectBigScreenService projectBigScreenService;
@ -75,6 +81,8 @@ public class ProjectBigScreenController {
private final IHseSafetyInspectionService safetyInspectionService;
private final Ys7Manager ys7Manager;
/**
* 查询项目土地统计
*/
@ -316,6 +324,7 @@ public class ProjectBigScreenController {
sxt.put("lat", item.getLatitude());
sxt.put("lng", item.getLongitude());
sxt.put("alt", item.getAltitude());
sxt.put("detail", item.getDetail());
sxtChildrenMap.add(sxt);
}
}
@ -341,6 +350,41 @@ public class ProjectBigScreenController {
return R.ok(maps);
}
/**
* 修改萤石摄像头
*/
@RepeatSubmit()
@PutMapping("/device")
public R<Void> edit(@Validated @RequestBody Ys7DeviceUpdateReq req) {
OthYs7Device one = othYs7DeviceService.lambdaQuery()
.eq(OthYs7Device::getDeviceSerial, req.getDeviceSerial())
.last("limit 1")
.one();
if (one == null) {
throw new ServiceException("萤石摄像头信息不存在", HttpStatus.NOT_FOUND);
}
// 将实体类和 DTO 进行转换
OthYs7Device ys7Device = new OthYs7Device();
BeanUtils.copyProperties(req, ys7Device);
ys7Device.setId(one.getId());
// 判断是否更新名称
String deviceName = req.getDeviceName();
if (deviceName != null && !deviceName.equals(one.getDeviceName())) {
Long count = othYs7DeviceService.lambdaQuery()
.eq(OthYs7Device::getDeviceName, req.getDeviceName())
.count();
if (count > 0) {
throw new ServiceException("已存在同名萤石摄像头", HttpStatus.CONFLICT);
}
// todo 更新云端名称
/* Boolean result = ys7Manager.updateDeviceName(one.getDeviceSerial(), deviceName);
if (!result) {
throw new ServiceException("更新云端萤石摄像头名称异常", HttpStatus.ERROR);
}*/
}
return toAjax(othYs7DeviceService.updateById(ys7Device));
}
/**
* 查询质量信息
*/

View File

@ -0,0 +1,40 @@
package org.dromara.bigscreen.domain.dto;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lilemy
* @date 2025/6/13 10:19
*/
@Data
public class Ys7DeviceUpdateReq implements Serializable {
@Serial
private static final long serialVersionUID = -3434796275594146484L;
/**
* 设备序列号
*/
@NotBlank(message = "设备序列号不能为空")
private String deviceSerial;
/**
* 设备名称
*/
private String deviceName;
/**
* 设备详情
*/
private String detail;
/**
* 备注
*/
private String remark;
}

View File

@ -6,9 +6,7 @@ import org.dromara.progress.service.IPgsProgressPlanDetailService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
/**
* 同步计划详情到施工产值
@ -26,17 +24,18 @@ public class IncSyncPlanDetail2ConstructionValue {
/**
* 同步计划详情到施工产值(每天 1 点执行)
*/
@Scheduled(cron = "0 0 2 ? * MON")
@Scheduled(cron = "0 0 1 * * ?")
public void run() {
LocalDate today = LocalDate.now();
// 找到本周一
LocalDate localDate = today.minusDays(1);
/* // 找到本周一
LocalDate thisMonday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
// 上周一 = 本周一 - 1 周
LocalDate lastMonday = thisMonday.minusWeeks(1);
// 上周日 = 上周一 + 6 天
LocalDate lastSunday = lastMonday.plusDays(6);
log.info("执行定时任务:同步 {}至{} 计划详情到施工产值", lastMonday, lastSunday);
Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(lastMonday, lastSunday, null);
LocalDate lastSunday = lastMonday.plusDays(6);*/
log.info("执行定时任务:同步 {}至{} 计划详情到施工产值", localDate, localDate);
Boolean synced = progressPlanDetailService.syncPlanDetail2ConstructionValue(localDate, localDate, null);
if (synced) {
log.info("同步计划详情到施工产值成功");
} else {

View File

@ -66,7 +66,9 @@ import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URISyntaxException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
@ -893,93 +895,190 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
return project.getId();
}
}).distinct().toList();
// 判断项目是否已存在施工产值范围
LocalDate now = LocalDate.now();
// 获取本周的星期一
LocalDate monday = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
// 获取本周的星期日
LocalDate sunday = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
List<OutConstructionValueRange> oldRangeList = constructionValueRangeService.lambdaQuery()
.eq(OutConstructionValueRange::getStartDate, monday)
.eq(OutConstructionValueRange::getEndDate, sunday)
.in(OutConstructionValueRange::getProjectId, allProjectIds)
.list();
// 过滤出没有值的项目
List<Long> haveProjectIds = oldRangeList.stream()
.map(OutConstructionValueRange::getProjectId)
.toList();
List<Long> noValueProjectIds = allProjectIds.stream()
.filter(p -> !haveProjectIds.contains(p))
.toList();
// 根据项目区分
Map<Long, List<PgsProgressPlanDetail>> detailMap = planDetailList.stream()
.collect(Collectors.groupingBy(PgsProgressPlanDetail::getProjectId));
List<OutConstructionValue> saveList = new ArrayList<>();
LocalDate now = LocalDate.now();
List<PgsProgressPlanDetail> allUpdateList = new ArrayList<>();
List<OutConstructionValueRange> ranges = allProjectIds.stream().map(id -> {
OutConstructionValueRange range = new OutConstructionValueRange();
long rangeId = IdWorker.getId(range);
range.setId(rangeId);
range.setProjectId(id);
range.setStartDate(startDate);
range.setEndDate(endDate);
// 获取所有子项目
List<Long> subProject = new ArrayList<>(projectList.stream()
.filter(project -> Objects.equals(project.getPId(), id))
.map(BusProject::getId)
.distinct()
.toList());
subProject.add(id);
List<PgsProgressPlanDetail> detailList = new ArrayList<>();
for (Long p : subProject) {
List<PgsProgressPlanDetail> details = detailMap.getOrDefault(p, List.of());
detailList.addAll(details);
}
if (CollUtil.isEmpty(detailList)) {
return null;
}
BigDecimal allConstructionValue = BigDecimal.ZERO;
BigDecimal allOwnerValue = BigDecimal.ZERO;
List<PgsProgressPlanDetail> updateList = new ArrayList<>();
for (PgsProgressPlanDetail planDetail : detailList) {
OutConstructionValue value = new OutConstructionValue();
Long progressCategoryId = planDetail.getProgressCategoryId();
PgsProgressCategory category = categoryMap.get(progressCategoryId);
if (category == null) {
continue;
if (CollUtil.isNotEmpty(noValueProjectIds)) {
List<OutConstructionValueRange> ranges = noValueProjectIds.stream().map(id -> {
OutConstructionValueRange range = new OutConstructionValueRange();
long rangeId = IdWorker.getId(range);
range.setId(rangeId);
range.setProjectId(id);
range.setStartDate(startDate);
range.setEndDate(endDate);
// 获取所有子项目
List<Long> subProject = new ArrayList<>(projectList.stream()
.filter(project -> Objects.equals(project.getPId(), id))
.map(BusProject::getId)
.distinct()
.toList());
subProject.add(id);
List<PgsProgressPlanDetail> detailList = new ArrayList<>();
for (Long p : subProject) {
List<PgsProgressPlanDetail> details = detailMap.getOrDefault(p, List.of());
detailList.addAll(details);
}
value.setProjectId(id);
value.setRangeId(rangeId);
value.setMatrixId(category.getMatrixId());
value.setProgressCategoryId(progressCategoryId);
value.setDetailId(planDetail.getId());
BigDecimal finishedNumber = planDetail.getFinishedNumber();
BigDecimal aiFill = planDetail.getAiFill();
// 如果完成数量为0, 则不保存
if (finishedNumber.compareTo(BigDecimal.ZERO) == 0) {
continue;
if (CollUtil.isEmpty(detailList)) {
return null;
}
BigDecimal allConstructionValue = BigDecimal.ZERO;
BigDecimal allOwnerValue = BigDecimal.ZERO;
List<PgsProgressPlanDetail> updateList = new ArrayList<>();
for (PgsProgressPlanDetail planDetail : detailList) {
OutConstructionValue value = new OutConstructionValue();
Long progressCategoryId = planDetail.getProgressCategoryId();
PgsProgressCategory category = categoryMap.get(progressCategoryId);
if (category == null) {
continue;
}
value.setProjectId(id);
value.setRangeId(rangeId);
value.setMatrixId(category.getMatrixId());
value.setProgressCategoryId(progressCategoryId);
value.setDetailId(planDetail.getId());
BigDecimal finishedNumber = planDetail.getFinishedNumber();
BigDecimal aiFill = planDetail.getAiFill();
// 如果完成数量为0, 则不保存
if (finishedNumber.compareTo(BigDecimal.ZERO) == 0) {
continue;
}
value.setArtificialNum(finishedNumber.subtract(aiFill).intValue());
value.setUavNum(aiFill.intValue());
value.setPlanNum(planDetail.getPlanNumber().intValue());
value.setReportDate(now.minusDays(1));
value.setPlanDate(planDetail.getDate());
// 计算产值
BigDecimal constructionPrice = category.getConstructionPrice();
BigDecimal ownerPrice = category.getOwnerPrice();
BigDecimal constructionValue = constructionPrice.multiply(finishedNumber).setScale(4, RoundingMode.HALF_UP);
BigDecimal ownerValue = ownerPrice.multiply(finishedNumber).setScale(4, RoundingMode.HALF_UP);
value.setOutValue(constructionValue);
value.setOwnerValue(ownerValue);
// 统计总产值
allConstructionValue = allConstructionValue.add(constructionValue).setScale(4, RoundingMode.HALF_UP);
allOwnerValue = allOwnerValue.add(ownerValue).setScale(4, RoundingMode.HALF_UP);
// 添加需要修改状态的计划详情
PgsProgressPlanDetail update = new PgsProgressPlanDetail();
update.setId(planDetail.getId());
update.setStatus("2");
updateList.add(update);
saveList.add(value);
}
range.setOutValue(allConstructionValue);
range.setOwnerValue(allOwnerValue);
// 如果产值都为0则不保存
if (allConstructionValue.compareTo(BigDecimal.ZERO) == 0 && allOwnerValue.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
allUpdateList.addAll(updateList);
return range;
}).filter(Objects::nonNull).toList();
// 保存数据
if (CollUtil.isNotEmpty(ranges)) {
boolean saveBatch = constructionValueRangeService.saveBatch(ranges);
if (!saveBatch) {
throw new ServiceException("同步计划详情到施工产值失败,数据库异常", HttpStatus.ERROR);
}
value.setArtificialNum(finishedNumber.subtract(aiFill).intValue());
value.setUavNum(aiFill.intValue());
value.setPlanNum(planDetail.getPlanNumber().intValue());
value.setReportDate(now);
value.setPlanDate(planDetail.getDate());
// 计算产值
BigDecimal constructionPrice = category.getConstructionPrice();
BigDecimal ownerPrice = category.getOwnerPrice();
BigDecimal constructionValue = constructionPrice.multiply(finishedNumber).setScale(4, RoundingMode.HALF_UP);
BigDecimal ownerValue = ownerPrice.multiply(finishedNumber).setScale(4, RoundingMode.HALF_UP);
value.setOutValue(constructionValue);
value.setOwnerValue(ownerValue);
// 统计总产值
allConstructionValue = allConstructionValue.add(constructionValue).setScale(4, RoundingMode.HALF_UP);
allOwnerValue = allOwnerValue.add(ownerValue).setScale(4, RoundingMode.HALF_UP);
// 添加需要修改状态的计划详情
PgsProgressPlanDetail update = new PgsProgressPlanDetail();
update.setId(planDetail.getId());
update.setStatus("2");
updateList.add(update);
saveList.add(value);
}
range.setOutValue(allConstructionValue);
range.setOwnerValue(allOwnerValue);
// 如果产值都为0则不保存
if (allConstructionValue.compareTo(BigDecimal.ZERO) == 0 && allOwnerValue.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
allUpdateList.addAll(updateList);
return range;
}).filter(Objects::nonNull).toList();
// 保存数据
if (CollUtil.isNotEmpty(ranges)) {
boolean saveBatch = constructionValueRangeService.saveBatch(ranges);
if (!saveBatch) {
throw new ServiceException("同步计划详情到施工产值失败,数据库异常", HttpStatus.ERROR);
}
}
if (CollUtil.isNotEmpty(haveProjectIds)) {
List<OutConstructionValueRange> ranges = oldRangeList.stream().map(range -> {
// 获取所有子项目
List<Long> subProject = new ArrayList<>(projectList.stream()
.filter(project -> Objects.equals(project.getPId(), range.getProjectId()))
.map(BusProject::getId)
.distinct()
.toList());
subProject.add(range.getProjectId());
List<PgsProgressPlanDetail> detailList = new ArrayList<>();
for (Long p : subProject) {
List<PgsProgressPlanDetail> details = detailMap.getOrDefault(p, List.of());
detailList.addAll(details);
}
if (CollUtil.isEmpty(detailList)) {
return null;
}
BigDecimal allConstructionValue = range.getOutValue();
BigDecimal allOwnerValue = range.getOwnerValue();
List<PgsProgressPlanDetail> updateList = new ArrayList<>();
for (PgsProgressPlanDetail planDetail : detailList) {
OutConstructionValue value = new OutConstructionValue();
Long progressCategoryId = planDetail.getProgressCategoryId();
PgsProgressCategory category = categoryMap.get(progressCategoryId);
if (category == null) {
continue;
}
value.setProjectId(range.getProjectId());
value.setRangeId(range.getId());
value.setMatrixId(category.getMatrixId());
value.setProgressCategoryId(progressCategoryId);
value.setDetailId(planDetail.getId());
BigDecimal finishedNumber = planDetail.getFinishedNumber();
BigDecimal aiFill = planDetail.getAiFill();
// 如果完成数量为0, 则不保存
if (finishedNumber.compareTo(BigDecimal.ZERO) == 0) {
continue;
}
value.setArtificialNum(finishedNumber.subtract(aiFill).intValue());
value.setUavNum(aiFill.intValue());
value.setPlanNum(planDetail.getPlanNumber().intValue());
value.setReportDate(now.minusDays(1));
value.setPlanDate(planDetail.getDate());
// 计算产值
BigDecimal constructionPrice = category.getConstructionPrice();
BigDecimal ownerPrice = category.getOwnerPrice();
BigDecimal constructionValue = constructionPrice.multiply(finishedNumber).setScale(4, RoundingMode.HALF_UP);
BigDecimal ownerValue = ownerPrice.multiply(finishedNumber).setScale(4, RoundingMode.HALF_UP);
value.setOutValue(constructionValue);
value.setOwnerValue(ownerValue);
// 统计总产值
allConstructionValue = allConstructionValue.add(constructionValue).setScale(4, RoundingMode.HALF_UP);
allOwnerValue = allOwnerValue.add(ownerValue).setScale(4, RoundingMode.HALF_UP);
// 添加需要修改状态的计划详情
PgsProgressPlanDetail update = new PgsProgressPlanDetail();
update.setId(planDetail.getId());
update.setStatus("2");
updateList.add(update);
saveList.add(value);
}
range.setOutValue(allConstructionValue);
range.setOwnerValue(allOwnerValue);
// 如果产值都为0则不修改
if (allConstructionValue.compareTo(BigDecimal.ZERO) == 0 && allOwnerValue.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
allUpdateList.addAll(updateList);
return range;
}).filter(Objects::nonNull).toList();
// 修改数据
if (CollUtil.isNotEmpty(ranges)) {
boolean updateBatchById = constructionValueRangeService.updateBatchById(ranges);
if (!updateBatchById) {
throw new ServiceException("同步计划详情到施工产值失败,数据库异常", HttpStatus.ERROR);
}
}
}
if (CollUtil.isNotEmpty(saveList)) {
boolean saved = constructionValueService.saveBatch(saveList);
if (!saved) {