[update]修改根据GeoJson创建方阵、光伏板、箱变、逆变器方法 [add] 新增进度计划模版、进度计划接口

This commit is contained in:
lcj
2025-05-26 19:58:15 +08:00
parent caef8fc4e2
commit 560ed53f70
43 changed files with 1985 additions and 211 deletions

View File

@ -0,0 +1,16 @@
package org.dromara.common.json.handler;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalToIntegerSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeNumber(value.setScale(0, RoundingMode.DOWN)); // 去除小数部分
}
}

View File

@ -0,0 +1,81 @@
package org.dromara.facility.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil;
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.facility.domain.dto.percentagefacility.FacPercentageFacilityQueryReq;
import org.dromara.facility.domain.vo.percentagefacility.FacPercentageFacilityVo;
import org.dromara.facility.service.IFacPercentageFacilityService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 设施-百分比设施
*
* @author lcj
* @date 2025-05-26
*/
@Validated
@RestController
@RequestMapping("/facility/percentageFacility")
public class FacPercentageFacilityController extends BaseController {
@Resource
private IFacPercentageFacilityService facPercentageFacilityService;
/**
* 查询设施-百分比设施列表
*/
@SaCheckPermission("facility:percentageFacility:list")
@GetMapping("/list")
public TableDataInfo<FacPercentageFacilityVo> list(FacPercentageFacilityQueryReq req, PageQuery pageQuery) {
return facPercentageFacilityService.queryPageList(req, pageQuery);
}
/**
* 导出设施-百分比设施列表
*/
@SaCheckPermission("facility:percentageFacility:export")
@Log(title = "设施-百分比设施", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(FacPercentageFacilityQueryReq req, HttpServletResponse response) {
List<FacPercentageFacilityVo> list = facPercentageFacilityService.queryList(req);
ExcelUtil.exportExcel(list, "设施-百分比设施", FacPercentageFacilityVo.class, response);
}
/**
* 获取设施-百分比设施详细信息
*
* @param id 主键
*/
@SaCheckPermission("facility:percentageFacility:query")
@GetMapping("/{id}")
public R<FacPercentageFacilityVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(facPercentageFacilityService.queryById(id));
}
/**
* 删除设施-百分比设施
*
* @param ids 主键串
*/
@SaCheckPermission("facility:percentageFacility:remove")
@Log(title = "设施-百分比设施", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(facPercentageFacilityService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,60 @@
package org.dromara.facility.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 设施-百分比设施对象 fac_percentage_facility
*
* @author lcj
* @date 2025-05-26
*/
@Data
@TableName("fac_percentage_facility")
public class FacPercentageFacility implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 方阵id
*/
private Long matrixId;
/**
* 进度类型id
*/
private Long progressCategoryId;
/**
* 进度类别名称
*/
private String progressCategoryName;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@ -30,11 +30,6 @@ public class FacBoxTransformerCreateByGeoJsonReq implements Serializable {
/**
* 名称
*/
private FacGeoJsonByPoint nameGeoJson;
/**
* 进度类别id列表
*/
private List<Long> progressCategoryIdList;
private List<FacGeoJsonByPoint> nameGeoJson;
}

View File

@ -30,11 +30,6 @@ public class FacInverterCreateByGeoJsonReq implements Serializable {
/**
* 名称
*/
private FacGeoJsonByPoint nameGeoJson;
/**
* 进度类别id列表
*/
private List<Long> progressCategoryIdList;
private List<FacGeoJsonByPoint> nameGeoJson;
}

View File

@ -6,6 +6,7 @@ import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPoint;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* @author lcj
@ -30,6 +31,6 @@ public class FacMatrixCreateByGeoJsonReq implements Serializable {
/**
* 名称
*/
private FacGeoJsonByPoint nameGeoJson;
private List<FacGeoJsonByPoint> nameGeoJson;
}

View File

@ -0,0 +1,38 @@
package org.dromara.facility.domain.dto.percentagefacility;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/5/26 18:46
*/
@Data
public class FacPercentageFacilityQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = -2855861335256326590L;
/**
* 项目id
*/
private Long projectId;
/**
* 方阵id
*/
private Long matrixId;
/**
* 进度类型id
*/
private Long progressCategoryId;
/**
* 进度类别名称
*/
private String progressCategoryName;
}

View File

@ -31,11 +31,6 @@ public class FacPhotovoltaicPanelCreateByGeoJsonReq implements Serializable {
/**
* 名称
*/
private FacGeoJsonByPoint nameGeoJson;
/**
* 进度类别id列表
*/
private List<Long> progressCategoryIdList;
private List<FacGeoJsonByPoint> nameGeoJson;
}

View File

@ -24,6 +24,6 @@ public class FacPhotovoltaicPanelPartsCreateByGeoJsonReq implements Serializable
/**
* 桩点、立柱、支架 GeoJson
*/
private FacGeoJsonByPoint pointGeoJson;
private FacGeoJsonByPoint locationGeoJson;
}

View File

@ -0,0 +1,58 @@
package org.dromara.facility.domain.vo.percentagefacility;
import org.dromara.facility.domain.FacPercentageFacility;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 设施-百分比设施视图对象 fac_percentage_facility
*
* @author lcj
* @date 2025-05-26
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = FacPercentageFacility.class)
public class FacPercentageFacilityVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 项目id
*/
@ExcelProperty(value = "项目id")
private Long projectId;
/**
* 方阵id
*/
@ExcelProperty(value = "方阵id")
private Long matrixId;
/**
* 进度类型id
*/
@ExcelProperty(value = "进度类型id")
private Long progressCategoryId;
/**
* 进度类别名称
*/
@ExcelProperty(value = "进度类别名称")
private String progressCategoryName;
}

View File

@ -0,0 +1,15 @@
package org.dromara.facility.mapper;
import org.dromara.facility.domain.FacPercentageFacility;
import org.dromara.facility.domain.vo.percentagefacility.FacPercentageFacilityVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 设施-百分比设施Mapper接口
*
* @author lcj
* @date 2025-05-26
*/
public interface FacPercentageFacilityMapper extends BaseMapperPlus<FacPercentageFacility, FacPercentageFacilityVo> {
}

View File

@ -0,0 +1,81 @@
package org.dromara.facility.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.facility.domain.FacPercentageFacility;
import org.dromara.facility.domain.dto.percentagefacility.FacPercentageFacilityQueryReq;
import org.dromara.facility.domain.vo.percentagefacility.FacPercentageFacilityVo;
import java.util.Collection;
import java.util.List;
/**
* 设施-百分比设施Service接口
*
* @author lcj
* @date 2025-05-26
*/
public interface IFacPercentageFacilityService extends IService<FacPercentageFacility> {
/**
* 查询设施-百分比设施
*
* @param id 主键
* @return 设施-百分比设施
*/
FacPercentageFacilityVo queryById(Long id);
/**
* 分页查询设施-百分比设施列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 设施-百分比设施分页列表
*/
TableDataInfo<FacPercentageFacilityVo> queryPageList(FacPercentageFacilityQueryReq req, PageQuery pageQuery);
/**
* 查询符合条件的设施-百分比设施列表
*
* @param req 查询条件
* @return 设施-百分比设施列表
*/
List<FacPercentageFacilityVo> queryList(FacPercentageFacilityQueryReq req);
/**
* 校验并批量删除设施-百分比设施信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 获取设施-百分比设施视图对象
*
* @param percentageFacility 设施-百分比设施对象
* @return 设施-百分比设施视图对象
*/
FacPercentageFacilityVo getVo(FacPercentageFacility percentageFacility);
/**
* 获取设施-百分比设施查询条件封装
*
* @param req 查询条件
* @return 查询条件封装
*/
LambdaQueryWrapper<FacPercentageFacility> buildQueryWrapper(FacPercentageFacilityQueryReq req);
/**
* 获取设施-百分比设施分页对象视图
*
* @param percentageFacilityPage 设施-百分比设施分页对象
* @return 设施-百分比设施分页对象视图
*/
Page<FacPercentageFacilityVo> getVoPage(Page<FacPercentageFacility> percentageFacilityPage);
}

View File

@ -64,6 +64,20 @@ public interface IFacPhotovoltaicPanelService extends IService<FacPhotovoltaicPa
*/
Boolean insertByGeoJson(FacPhotovoltaicPanelCreateByGeoJsonReq geoJson);
/**
* 批量新增光伏板
*
* @param photovoltaicPanelList 光伏板列表
*/
void insertBatchInner(List<FacPhotovoltaicPanel> photovoltaicPanelList);
/**
* 批量删除光伏板
*
* @param photovoltaicPanelList 光伏板列表
*/
void deleteBatchInner(List<FacPhotovoltaicPanel> photovoltaicPanelList);
/**
* 修改设施-光伏板
*

View File

@ -20,11 +20,13 @@ import org.dromara.facility.domain.dto.boxtransformer.FacBoxTransformerCreateReq
import org.dromara.facility.domain.dto.boxtransformer.FacBoxTransformerQueryReq;
import org.dromara.facility.domain.dto.boxtransformer.FacBoxTransformerUpdateReq;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeometryByPoint;
import org.dromara.facility.domain.vo.boxtransformer.FacBoxTransformerVo;
import org.dromara.facility.mapper.FacBoxTransformerMapper;
import org.dromara.facility.service.IFacBoxTransformerService;
import org.dromara.facility.service.IFacMatrixService;
import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
@ -33,6 +35,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -162,17 +165,17 @@ public class FacBoxTransformerServiceImpl extends ServiceImpl<FacBoxTransformerM
(boxTransformer1, boxTransformer2) -> boxTransformer1
));
List<FacFeatureByPoint> locationGeoJson = geoJson.getLocationGeoJson().getFeatures();
List<FacFeatureByPoint> nameGeoJson = geoJson.getNameGeoJson().getFeatures();
// 获取所有对应名称的点
List<FacGeoJsonByPoint> nameGeoJsonList = geoJson.getNameGeoJson();
List<FacFeatureByPoint> nameGeoJson = new ArrayList<>();
for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonList) {
nameGeoJson.addAll(geoJsonByPoint.getFeatures());
}
// 获取进度类别信息
List<Long> progressCategoryIdList = geoJson.getProgressCategoryIdList();
Map<Long, PgsProgressCategory> progressCategoryMap = progressCategoryService.lambdaQuery()
.in(PgsProgressCategory::getId, progressCategoryIdList).list()
.stream()
.collect(Collectors.toMap(
PgsProgressCategory::getId,
Function.identity(),
(existing, replacement) -> existing
));
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
.in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.BOX_TRANSFORMER_PROGRESS_CATEGORY_WORK_TYPE).list();
Map<Long, List<PgsProgressCategory>> progressCategoryMap = progressCategoryList
.stream().collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId));
List<FacBoxTransformer> boxTransformerList = new ArrayList<>();
for (FacFeatureByPoint locationFeature : locationGeoJson) {
FacGeometryByPoint geometry = locationFeature.getGeometry();
@ -188,24 +191,26 @@ public class FacBoxTransformerServiceImpl extends ServiceImpl<FacBoxTransformerM
continue;
}
// 根据进度类别创建
for (Long progressCategoryId : progressCategoryIdList) {
Long matrixId = matrix.getId();
List<PgsProgressCategory> progressCategoryListByMatrix = progressCategoryMap.get(matrixId);
for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) {
FacBoxTransformer boxTransformer = new FacBoxTransformer();
boxTransformer.setMatrixId(matrix.getId());
boxTransformer.setName(name);
boxTransformer.setProjectId(projectId);
boxTransformer.setPositions(JSONUtil.toJsonStr(coordinates));
String mapKey = name + "_" + progressCategoryId;
String mapKey = name + "_" + progressCategory.getId();
// 如果有同名同类别箱变,则获取该箱变完成状态
if (CollUtil.isNotEmpty(boxTransformerMap) && boxTransformerMap.containsKey(mapKey)) {
FacBoxTransformer oldBoxTransformer = boxTransformerMap.get(name);
FacBoxTransformer oldBoxTransformer = boxTransformerMap.get(mapKey);
boxTransformer.setFinishType(oldBoxTransformer.getFinishType());
boxTransformer.setFinishDate(oldBoxTransformer.getFinishDate());
boxTransformer.setProgressCategoryId(oldBoxTransformer.getProgressCategoryId());
boxTransformer.setProgressCategoryName(oldBoxTransformer.getProgressCategoryName());
boxTransformer.setStatus(oldBoxTransformer.getStatus());
} else {
boxTransformer.setProgressCategoryId(progressCategoryId);
boxTransformer.setProgressCategoryName(progressCategoryMap.get(progressCategoryId).getName());
boxTransformer.setProgressCategoryId(progressCategory.getId());
boxTransformer.setProgressCategoryName(progressCategory.getName());
}
boxTransformerList.add(boxTransformer);
}
@ -224,6 +229,21 @@ public class FacBoxTransformerServiceImpl extends ServiceImpl<FacBoxTransformerM
throw new ServiceException("新增箱变失败,数据库异常", HttpStatus.ERROR);
}
}
// 更新数量
Map<Long, List<FacBoxTransformer>> countMap = boxTransformerList
.stream().collect(Collectors.groupingBy(FacBoxTransformer::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
int total = 0;
if (countMap.containsKey(progressCategoryId)) {
total = countMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {
throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR);
}
return true;
}

View File

@ -16,6 +16,7 @@ import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.facility.domain.FacInverter;
import org.dromara.facility.domain.FacMatrix;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeometryByPoint;
import org.dromara.facility.domain.dto.inverter.FacInverterCreateByGeoJsonReq;
import org.dromara.facility.domain.dto.inverter.FacInverterCreateReq;
@ -25,6 +26,7 @@ import org.dromara.facility.domain.vo.inverter.FacInverterVo;
import org.dromara.facility.mapper.FacInverterMapper;
import org.dromara.facility.service.IFacInverterService;
import org.dromara.facility.service.IFacMatrixService;
import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
@ -33,6 +35,7 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -162,17 +165,17 @@ public class FacInverterServiceImpl extends ServiceImpl<FacInverterMapper, FacIn
(inverter1, inverter2) -> inverter1
));
List<FacFeatureByPoint> locationGeoJson = geoJson.getLocationGeoJson().getFeatures();
List<FacFeatureByPoint> nameGeoJson = geoJson.getNameGeoJson().getFeatures();
// 获取所有对应名称的点
List<FacGeoJsonByPoint> nameGeoJsonList = geoJson.getNameGeoJson();
List<FacFeatureByPoint> nameGeoJson = new ArrayList<>();
for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonList) {
nameGeoJson.addAll(geoJsonByPoint.getFeatures());
}
// 获取进度类别信息
List<Long> progressCategoryIdList = geoJson.getProgressCategoryIdList();
Map<Long, PgsProgressCategory> progressCategoryMap = progressCategoryService.lambdaQuery()
.in(PgsProgressCategory::getId, progressCategoryIdList).list()
.stream()
.collect(Collectors.toMap(
PgsProgressCategory::getId,
Function.identity(),
(existing, replacement) -> existing
));
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
.in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.INVERTER_PROGRESS_CATEGORY_WORK_TYPE).list();
Map<Long, List<PgsProgressCategory>> progressCategoryMap = progressCategoryList.stream()
.collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId));
List<FacInverter> inverterList = new ArrayList<>();
for (FacFeatureByPoint locationFeature : locationGeoJson) {
FacGeometryByPoint geometry = locationFeature.getGeometry();
@ -188,24 +191,26 @@ public class FacInverterServiceImpl extends ServiceImpl<FacInverterMapper, FacIn
continue;
}
// 根据进度类别创建
for (Long progressCategoryId : progressCategoryIdList) {
Long matrixId = matrix.getId();
List<PgsProgressCategory> progressCategoryListByMatrix = progressCategoryMap.get(matrixId);
for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) {
FacInverter inverter = new FacInverter();
inverter.setMatrixId(matrix.getId());
inverter.setName(name);
inverter.setProjectId(projectId);
inverter.setPositions(JSONUtil.toJsonStr(coordinates));
String mapKey = name + "_" + progressCategoryId;
String mapKey = name + "_" + progressCategory.getId();
// 如果有同名同类别箱变,则获取该箱变完成状态
if (CollUtil.isNotEmpty(inverterMap) && inverterMap.containsKey(mapKey)) {
FacInverter oldInverter = inverterMap.get(name);
FacInverter oldInverter = inverterMap.get(mapKey);
inverter.setFinishType(oldInverter.getFinishType());
inverter.setFinishDate(oldInverter.getFinishDate());
inverter.setProgressCategoryId(oldInverter.getProgressCategoryId());
inverter.setProgressCategoryName(oldInverter.getProgressCategoryName());
inverter.setStatus(oldInverter.getStatus());
} else {
inverter.setProgressCategoryId(progressCategoryId);
inverter.setProgressCategoryName(progressCategoryMap.get(progressCategoryId).getName());
inverter.setProgressCategoryId(progressCategory.getId());
inverter.setProgressCategoryName(progressCategory.getName());
}
inverterList.add(inverter);
}
@ -224,6 +229,21 @@ public class FacInverterServiceImpl extends ServiceImpl<FacInverterMapper, FacIn
throw new ServiceException("新增逆变器失败,数据库异常", HttpStatus.ERROR);
}
}
// 更新数量
Map<Long, List<FacInverter>> countMap = inverterList
.stream().collect(Collectors.groupingBy(FacInverter::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
int total = 0;
if (countMap.containsKey(progressCategoryId)) {
total = countMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {
throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR);
}
return true;
}

View File

@ -16,6 +16,7 @@ import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.facility.domain.*;
import org.dromara.facility.domain.dto.geojson.FacFeature;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeometry;
import org.dromara.facility.domain.dto.matrix.*;
import org.dromara.facility.domain.enums.FacFinishStatusEnum;
@ -23,6 +24,8 @@ import org.dromara.facility.domain.vo.matrix.FacMatrixDetailGisVo;
import org.dromara.facility.domain.vo.matrix.FacMatrixVo;
import org.dromara.facility.mapper.FacMatrixMapper;
import org.dromara.facility.service.*;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.utils.JSTUtils;
import org.springframework.beans.BeanUtils;
@ -75,6 +78,10 @@ public class FacMatrixServiceImpl extends ServiceImpl<FacMatrixMapper, FacMatrix
@Resource
private IFacInverterService inverterService;
@Lazy
@Resource
private IPgsProgressCategoryService progressCategoryService;
/**
* 查询设施-方阵
*
@ -257,7 +264,12 @@ public class FacMatrixServiceImpl extends ServiceImpl<FacMatrixMapper, FacMatrix
.eq(FacMatrix::getProjectId, projectId).list();
List<FacMatrix> matrixList = new ArrayList<>();
List<FacFeature> locationFeatures = geoJson.getLocationGeoJson().getFeatures();
List<FacFeatureByPoint> nameFeatures = geoJson.getNameGeoJson().getFeatures();
// 获取所有对应名称的点
List<FacGeoJsonByPoint> nameGeoJsonList = geoJson.getNameGeoJson();
List<FacFeatureByPoint> nameFeatures = new ArrayList<>();
for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonList) {
nameFeatures.addAll(geoJsonByPoint.getFeatures());
}
// 遍历位置信息
for (FacFeature feature : locationFeatures) {
FacMatrix matrix = new FacMatrix();
@ -266,15 +278,8 @@ public class FacMatrixServiceImpl extends ServiceImpl<FacMatrixMapper, FacMatrix
// 获取坐标信息
List<List<Double>> coordinatesList = JSTUtils.getTwoDimensionalCoordinates(geometry);
// 获取方阵名称
String name = null;
for (FacFeatureByPoint nameFeature : nameFeatures) {
List<Double> nameCoordinates = nameFeature.getGeometry().getCoordinates();
Boolean result = JSTUtils.pointIsWithInPlane(coordinatesList, nameCoordinates);
if (result) {
name = nameFeature.getProperties().getText();
break;
}
}
String nameStr = JSTUtils.findNearestPointText(coordinatesList, nameFeatures);
String name = nameStr.split(" ")[0];
if (name == null) {
continue;
}
@ -284,17 +289,33 @@ public class FacMatrixServiceImpl extends ServiceImpl<FacMatrixMapper, FacMatrix
matrix.setMatrixName(name);
matrixList.add(matrix);
}
// todo 关联数据处理
if (CollUtil.isNotEmpty(oldMatrixList)) {
boolean result = this.removeBatchByIds(oldMatrixList);
if (!result) {
throw new ServiceException("删除老方阵失败,数据库异常", HttpStatus.ERROR);
}
LambdaQueryWrapper<PgsProgressCategory> lqw = new LambdaQueryWrapper<>();
lqw.eq(PgsProgressCategory::getProjectId, projectId)
.in(PgsProgressCategory::getMatrixId, oldMatrixList.stream().map(FacMatrix::getId).toList());
List<PgsProgressCategory> progressCategories = progressCategoryService.list(lqw);
if (CollUtil.isNotEmpty(progressCategories)) {
boolean remove = progressCategoryService.remove(lqw);
if (!remove) {
throw new ServiceException("删除老方阵进度分类失败,数据库异常", HttpStatus.ERROR);
}
}
}
if (CollUtil.isNotEmpty(matrixList)) {
boolean result = this.saveBatch(matrixList);
if (!result) {
throw new ServiceException("批量新增方阵失败,数据库异常", HttpStatus.ERROR);
}
List<Long> matrixIdList = matrixList.stream().map(FacMatrix::getId).toList();
Boolean save = progressCategoryService.insertByTemplate(projectId, matrixIdList);
if (!save) {
throw new ServiceException("批量新增方阵进度分类失败,数据库异常", HttpStatus.ERROR);
}
}
return true;
}
@ -524,6 +545,12 @@ public class FacMatrixServiceImpl extends ServiceImpl<FacMatrixMapper, FacMatrix
if (result) {
matchMatrix = matrix;
break;
} else {
Boolean areResult = JSTUtils.arePolygonsIntersecting(positionList, coordinates);
if (areResult) {
matchMatrix = matrix;
break;
}
}
}
return matchMatrix;

View File

@ -0,0 +1,161 @@
package org.dromara.facility.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
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.facility.domain.FacPercentageFacility;
import org.dromara.facility.domain.dto.percentagefacility.FacPercentageFacilityQueryReq;
import org.dromara.facility.domain.vo.percentagefacility.FacPercentageFacilityVo;
import org.dromara.facility.mapper.FacPercentageFacilityMapper;
import org.dromara.facility.service.IFacPercentageFacilityService;
import org.dromara.project.service.IBusProjectService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
/**
* 设施-百分比设施Service业务层处理
*
* @author lcj
* @date 2025-05-26
*/
@Service
public class FacPercentageFacilityServiceImpl extends ServiceImpl<FacPercentageFacilityMapper, FacPercentageFacility>
implements IFacPercentageFacilityService {
@Resource
private IBusProjectService projectService;
/**
* 查询设施-百分比设施
*
* @param id 主键
* @return 设施-百分比设施
*/
@Override
public FacPercentageFacilityVo queryById(Long id) {
FacPercentageFacility percentageFacility = this.getById(id);
if (percentageFacility == null) {
throw new ServiceException("查询设施失败,数据不存在", HttpStatus.NOT_FOUND);
}
return this.getVo(percentageFacility);
}
/**
* 分页查询设施-百分比设施列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 设施-百分比设施分页列表
*/
@Override
public TableDataInfo<FacPercentageFacilityVo> queryPageList(FacPercentageFacilityQueryReq req, PageQuery pageQuery) {
Page<FacPercentageFacility> result = this.page(pageQuery.build(), this.buildQueryWrapper(req));
return TableDataInfo.build(this.getVoPage(result));
}
/**
* 查询符合条件的设施-百分比设施列表
*
* @param req 查询条件
* @return 设施-百分比设施列表
*/
@Override
public List<FacPercentageFacilityVo> queryList(FacPercentageFacilityQueryReq req) {
List<FacPercentageFacility> list = this.list(this.buildQueryWrapper(req));
return list.stream().map(this::getVo).toList();
}
/**
* 校验并批量删除设施-百分比设施信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
Long userId = LoginHelper.getUserId();
List<FacPercentageFacility> percentageFacilityList = this.listByIds(ids);
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
List<Long> projectId = percentageFacilityList.stream().map(FacPercentageFacility::getProjectId).toList();
projectService.validAuth(projectId, userId);
}
return this.removeBatchByIds(ids);
}
/**
* 获取设施-百分比设施视图对象
*
* @param percentageFacility 设施-百分比设施对象
* @return 设施-百分比设施视图对象
*/
@Override
public FacPercentageFacilityVo getVo(FacPercentageFacility percentageFacility) {
// 对象转封装类
FacPercentageFacilityVo percentageFacilityVo = new FacPercentageFacilityVo();
if (percentageFacility == null) {
return percentageFacilityVo;
}
BeanUtils.copyProperties(percentageFacility, percentageFacilityVo);
return percentageFacilityVo;
}
/**
* 获取设施-百分比设施查询条件封装
*
* @param req 查询条件
* @return 查询条件封装
*/
@Override
public LambdaQueryWrapper<FacPercentageFacility> buildQueryWrapper(FacPercentageFacilityQueryReq req) {
LambdaQueryWrapper<FacPercentageFacility> lqw = new LambdaQueryWrapper<>();
if (req == null) {
return lqw;
}
Long projectId = req.getProjectId();
Long matrixId = req.getMatrixId();
Long progressCategoryId = req.getProgressCategoryId();
String progressCategoryName = req.getProgressCategoryName();
lqw.eq(ObjectUtils.isNotEmpty(projectId), FacPercentageFacility::getProjectId, projectId);
lqw.eq(ObjectUtils.isNotEmpty(matrixId), FacPercentageFacility::getMatrixId, matrixId);
lqw.eq(ObjectUtils.isNotEmpty(progressCategoryId), FacPercentageFacility::getProgressCategoryId, progressCategoryId);
lqw.eq(StringUtils.isNotBlank(progressCategoryName), FacPercentageFacility::getProgressCategoryName, progressCategoryName);
return lqw;
}
/**
* 获取设施-百分比设施分页对象视图
*
* @param percentageFacilityPage 设施-百分比设施分页对象
* @return 设施-百分比设施分页对象视图
*/
@Override
public Page<FacPercentageFacilityVo> getVoPage(Page<FacPercentageFacility> percentageFacilityPage) {
List<FacPercentageFacility> percentageFacilityList = percentageFacilityPage.getRecords();
Page<FacPercentageFacilityVo> percentageFacilityVoPage = new Page<>(
percentageFacilityPage.getCurrent(),
percentageFacilityPage.getSize(),
percentageFacilityPage.getTotal());
if (CollUtil.isEmpty(percentageFacilityList)) {
return percentageFacilityVoPage;
}
List<FacPercentageFacilityVo> percentageFacilityVoList = percentageFacilityList.stream().map(this::getVo).toList();
percentageFacilityVoPage.setRecords(percentageFacilityVoList);
return percentageFacilityVoPage;
}
}

View File

@ -20,7 +20,9 @@ import org.dromara.facility.domain.dto.photovoltaicpanelparts.FacPhotovoltaicPan
import org.dromara.facility.service.*;
import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.PgsProgressCategoryTemplate;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.progress.service.IPgsProgressCategoryTemplateService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.utils.JSTUtils;
import org.springframework.aop.framework.AopContext;
@ -88,7 +90,7 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan
if (CollUtil.isEmpty(photovoltaicPanelList)) {
throw new ServiceException("项目下未创建光伏板", HttpStatus.NOT_FOUND);
}
List<FacFeatureByPoint> features = geoJson.getPointGeoJson().getFeatures();
List<FacFeatureByPoint> features = geoJson.getLocationGeoJson().getFeatures();
// 获取数据库中所有点的列表
List<FacPhotovoltaicPanelPoint> oldPointList = photovoltaicPanelPointService.lambdaQuery()
.eq(FacPhotovoltaicPanelPoint::getProjectId, projectId).list();

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
@ -17,29 +18,34 @@ import org.dromara.facility.domain.FacMatrix;
import org.dromara.facility.domain.FacPhotovoltaicPanel;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane;
import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeoJsonByPoint;
import org.dromara.facility.domain.dto.geojson.FacGeometryByPlane;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelCreateByGeoJsonReq;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelCreateReq;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelQueryReq;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelUpdateReq;
import org.dromara.facility.domain.enums.FacFinishStatusEnum;
import org.dromara.facility.domain.vo.photovoltaicpanel.FacPhotovoltaicPanelVo;
import org.dromara.facility.mapper.FacPhotovoltaicPanelMapper;
import org.dromara.facility.service.IFacMatrixService;
import org.dromara.facility.service.IFacPhotovoltaicPanelPartsService;
import org.dromara.facility.service.IFacPhotovoltaicPanelService;
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.utils.JSTUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -49,6 +55,7 @@ import java.util.stream.Collectors;
* @author lcj
* @date 2025-04-21
*/
@Slf4j
@Service
public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaicPanelMapper, FacPhotovoltaicPanel>
implements IFacPhotovoltaicPanelService {
@ -169,82 +176,204 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaic
Function.identity(),
(existing, replacement) -> existing // 如果有重复,保留第一个
));
// 获取数据库中光伏板信息
List<FacPhotovoltaicPanel> photovoltaicPanelList = new ArrayList<>();
List<FacFeatureByPlane> locationFeatures = geoJson.getLocationGeoJson().getFeatures();
List<FacFeatureByPoint> nameFeatures = geoJson.getNameGeoJson().getFeatures();
// 获取所有对应名称的点
List<FacGeoJsonByPoint> nameGeoJsonList = geoJson.getNameGeoJson();
List<FacFeatureByPoint> nameFeatures = new ArrayList<>();
for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonList) {
nameFeatures.addAll(geoJsonByPoint.getFeatures());
}
// 获取进度类别信息
List<Long> progressCategoryIdList = geoJson.getProgressCategoryIdList();
Map<Long, PgsProgressCategory> progressCategoryMap = progressCategoryService.lambdaQuery()
.in(PgsProgressCategory::getId, progressCategoryIdList).list()
.stream()
.collect(Collectors.toMap(
PgsProgressCategory::getId,
Function.identity(),
(existing, replacement) -> existing
));
for (FacFeatureByPlane locationFeature : locationFeatures) {
FacGeometryByPlane geometry = locationFeature.getGeometry();
List<List<Double>> coordinates = geometry.getCoordinates().getFirst();
// 判断光伏板在哪个方阵里
FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates);
if (matrix == null) {
continue;
List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
.in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE).list();
Map<Long, List<PgsProgressCategory>> progressCategoryMap = progressCategoryList.stream()
.collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId));
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
List<FacPhotovoltaicPanel> allPanels = new ArrayList<>();
try {
List<Future<List<FacPhotovoltaicPanel>>> futures = new ArrayList<>();
Long userId = LoginHelper.getUserId();
for (FacFeatureByPlane locationFeature : locationFeatures) {
Future<List<FacPhotovoltaicPanel>> future = executorService.submit(() -> {
List<FacPhotovoltaicPanel> panelList = new ArrayList<>();
// ① 获取 geometry 坐标
FacGeometryByPlane geometry = locationFeature.getGeometry();
List<List<Double>> coordinates = geometry.getCoordinates().getFirst();
// ② 判断方阵
FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates);
if (matrix == null) return Collections.emptyList();
// ③ 获取名称
String name = JSTUtils.findNearestPointText(coordinates, nameFeatures);
if (name == null) return Collections.emptyList();
// ④ 获取进度类别
Long matrixId = matrix.getId();
List<PgsProgressCategory> progressCategoryListByMatrix = progressCategoryMap.get(matrixId);
if (CollUtil.isEmpty(progressCategoryListByMatrix)) return Collections.emptyList();
// ⑤ 构建光伏板
for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) {
FacPhotovoltaicPanel panel = new FacPhotovoltaicPanel();
panel.setMatrixId(matrixId);
panel.setName(name);
panel.setProjectId(projectId);
panel.setPositions(JSONUtil.toJsonStr(coordinates));
panel.setCreateBy(userId);
panel.setUpdateBy(userId);
String mapKey = name + "_" + progressCategory.getId();
FacPhotovoltaicPanel oldPanel = photovoltaicPanelMap.get(mapKey);
if (oldPanel != null) {
panel.setStatus(oldPanel.getStatus());
if (FacFinishStatusEnum.FINISH.getValue().equals(oldPanel.getStatus())) {
panel.setFinishType(oldPanel.getFinishType());
panel.setFinishDate(oldPanel.getFinishDate());
}
panel.setProgressCategoryId(oldPanel.getProgressCategoryId());
panel.setProgressCategoryName(oldPanel.getProgressCategoryName());
} else {
panel.setProgressCategoryId(progressCategory.getId());
panel.setProgressCategoryName(progressCategory.getName());
}
panelList.add(panel);
}
return panelList;
});
futures.add(future);
}
// 获取光伏板名称
String name = null;
for (FacFeatureByPoint nameFeature : nameFeatures) {
List<Double> nameCoordinates = nameFeature.getGeometry().getCoordinates();
Boolean result = JSTUtils.pointIsWithInPlane(coordinates, nameCoordinates);
if (result) {
name = nameFeature.getProperties().getText();
break;
// 等待所有结果
for (Future<List<FacPhotovoltaicPanel>> future : futures) {
try {
allPanels.addAll(future.get());
} catch (Exception e) {
log.error("线程执行异常", e);
}
}
if (name == null) {
continue;
}
// 根据进度类别创建
for (Long progressCategoryId : progressCategoryIdList) {
FacPhotovoltaicPanel photovoltaicPanel = new FacPhotovoltaicPanel();
photovoltaicPanel.setMatrixId(matrix.getId());
photovoltaicPanel.setName(name);
photovoltaicPanel.setProjectId(projectId);
photovoltaicPanel.setPositions(JSONUtil.toJsonStr(coordinates));
String mapKey = name + "_" + progressCategoryId;
// 如果有同名同类别光伏板,则获取该光伏板的完成状态
if (CollUtil.isNotEmpty(photovoltaicPanelMap) && photovoltaicPanelMap.containsKey(mapKey)) {
FacPhotovoltaicPanel oldPhotovoltaicPanel = photovoltaicPanelMap.get(name);
photovoltaicPanel.setFinishType(oldPhotovoltaicPanel.getFinishType());
photovoltaicPanel.setFinishDate(oldPhotovoltaicPanel.getFinishDate());
photovoltaicPanel.setProgressCategoryId(oldPhotovoltaicPanel.getProgressCategoryId());
photovoltaicPanel.setProgressCategoryName(oldPhotovoltaicPanel.getProgressCategoryName());
photovoltaicPanel.setStatus(oldPhotovoltaicPanel.getStatus());
} else {
photovoltaicPanel.setProgressCategoryId(progressCategoryId);
photovoltaicPanel.setProgressCategoryName(progressCategoryMap.get(progressCategoryId).getName());
} finally {
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
photovoltaicPanelList.add(photovoltaicPanel);
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
}
// 操作数据库
// 删除旧数据
if (CollUtil.isNotEmpty(oldPhotovoltaicPanelList)) {
boolean result = this.removeBatchByIds(oldPhotovoltaicPanelList);
if (!result) {
throw new ServiceException("删除光伏板失败,数据库异常", HttpStatus.ERROR);
}
// 自定义线程池IO 密集型线程池)
ThreadPoolExecutor customExecutor = new ThreadPoolExecutor(
20, // 核心线程数
50, // 最大线程数
60L, // 线程空闲存活时间
TimeUnit.SECONDS, // 存活时间单位
new LinkedBlockingQueue<>(10000), // 阻塞队列容量
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程处理任务
);
// 分批处理,避免长事务,每次处理 1000 条数据
int batchSize = 1000;
// 保存所有批次任务
List<CompletableFuture<Void>> deleteFutures = new ArrayList<>();
int deleteSize = oldPhotovoltaicPanelList.size();
for (int i = 0; i < deleteSize; i += batchSize) {
int endIndex = Math.min(i + batchSize, deleteSize);
List<FacPhotovoltaicPanel> batchList = oldPhotovoltaicPanelList.subList(i, endIndex);
// 使用事务处理每批数据
// 获取代理
FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = (FacPhotovoltaicPanelServiceImpl) AopContext.currentProxy();
// 异步处理每批数据,将任务添加到异步任务列表
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> photovoltaicPanelService.deleteBatchInner(batchList), customExecutor);
deleteFutures.add(future);
}
// 批量保存
if (CollUtil.isNotEmpty(photovoltaicPanelList)) {
boolean save = this.saveBatch(photovoltaicPanelList);
if (!save) {
throw new ServiceException("新增光伏板失败,数据库异常", HttpStatus.ERROR);
// 等待所有批次完成操作
CompletableFuture.allOf(deleteFutures.toArray(new CompletableFuture[0])).join();
// 保存所有批次任务
List<CompletableFuture<Void>> insertFutures = new ArrayList<>();
int totalSize = allPanels.size();
for (int i = 0; i < totalSize; i += batchSize) {
int endIndex = Math.min(i + batchSize, totalSize);
List<FacPhotovoltaicPanel> batchList = allPanels.subList(i, endIndex);
// 使用事务处理每批数据
// 获取代理
FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = (FacPhotovoltaicPanelServiceImpl) AopContext.currentProxy();
// 异步处理每批数据,将任务添加到异步任务列表
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> photovoltaicPanelService.insertBatchInner(batchList), customExecutor);
insertFutures.add(future);
}
// 等待所有批次完成操作
CompletableFuture.allOf(insertFutures.toArray(new CompletableFuture[0])).join();
// 关闭线程池
customExecutor.shutdown();
// 更新数量
Map<Long, List<FacPhotovoltaicPanel>> countMap = allPanels
.stream().collect(Collectors.groupingBy(FacPhotovoltaicPanel::getProgressCategoryId));
for (PgsProgressCategory progressCategory : progressCategoryList) {
Long progressCategoryId = progressCategory.getId();
int total = 0;
if (countMap.containsKey(progressCategoryId)) {
total = countMap.get(progressCategoryId).size();
}
progressCategory.setTotal(BigDecimal.valueOf(total));
}
boolean result = progressCategoryService.updateBatchById(progressCategoryList);
if (!result) {
throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR);
}
return true;
}
/**
* 批量新增光伏板
*
* @param photovoltaicPanelList 光伏板列表
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void insertBatchInner(List<FacPhotovoltaicPanel> photovoltaicPanelList) {
try {
if (CollUtil.isNotEmpty(photovoltaicPanelList)) {
boolean result = this.saveBatch(photovoltaicPanelList);
if (!result) {
throw new ServiceException("批量新增光伏板失败,数据库异常", HttpStatus.ERROR);
}
}
} catch (DataIntegrityViolationException e) {
log.error("数据库唯一键冲突或违反其他完整性约束, 错误信息: {}", e.getMessage());
throw new ServiceException("数据已存在,无法重复添加");
} catch (DataAccessException e) {
log.error("数据库连接问题、事务问题等导致操作失败, 错误信息: {}", e.getMessage());
throw new ServiceException("数据库操作失败");
} catch (Exception e) {
// 捕获其他异常,做通用处理
log.error("批量添加光伏板时发生未知错误,错误信息: {}", e.getMessage());
throw new ServiceException("批量添加光伏板失败");
}
}
/**
* 批量删除光伏板
*
* @param photovoltaicPanelList 光伏板列表
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteBatchInner(List<FacPhotovoltaicPanel> photovoltaicPanelList) {
try {
if (CollUtil.isNotEmpty(photovoltaicPanelList)) {
boolean result = this.removeBatchByIds(photovoltaicPanelList);
if (!result) {
throw new ServiceException("删除光伏板失败,数据库异常", HttpStatus.ERROR);
}
}
} catch (DataIntegrityViolationException e) {
log.error("数据库唯一键冲突或违反其他完整性约束: {}", e.getMessage());
throw new ServiceException("数据已存在,无法重复添加");
} catch (DataAccessException e) {
log.error("数据库连接问题、事务问题等导致操作失败: {}", e.getMessage());
throw new ServiceException("数据库操作失败");
} catch (Exception e) {
// 捕获其他异常,做通用处理
log.error("批量删除光伏板时发生未知错误,错误信息: {}", e.getMessage());
throw new ServiceException("批量添加光伏板失败");
}
}
/**
* 修改设施-光伏板
*

View File

@ -1,5 +1,7 @@
package org.dromara.progress.constant;
import java.util.List;
/**
* @author lcj
* @date 2025/5/23 11:44
@ -11,4 +13,41 @@ public interface PgsProgressCategoryConstant {
*/
Long PUBLIC_PROJECT_ID = 0L;
/**
* 光伏板进度类别名称
*/
List<String> PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE = List.of(
"12",
"13",
"14",
"15",
"16",
"17"
);
/**
* 逆变器进度类别名称
*/
List<String> INVERTER_PROGRESS_CATEGORY_WORK_TYPE = List.of(
"2",
"3",
"4",
"18",
"19",
"20",
"21"
);
/**
* 箱变进度类别名称
*/
List<String> BOX_TRANSFORMER_PROGRESS_CATEGORY_WORK_TYPE = List.of(
"23",
"24",
"25",
"26",
"27",
"28"
);
}

View File

@ -29,7 +29,7 @@ import java.util.List;
* 进度类别
*
* @author lcj
* @date 2025-05-22
* @date 2025-05-26
*/
@Validated
@RestController

View File

@ -0,0 +1,118 @@
package org.dromara.progress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
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.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateCreateReq;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateQueryReq;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateUpdateReq;
import org.dromara.progress.domain.vo.progresscategorytemplate.PgsProgressCategoryTemplateVo;
import org.dromara.progress.service.IPgsProgressCategoryTemplateService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 进度类别模版
*
* @author lcj
* @date 2025-05-22
*/
@Validated
@RestController
@RequestMapping("/progress/progressCategoryTemplate")
public class PgsProgressCategoryTemplateController extends BaseController {
@Resource
private IPgsProgressCategoryTemplateService pgsProgressCategoryTemplateService;
/**
* 分页查询进度类别模版列表
*/
@SaCheckPermission("progress:progressCategoryTemplate:page")
@GetMapping("/page")
public TableDataInfo<PgsProgressCategoryTemplateVo> page(PgsProgressCategoryTemplateQueryReq req, PageQuery pageQuery) {
return pgsProgressCategoryTemplateService.queryPageList(req, pageQuery);
}
/**
* 查询进度类别模版列表
*/
@SaCheckPermission("progress:progressCategoryTemplate:list")
@GetMapping("/list")
public R<List<PgsProgressCategoryTemplateVo>> list(PgsProgressCategoryTemplateQueryReq req) {
List<PgsProgressCategoryTemplateVo> list = pgsProgressCategoryTemplateService.queryList(req);
return R.ok(list);
}
/**
* 导出进度类别模版列表
*/
@SaCheckPermission("progress:progressCategoryTemplate:export")
@Log(title = "进度类别模版", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(PgsProgressCategoryTemplateQueryReq req, HttpServletResponse response) {
List<PgsProgressCategoryTemplateVo> list = pgsProgressCategoryTemplateService.queryList(req);
ExcelUtil.exportExcel(list, "进度类别模版", PgsProgressCategoryTemplateVo.class, response);
}
/**
* 获取进度类别模版详细信息
*
* @param id 主键
*/
@SaCheckPermission("progress:progressCategoryTemplate:query")
@GetMapping("/{id}")
public R<PgsProgressCategoryTemplateVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(pgsProgressCategoryTemplateService.queryById(id));
}
/**
* 新增进度类别模版
*/
@SaCheckPermission("progress:progressCategoryTemplate:add")
@Log(title = "进度类别模版", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Long> add(@Validated(AddGroup.class) @RequestBody PgsProgressCategoryTemplateCreateReq req) {
return R.ok(pgsProgressCategoryTemplateService.insertByBo(req));
}
/**
* 修改进度类别模版
*/
@SaCheckPermission("progress:progressCategoryTemplate:edit")
@Log(title = "进度类别模版", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PgsProgressCategoryTemplateUpdateReq req) {
return toAjax(pgsProgressCategoryTemplateService.updateByBo(req));
}
/**
* 删除进度类别模版
*
* @param ids 主键串
*/
@SaCheckPermission("progress:progressCategoryTemplate:remove")
@Log(title = "进度类别模版", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(pgsProgressCategoryTemplateService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -1,22 +1,26 @@
package org.dromara.progress.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
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.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 进度类别对象 pgs_progress_category
*
* @author lcj
* @date 2025-05-22
* @date 2025-05-26
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("pgs_progress_category")
public class PgsProgressCategory implements Serializable {
public class PgsProgressCategory extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
@ -32,6 +36,16 @@ public class PgsProgressCategory implements Serializable {
*/
private Long pid;
/**
* 项目id
*/
private Long projectId;
/**
* 方阵id
*/
private Long matrixId;
/**
* 类别名称
*/
@ -43,18 +57,44 @@ public class PgsProgressCategory implements Serializable {
private String unitType;
/**
* 项目id0表示共用
* 总数量/百分比
*/
private Long projectId;
private BigDecimal total;
/**
* 创建时间
* 已完成数量/百分比
*/
private Date createTime;
private BigDecimal completed;
/**
* 更新时间
* 计划总数量/百分比
*/
private Date updateTime;
private BigDecimal planTotal;
/**
* 是否超期0否 1是
*/
private String isDelay;
/**
* 完成状态0未开始 1进行中 2已完成
*/
private String status;
/**
* 工作类型
*/
private String workType;
/**
* 删除时间
*/
private Date deletedAt;
/**
* 是否删除0正常 1删除
*/
@TableLogic
private Long isDelete;
}

View File

@ -0,0 +1,65 @@
package org.dromara.progress.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 进度类别模版对象 pgs_progress_category_template
*
* @author lcj
* @date 2025-05-22
*/
@Data
@TableName("pgs_progress_category_template")
public class PgsProgressCategoryTemplate implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 父类别id
*/
private Long pid;
/**
* 类别名称
*/
private String name;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
/**
* 工作类型
*/
private String workType;
/**
* 项目id0表示共用
*/
private Long projectId;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@ -2,24 +2,28 @@ package org.dromara.progress.domain.dto.progresscategory;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/5/22 16:07
* @date 2025/5/26 9:46
*/
@Data
public class PgsProgressCategoryCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = 6264724604334298318L;
public class PgsProgressCategoryCreateReq {
/**
* 父类别id
*/
private Long pid;
/**
* 项目id
*/
private Long projectId;
/**
* 方阵id
*/
private Long matrixId;
/**
* 类别名称
*/
@ -30,9 +34,4 @@ public class PgsProgressCategoryCreateReq implements Serializable {
*/
private String unitType;
/**
* 项目id0表示共用
*/
private Long projectId;
}

View File

@ -2,36 +2,21 @@ package org.dromara.progress.domain.dto.progresscategory;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/5/22 16:07
* @date 2025/5/26 9:46
*/
@Data
public class PgsProgressCategoryQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = 2607953543340685175L;
public class PgsProgressCategoryQueryReq {
/**
* 父类别id
*/
private Long pid;
/**
* 类别名称
*/
private String name;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
/**
* 项目id0表示共用
* 项目id
*/
private Long projectId;
/**
* 方阵id
*/
private Long matrixId;
}

View File

@ -2,18 +2,14 @@ package org.dromara.progress.domain.dto.progresscategory;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lcj
* @date 2025/5/22 16:07
* @date 2025/5/26 9:47
*/
@Data
public class PgsProgressCategoryUpdateReq implements Serializable {
@Serial
private static final long serialVersionUID = 8324950385975719302L;
public class PgsProgressCategoryUpdateReq {
/**
* 主键id
@ -25,6 +21,11 @@ public class PgsProgressCategoryUpdateReq implements Serializable {
*/
private Long pid;
/**
* 项目id
*/
private Long projectId;
/**
* 类别名称
*/
@ -35,4 +36,29 @@ public class PgsProgressCategoryUpdateReq implements Serializable {
*/
private String unitType;
/**
* 总数量/百分比
*/
private BigDecimal total;
/**
* 已完成数量/百分比
*/
private BigDecimal completed;
/**
* 计划总数量/百分比
*/
private BigDecimal planTotal;
/**
* 是否超期0否 1是
*/
private String isDelay;
/**
* 完成状态0未开始 1进行中 2已完成
*/
private String status;
}

View File

@ -0,0 +1,38 @@
package org.dromara.progress.domain.dto.progresscategorytemplate;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/5/22 16:07
*/
@Data
public class PgsProgressCategoryTemplateCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = 6264724604334298318L;
/**
* 父类别id
*/
private Long pid;
/**
* 类别名称
*/
private String name;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
/**
* 项目id0表示共用
*/
private Long projectId;
}

View File

@ -0,0 +1,37 @@
package org.dromara.progress.domain.dto.progresscategorytemplate;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/5/22 16:07
*/
@Data
public class PgsProgressCategoryTemplateQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = 2607953543340685175L;
/**
* 父类别id
*/
private Long pid;
/**
* 类别名称
*/
private String name;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
/**
* 项目id0表示共用
*/
private Long projectId;
}

View File

@ -0,0 +1,38 @@
package org.dromara.progress.domain.dto.progresscategorytemplate;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/5/22 16:07
*/
@Data
public class PgsProgressCategoryTemplateUpdateReq implements Serializable {
@Serial
private static final long serialVersionUID = 8324950385975719302L;
/**
* 主键id
*/
private Long id;
/**
* 父类别id
*/
private Long pid;
/**
* 类别名称
*/
private String name;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
}

View File

@ -0,0 +1,26 @@
package org.dromara.progress.domain.enums;
import lombok.Getter;
/**
* @author lcj
* @date 2025/5/26 19:07
*/
@Getter
public enum PgsProgressUnitTypeEnum {
NULL("", "0"),
NUMBER("数量", "1"),
PERCENTAGE("百分比", "2");
private final String text;
private final String value;
PgsProgressUnitTypeEnum(String text, String value) {
this.text = text;
this.value = value;
}
}

View File

@ -1,22 +1,25 @@
package org.dromara.progress.domain.vo.progresscategory;
import org.dromara.progress.domain.PgsProgressCategory;
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 com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.common.json.handler.BigDecimalToIntegerSerializer;
import org.dromara.progress.domain.PgsProgressCategory;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 进度类别视图对象 pgs_progress_category
*
* @author lcj
* @date 2025-05-22
* @date 2025-05-26
*/
@Data
@ExcelIgnoreUnannotated
@ -38,6 +41,17 @@ public class PgsProgressCategoryVo implements Serializable {
@ExcelProperty(value = "父类别id")
private Long pid;
/**
* 项目id
*/
@ExcelProperty(value = "项目id")
private Long projectId;
/**
* 方阵id
*/
private Long matrixId;
/**
* 类别名称
*/
@ -48,14 +62,42 @@ public class PgsProgressCategoryVo implements Serializable {
* 计量方式0无 1数量 2百分比
*/
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=数量,2=百分比")
@ExcelDictFormat(readConverterExp = "0=无,1=数量,2=百分比")
private String unitType;
/**
* 项目id0表示共用
* 总数量/百分比
*/
@ExcelProperty(value = "项目id")
private Long projectId;
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
@ExcelProperty(value = "总数量/百分比")
private BigDecimal total;
/**
* 已完成数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
@ExcelProperty(value = "已完成数量/百分比")
private BigDecimal completed;
/**
* 计划总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
@ExcelProperty(value = "计划总数量/百分比")
private BigDecimal planTotal;
/**
* 是否超期0否 1是
*/
@ExcelProperty(value = "是否超期", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=否,1=是")
private String isDelay;
/**
* 完成状态0未开始 1进行中 2已完成
*/
@ExcelProperty(value = "完成状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=未开始,1=进行中,2=已完成")
private String status;
}

View File

@ -0,0 +1,61 @@
package org.dromara.progress.domain.vo.progresscategorytemplate;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.progress.domain.PgsProgressCategoryTemplate;
import java.io.Serial;
import java.io.Serializable;
/**
* 进度类别模版视图对象 pgs_progress_category_template
*
* @author lcj
* @date 2025-05-22
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = PgsProgressCategoryTemplate.class)
public class PgsProgressCategoryTemplateVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ExcelProperty(value = "主键id")
private Long id;
/**
* 父类别id
*/
@ExcelProperty(value = "父类别id")
private Long pid;
/**
* 类别名称
*/
@ExcelProperty(value = "类别名称")
private String name;
/**
* 计量方式0无 1数量 2百分比
*/
@ExcelProperty(value = "计量方式", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "1=数量,2=百分比")
private String unitType;
/**
* 项目id0表示共用
*/
@ExcelProperty(value = "项目id")
private Long projectId;
}

View File

@ -8,7 +8,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
* 进度类别Mapper接口
*
* @author lcj
* @date 2025-05-22
* @date 2025-05-26
*/
public interface PgsProgressCategoryMapper extends BaseMapperPlus<PgsProgressCategory, PgsProgressCategoryVo> {

View File

@ -0,0 +1,15 @@
package org.dromara.progress.mapper;
import org.dromara.progress.domain.PgsProgressCategoryTemplate;
import org.dromara.progress.domain.vo.progresscategorytemplate.PgsProgressCategoryTemplateVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 进度类别Mapper接口
*
* @author lcj
* @date 2025-05-22
*/
public interface PgsProgressCategoryTemplateMapper extends BaseMapperPlus<PgsProgressCategoryTemplate, PgsProgressCategoryTemplateVo> {
}

View File

@ -18,7 +18,7 @@ import java.util.List;
* 进度类别Service接口
*
* @author lcj
* @date 2025-05-22
* @date 2025-05-26
*/
public interface IPgsProgressCategoryService extends IService<PgsProgressCategory> {
@ -96,4 +96,12 @@ public interface IPgsProgressCategoryService extends IService<PgsProgressCategor
*/
Page<PgsProgressCategoryVo> getVoPage(Page<PgsProgressCategory> progressCategoryPage);
/**
* 根据模板创建进度类别
*
* @param projectId 项目id
* @param matrixIds 方阵id列表
* @return 是否创建成功
*/
Boolean insertByTemplate(Long projectId, List<Long> matrixIds);
}

View File

@ -0,0 +1,99 @@
package org.dromara.progress.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.progress.domain.PgsProgressCategoryTemplate;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateCreateReq;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateQueryReq;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateUpdateReq;
import org.dromara.progress.domain.vo.progresscategorytemplate.PgsProgressCategoryTemplateVo;
import java.util.Collection;
import java.util.List;
/**
* 进度类别模版Service接口
*
* @author lcj
* @date 2025-05-22
*/
public interface IPgsProgressCategoryTemplateService extends IService<PgsProgressCategoryTemplate> {
/**
* 查询进度类别模版
*
* @param id 主键
* @return 进度类别模版
*/
PgsProgressCategoryTemplateVo queryById(Long id);
/**
* 分页查询进度类别模版
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 进度类别模版分页列表
*/
TableDataInfo<PgsProgressCategoryTemplateVo> queryPageList(PgsProgressCategoryTemplateQueryReq req, PageQuery pageQuery);
/**
* 查询符合条件的进度类别模版列表
*
* @param req 查询条件
* @return 进度类别模版列表
*/
List<PgsProgressCategoryTemplateVo> queryList(PgsProgressCategoryTemplateQueryReq req);
/**
* 新增进度类别模版
*
* @param req 进度类别模版
* @return 新增进度类别模版id
*/
Long insertByBo(PgsProgressCategoryTemplateCreateReq req);
/**
* 修改进度类别模版
*
* @param req 进度类别模版
* @return 是否修改成功
*/
Boolean updateByBo(PgsProgressCategoryTemplateUpdateReq req);
/**
* 校验并批量删除进度类别模版信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 获取进度类别模版视图对象
*
* @param progressCategoryTemplate 进度类别模版对象
* @return 进度类别模版视图对象
*/
PgsProgressCategoryTemplateVo getVo(PgsProgressCategoryTemplate progressCategoryTemplate);
/**
* 获取进度类别模版查询条件封装
*
* @param req 查询条件
* @return 查询条件封装
*/
LambdaQueryWrapper<PgsProgressCategoryTemplate> buildQueryWrapper(PgsProgressCategoryTemplateQueryReq req);
/**
* 获取进度类别模版分页对象视图
*
* @param progressCategoryTemplatePage 进度类别模版分页对象
* @return 进度类别模版分页对象视图
*/
Page<PgsProgressCategoryTemplateVo> getVoPage(Page<PgsProgressCategoryTemplate> progressCategoryTemplatePage);
}

View File

@ -2,40 +2,52 @@ package org.dromara.progress.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
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 org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
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.facility.domain.FacPercentageFacility;
import org.dromara.facility.service.IFacPercentageFacilityService;
import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.PgsProgressCategoryTemplate;
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryCreateReq;
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryQueryReq;
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryUpdateReq;
import org.dromara.progress.domain.enums.PgsProgressUnitTypeEnum;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import org.dromara.progress.mapper.PgsProgressCategoryMapper;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.progress.service.IPgsProgressCategoryTemplateService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.math.BigDecimal;
import java.util.*;
/**
* 进度类别Service业务层处理
*
* @author lcj
* @date 2025-05-22
* @date 2025-05-26
*/
@Service
public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCategoryMapper, PgsProgressCategory>
implements IPgsProgressCategoryService {
@Resource
private IPgsProgressCategoryTemplateService pgsProgressCategoryTemplateService;
@Resource
private IFacPercentageFacilityService percentageFacilityService;
/**
* 查询进度类别
*
@ -199,16 +211,12 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
if (req == null) {
return lqw;
}
Long pid = req.getPid();
String name = req.getName();
String unitType = req.getUnitType();
Long projectId = req.getProjectId();
// 模糊查询
lqw.like(StringUtils.isNotBlank(name), PgsProgressCategory::getName, name);
Long matrixId = req.getMatrixId();
// 精确查询
lqw.in(ObjectUtils.isNotEmpty(projectId), PgsProgressCategory::getProjectId, projectId, PgsProgressCategoryConstant.PUBLIC_PROJECT_ID);
lqw.eq(StringUtils.isNotBlank(unitType), PgsProgressCategory::getUnitType, unitType);
lqw.eq(ObjectUtils.isNotEmpty(pid), PgsProgressCategory::getPid, pid);
lqw.in(ObjectUtils.isNotEmpty(projectId), PgsProgressCategory::getProjectId, projectId);
lqw.eq(ObjectUtils.isNotEmpty(matrixId), PgsProgressCategory::getMatrixId, matrixId);
lqw.orderByAsc(PgsProgressCategory::getWorkType);
return lqw;
}
@ -235,4 +243,74 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
progressCategoryVoPage.setRecords(progressCategoryVoList);
return progressCategoryVoPage;
}
/**
* 根据模板创建进度类别
*
* @param projectId 项目id
* @param matrixIds 方阵id列表
* @return 是否创建成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByTemplate(Long projectId, List<Long> matrixIds) {
// 获取模板进度类别
List<PgsProgressCategoryTemplate> categoryTemplateList = pgsProgressCategoryTemplateService.lambdaQuery()
.in(PgsProgressCategoryTemplate::getProjectId, projectId, PgsProgressCategoryConstant.PUBLIC_PROJECT_ID)
.list();
// 遍历模板进度类别,复制数据
if (CollUtil.isEmpty(categoryTemplateList)) {
throw new ServiceException("对应模板进度类别不存在", HttpStatus.NOT_FOUND);
}
List<PgsProgressCategory> newList = new ArrayList<>();
List<FacPercentageFacility> percentageFacilityList = new ArrayList<>();
for (Long matrixId : matrixIds) {
// 每个 matrixId 对应一套新的 ID 映射
Map<Long, Long> localIdMap = new HashMap<>(); // templateId -> newId
List<PgsProgressCategory> localList = new ArrayList<>();
for (PgsProgressCategoryTemplate template : categoryTemplateList) {
Long newId = IdWorker.getId();
localIdMap.put(template.getId(), newId);
PgsProgressCategory newCategory = new PgsProgressCategory();
newCategory.setId(newId);
newCategory.setName(template.getName());
newCategory.setUnitType(template.getUnitType());
newCategory.setWorkType(template.getWorkType());
newCategory.setProjectId(projectId);
newCategory.setMatrixId(matrixId);
newCategory.setPid(template.getPid()); // 先临时设置旧 pid
localList.add(newCategory);
// 创建百分比设施
if (template.getPid() != 0 && template.getUnitType().equals(PgsProgressUnitTypeEnum.PERCENTAGE.getValue())) {
newCategory.setTotal(BigDecimal.valueOf(100));
FacPercentageFacility percentageFacility = new FacPercentageFacility();
percentageFacility.setProjectId(projectId);
percentageFacility.setMatrixId(matrixId);
percentageFacility.setProgressCategoryId(newId);
percentageFacility.setProgressCategoryName(template.getName());
percentageFacilityList.add(percentageFacility);
}
}
// 修正本 matrix 的 pid
for (PgsProgressCategory category : localList) {
Long oldPid = category.getPid();
if (oldPid != 0) {
category.setPid(localIdMap.getOrDefault(oldPid, 0L));
}
}
newList.addAll(localList);
}
boolean result = this.saveBatch(newList);
if (!result) {
throw new ServiceException("创建进度类别失败", HttpStatus.ERROR);
}
// 保存百分比设施
if (CollUtil.isNotEmpty(percentageFacilityList)) {
boolean save = percentageFacilityService.saveBatch(percentageFacilityList);
if (!save) {
throw new ServiceException("创建设施失败", HttpStatus.ERROR);
}
}
return true;
}
}

View File

@ -0,0 +1,238 @@
package org.dromara.progress.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 org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
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.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategoryTemplate;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateCreateReq;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateQueryReq;
import org.dromara.progress.domain.dto.progresscategorytemplate.PgsProgressCategoryTemplateUpdateReq;
import org.dromara.progress.domain.vo.progresscategorytemplate.PgsProgressCategoryTemplateVo;
import org.dromara.progress.mapper.PgsProgressCategoryTemplateMapper;
import org.dromara.progress.service.IPgsProgressCategoryTemplateService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
/**
* 进度类别模版Service业务层处理
*
* @author lcj
* @date 2025-05-22
*/
@Service
public class PgsProgressCategoryTemplateServiceImpl extends ServiceImpl<PgsProgressCategoryTemplateMapper, PgsProgressCategoryTemplate>
implements IPgsProgressCategoryTemplateService {
/**
* 查询进度类别模版
*
* @param id 主键
* @return 进度类别模版
*/
@Override
public PgsProgressCategoryTemplateVo queryById(Long id) {
PgsProgressCategoryTemplate progressCategoryTemplate = this.getById(id);
if (progressCategoryTemplate == null) {
throw new ServiceException("进度类别模版信息不存在", HttpStatus.NOT_FOUND);
}
return this.getVo(progressCategoryTemplate);
}
/**
* 分页查询进度类别模版
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 进度类别模版分页列表
*/
@Override
public TableDataInfo<PgsProgressCategoryTemplateVo> queryPageList(PgsProgressCategoryTemplateQueryReq req, PageQuery pageQuery) {
Page<PgsProgressCategoryTemplate> progressCategoryTemplatePage = this.page(pageQuery.build(), this.buildQueryWrapper(req));
return TableDataInfo.build(this.getVoPage(progressCategoryTemplatePage));
}
/**
* 查询符合条件的进度类别模版列表
*
* @param req 查询条件
* @return 进度类别模版列表
*/
@Override
public List<PgsProgressCategoryTemplateVo> queryList(PgsProgressCategoryTemplateQueryReq req) {
List<PgsProgressCategoryTemplate> list = this.list(this.buildQueryWrapper(req));
return list.stream().map(this::getVo).toList();
}
/**
* 新增进度类别模版
*
* @param req 进度类别模版
* @return 新增进度类别模版id
*/
@Override
public Long insertByBo(PgsProgressCategoryTemplateCreateReq req) {
// 将实体类和 DTO 进行转换
PgsProgressCategoryTemplate progressCategoryTemplate = new PgsProgressCategoryTemplate();
BeanUtils.copyProperties(req, progressCategoryTemplate);
// 数据校验
validEntityBeforeSave(progressCategoryTemplate);
// 写入数据库
boolean result = this.save(progressCategoryTemplate);
if (!result) {
throw new ServiceException("新增进度类别模版失败,数据库异常", HttpStatus.ERROR);
}
return progressCategoryTemplate.getId();
}
/**
* 修改进度类别模版
*
* @param req 进度类别模版
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(PgsProgressCategoryTemplateUpdateReq req) {
// 将实体类和 DTO 进行转换
PgsProgressCategoryTemplate progressCategoryTemplate = new PgsProgressCategoryTemplate();
BeanUtils.copyProperties(req, progressCategoryTemplate);
PgsProgressCategoryTemplate oldProgressCategoryTemplate = this.getById(req.getId());
if (oldProgressCategoryTemplate == null) {
throw new ServiceException("修改进度类别模版失败,数据不存在", HttpStatus.NOT_FOUND);
}
// 数据校验
validEntityBeforeSave(progressCategoryTemplate);
// 写入数据库
boolean result = this.updateById(progressCategoryTemplate);
if (!result) {
throw new ServiceException("更新进度类别模版失败,数据库异常", HttpStatus.ERROR);
}
return true;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(PgsProgressCategoryTemplate entity) {
// TODO 做一些数据校验,如唯一约束
Long projectId = entity.getProjectId();
Long pid = entity.getPid();
if (projectId != null && projectId != 0) {
if (this.getById(projectId) == null) {
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
}
}
if (pid != null && pid != 0) {
if (this.getById(pid) == null) {
throw new ServiceException("对应进度类别模版不存在", HttpStatus.NOT_FOUND);
}
}
// 名称唯一性校验
LambdaQueryWrapper<PgsProgressCategoryTemplate> lqw = new LambdaQueryWrapper<>();
lqw.eq(PgsProgressCategoryTemplate::getName, entity.getName());
if (projectId != null && projectId != 0) {
lqw.eq(PgsProgressCategoryTemplate::getProjectId, entity.getProjectId());
}
if (pid != null && pid != 0) {
lqw.eq(PgsProgressCategoryTemplate::getPid, entity.getPid());
}
if (entity.getId() != null) {
// 排除自身
lqw.ne(PgsProgressCategoryTemplate::getId, entity.getId());
}
if (this.count(lqw) > 0) {
throw new ServiceException("已有同名进度类别模版", HttpStatus.CONFLICT);
}
}
/**
* 校验并批量删除进度类别模版信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
return this.removeBatchByIds(ids);
}
/**
* 获取进度类别模版视图对象
*
* @param progressCategoryTemplate 进度类别模版对象
* @return 进度类别模版视图对象
*/
@Override
public PgsProgressCategoryTemplateVo getVo(PgsProgressCategoryTemplate progressCategoryTemplate) {
if (progressCategoryTemplate == null) {
return null;
}
// 对象转封装类
PgsProgressCategoryTemplateVo progressCategoryTemplateVo = new PgsProgressCategoryTemplateVo();
BeanUtils.copyProperties(progressCategoryTemplate, progressCategoryTemplateVo);
return progressCategoryTemplateVo;
}
/**
* 获取进度类别模版查询条件封装
*
* @param req 查询条件
* @return 查询条件封装
*/
@Override
public LambdaQueryWrapper<PgsProgressCategoryTemplate> buildQueryWrapper(PgsProgressCategoryTemplateQueryReq req) {
LambdaQueryWrapper<PgsProgressCategoryTemplate> lqw = Wrappers.lambdaQuery();
if (req == null) {
return lqw;
}
Long pid = req.getPid();
String name = req.getName();
String unitType = req.getUnitType();
Long projectId = req.getProjectId();
// 模糊查询
lqw.like(StringUtils.isNotBlank(name), PgsProgressCategoryTemplate::getName, name);
// 精确查询
lqw.in(ObjectUtils.isNotEmpty(projectId), PgsProgressCategoryTemplate::getProjectId, projectId, PgsProgressCategoryConstant.PUBLIC_PROJECT_ID);
lqw.eq(StringUtils.isNotBlank(unitType), PgsProgressCategoryTemplate::getUnitType, unitType);
lqw.eq(ObjectUtils.isNotEmpty(pid), PgsProgressCategoryTemplate::getPid, pid);
return lqw;
}
/**
* 获取进度类别模版分页对象视图
*
* @param progressCategoryTemplatePage 进度类别模版分页对象
* @return 进度类别模版分页对象视图
*/
@Override
public Page<PgsProgressCategoryTemplateVo> getVoPage(Page<PgsProgressCategoryTemplate> progressCategoryTemplatePage) {
List<PgsProgressCategoryTemplate> progressCategoryTemplateList = progressCategoryTemplatePage.getRecords();
Page<PgsProgressCategoryTemplateVo> progressCategoryTemplateVoPage = new Page<>(progressCategoryTemplatePage.getCurrent(), progressCategoryTemplatePage.getSize(), progressCategoryTemplatePage.getTotal());
if (CollUtil.isEmpty(progressCategoryTemplateList)) {
return progressCategoryTemplateVoPage;
}
// 对象列表 => 封装对象列表
List<PgsProgressCategoryTemplateVo> progressCategoryTemplateVoList = progressCategoryTemplateList.stream().map(progressCategoryTemplate -> {
// 对象转封装类
PgsProgressCategoryTemplateVo progressCategoryTemplateVo = new PgsProgressCategoryTemplateVo();
BeanUtils.copyProperties(progressCategoryTemplate, progressCategoryTemplateVo);
return progressCategoryTemplateVo;
}).toList();
progressCategoryTemplateVoPage.setRecords(progressCategoryTemplateVoList);
return progressCategoryTemplateVoPage;
}
}

View File

@ -17,6 +17,8 @@ import java.util.stream.Collectors;
*/
public class JSTUtils {
private static final GeometryFactory geometryFactory = new GeometryFactory();
/**
* 获取最近点的名称
*
@ -25,7 +27,6 @@ public class JSTUtils {
* @return 最近点的名称
*/
public static String findNearestText(List<Double> target, List<FacFeatureByPoint> nameGeoJson) {
GeometryFactory geometryFactory = new GeometryFactory();
Point targetPoint = geometryFactory.createPoint(new Coordinate(target.get(0), target.get(1)));
FacFeatureByPoint nearestFeature = null;
double minDistance = Double.MAX_VALUE;
@ -55,7 +56,6 @@ public class JSTUtils {
* @return 点是否在平面内
*/
public static Boolean pointIsWithInPlane(List<List<Double>> planeLists, List<Double> pointList) {
GeometryFactory geometryFactory = new GeometryFactory();
// 构建平面
Coordinate[] coordinates = getPlaneCoordinate(planeLists);
Polygon polygon = geometryFactory.createPolygon(coordinates);
@ -73,7 +73,6 @@ public class JSTUtils {
* @return 平面内点坐标列表集合
*/
public static List<List<Double>> getPointInPlaneList(List<List<Double>> planeLists, List<List<Double>> pointLists) {
GeometryFactory geometryFactory = new GeometryFactory();
// 构建平面
Coordinate[] coordinates = getPlaneCoordinate(planeLists);
LinearRing shell = geometryFactory.createLinearRing(coordinates);
@ -95,7 +94,6 @@ public class JSTUtils {
* @return 平面是否在平面内
*/
public static Boolean planeIsWithInPlane(List<List<Double>> referencePlane, List<List<Double>> comparePlane) {
GeometryFactory geometryFactory = new GeometryFactory();
// 构建参考平面
Coordinate[] referenceCoordinates = getPlaneCoordinate(referencePlane);
Polygon referencePolygon = geometryFactory.createPolygon(referenceCoordinates);
@ -106,6 +104,28 @@ public class JSTUtils {
return referencePolygon.contains(comparePolygon);
}
/**
* 判断两个平面是否相交
*
* @param referencePlane 参考平面
* @param comparePlane 待比较平面
* @return 平面是否相交
*/
public static Boolean arePolygonsIntersecting(List<List<Double>> referencePlane, List<List<Double>> comparePlane) {
// 构建 Polygon A参考面
Coordinate[] coordsA = referencePlane.stream()
.map(p -> new Coordinate(p.getFirst(), p.get(1)))
.toArray(Coordinate[]::new);
Polygon polygonA = geometryFactory.createPolygon(coordsA);
// 构建 Polygon B比较面
Coordinate[] coordsB = comparePlane.stream()
.map(p -> new Coordinate(p.getFirst(), p.get(1)))
.toArray(Coordinate[]::new);
Polygon polygonB = geometryFactory.createPolygon(coordsB);
// 使用 JTS 判断是否相交
return polygonA.intersects(polygonB);
}
/**
* 获取平面坐标数组
*
@ -149,4 +169,40 @@ public class JSTUtils {
};
}
/**
* 匹配最近的点,获取该点的名称
*
* @param polygon 平面
* @param points 点列表集合
* @return 最近点的名称
*/
public static String findNearestPointText(List<List<Double>> polygon, List<FacFeatureByPoint> points) {
if (polygon == null || polygon.size() < 3 || points == null || points.isEmpty()) {
return null;
}
// 1. 构建 Polygon
Coordinate[] polygonCoords = polygon.stream()
.map(coord -> new Coordinate(coord.getFirst(), coord.get(1)))
.toArray(Coordinate[]::new);
Polygon jtsPolygon = geometryFactory.createPolygon(polygonCoords);
// 2. 查找最近点
FacFeatureByPoint nearestFeature = null;
double minDistance = Double.MAX_VALUE;
for (FacFeatureByPoint feature : points) {
List<Double> coords = feature.getGeometry().getCoordinates();
if (coords == null || coords.size() != 2) continue;
Point point = geometryFactory.createPoint(new Coordinate(coords.get(0), coords.get(1)));
double distance = point.distance(jtsPolygon);
if (distance < minDistance) {
minDistance = distance;
nearestFeature = feature;
}
}
// 3. 返回最近点的 text
if (nearestFeature != null && nearestFeature.getProperties() != null) {
return nearestFeature.getProperties().getText();
}
return null;
}
}

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.facility.mapper.FacPercentageFacilityMapper">
</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.progress.mapper.PgsProgressCategoryTemplateMapper">
</mapper>

View File

@ -958,17 +958,61 @@ CREATE TABLE `bus_project_news`
INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id'
) comment = '项目新闻' COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `pgs_progress_category`;
CREATE TABLE `pgs_progress_category`
DROP TABLE IF EXISTS `pgs_progress_category_template`;
CREATE TABLE `pgs_progress_category_template`
(
`id` bigint not null auto_increment comment '主键id',
`pid` bigint default 0 not null comment '父类别id',
`pid` bigint default '0' not null comment '父类别id',
`name` varchar(64) not null comment '类别名称',
`unit_type` char(1) not null comment '计量方式0无 1数量 2百分比',
`project_id` bigint default 0 not null comment '项目id0表示共用',
`project_id` bigint default '0' not null comment '项目id0表示共用',
`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_pid` (`pid` ASC) USING BTREE comment '父类别id',
INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id'
) comment ='进度类别'
) comment ='进度类别模版' COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `pgs_progress_category`;
CREATE TABLE `pgs_progress_category`
(
`id` bigint not null auto_increment comment '主键id',
`pid` bigint default '0' not null comment '父类别id',
`project_id` bigint not null comment '项目id',
`matrix_id` bigint not null comment '方阵id',
`name` varchar(64) not null comment '类别名称',
`unit_type` char(1) not null comment '计量方式0无 1数量 2百分比',
`total` decimal(10, 2) null comment '总数量/百分比',
`completed` decimal(10, 2) null comment '已完成数量/百分比',
`plan_total` decimal(10, 2) null comment '计划总数量/百分比',
`is_delay` char(1) default '0' not null comment '是否超期0否 1是',
`status` char(1) default '0' not null comment '完成状态0未开始 1进行中 2已完成',
`create_by` varchar(64) null comment '创建者',
`update_by` varchar(64) null comment '更新者',
`create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间',
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
`deleted_at` datetime null comment '删除时间',
`is_delete` tinyint(4) default 0 not null comment '是否删除0正常 1删除',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_pid` (`pid` ASC) USING BTREE comment '父类别id',
INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE comment '方阵id',
INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id'
) comment ='进度类别' COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `fac_percentage_facility`;
CREATE TABLE `fac_percentage_facility`
(
`id` bigint not null auto_increment comment '主键id',
`project_id` bigint not null comment '项目id',
`matrix_id` bigint not null comment '方阵id',
`progress_category_id` bigint null comment '进度类型id',
`progress_category_name` varchar(64) null comment '进度类别名称',
`create_by` varchar(64) null comment '创建者',
`update_by` varchar(64) 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_project_id` (`project_id` ASC) USING BTREE comment '项目id',
INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE comment '方阵id',
INDEX `idx_progress_category_id` (`progress_category_id` ASC) USING BTREE comment '进度类别id'
) comment ='设施-百分比设施' COLLATE = utf8mb4_unicode_ci;