[update] 修改项目列表和进度计划相关逻辑

This commit is contained in:
lcj
2025-06-06 19:52:34 +08:00
parent e67d555685
commit 5bb201b272
26 changed files with 694 additions and 94 deletions

View File

@ -90,7 +90,7 @@
<id>prod</id> <id>prod</id>
<properties> <properties>
<profiles.active>prod</profiles.active> <profiles.active>prod</profiles.active>
<logging.level>warn</logging.level> <logging.level>info</logging.level>
<monitor.username>ruoyi</monitor.username> <monitor.username>ruoyi</monitor.username>
<monitor.password>123456</monitor.password> <monitor.password>123456</monitor.password>
</properties> </properties>

View File

@ -269,3 +269,6 @@ weather:
project-id: 2JTHPUQ5YY project-id: 2JTHPUQ5YY
private-key: MC4CAQAwBQYDK2VwBCIEIMAglX7IsxYiTeM+FXXnvCUsIggajeP4s8gAllewm6BN private-key: MC4CAQAwBQYDK2VwBCIEIMAglX7IsxYiTeM+FXXnvCUsIggajeP4s8gAllewm6BN
api-host: n35rk53njv.re.qweatherapi.com api-host: n35rk53njv.re.qweatherapi.com
# dxf转 geojson 执行文件名
dxf2GeoJson:
file-name: main.exe

View File

@ -52,35 +52,35 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://mysql:3306/xinnengyuan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true url: jdbc:mysql://192.168.110.2:13386/xinnengyuan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root username: xinnengyuan
password: 123456 password: caJWNthNFaNRpRNy
# # 从库数据源 # # 从库数据源
# slave: # slave:
# lazy: true # lazy: true
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver # driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username: # username:
# password: # password:
# oracle: # oracle:
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver # driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE # url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT # username: ROOT
# password: root # password: root
# postgres: # postgres:
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver # driverClassName: org.postgresql.Driver
# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
# username: root # username: root
# password: root # password: root
# sqlserver: # sqlserver:
# type: ${spring.datasource.type} # type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver # driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true # url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA # username: SA
# password: root # password: root
hikari: hikari:
# 最大连接池数量 # 最大连接池数量
maxPoolSize: 20 maxPoolSize: 20
@ -101,13 +101,13 @@ spring:
spring.data: spring.data:
redis: redis:
# 地址 # 地址
host: redis host: 192.168.110.2
# 端口默认为6379 # 端口默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 3 database: 1
# redis 密码必须配置 # redis 密码必须配置
password: 123456 password: HMASKEbyhaASPZXB
# 连接超时时间 # 连接超时时间
timeout: 10s timeout: 10s
# 是否开启ssl # 是否开启ssl
@ -265,3 +265,12 @@ justauth:
client-id: 10**********6 client-id: 10**********6
client-secret: 1f7d08**********5b7**********29e client-secret: 1f7d08**********5b7**********29e
redirect-uri: ${justauth.address}/social-callback?source=gitlab redirect-uri: ${justauth.address}/social-callback?source=gitlab
# 和风天气 https://dev.qweather.com/
weather:
key-id: T65EAABUXC
project-id: 2JTHPUQ5YY
private-key: MC4CAQAwBQYDK2VwBCIEIMAglX7IsxYiTeM+FXXnvCUsIggajeP4s8gAllewm6BN
api-host: n35rk53njv.re.qweatherapi.com
# dxf转 geojson 执行文件名
dxf2GeoJson:
file-name: main

View File

@ -76,7 +76,7 @@ spring:
servlet: servlet:
multipart: multipart:
# 单个文件大小 # 单个文件大小
max-file-size: 100MB max-file-size: 200MB
# 设置总上传的文件大小 # 设置总上传的文件大小
max-request-size: 200MB max-request-size: 200MB
mvc: mvc:

View File

@ -37,7 +37,10 @@ public class IncSyncDeleteProjectCache {
} }
// 批量删除 // 批量删除
if (!keysToDelete.isEmpty()) { if (!keysToDelete.isEmpty()) {
log.info("清理项目缓存,共 {} 条:{}", keysToDelete.size(), keysToDelete);
stringRedisTemplate.delete(keysToDelete); stringRedisTemplate.delete(keysToDelete);
} else {
log.info("没有需要清理的项目缓存");
} }
} }
} }

View File

@ -18,6 +18,7 @@ import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryQuery
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryUpdateReq; import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryUpdateReq;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryCoordinateVo; import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryCoordinateVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryLastTimeVo; import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryLastTimeVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryProjectVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo; import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import org.dromara.progress.service.IPgsProgressCategoryService; import org.dromara.progress.service.IPgsProgressCategoryService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -84,6 +85,18 @@ public class PgsProgressCategoryController extends BaseController {
return R.ok(pgsProgressCategoryService.getCoordinate(id)); return R.ok(pgsProgressCategoryService.getCoordinate(id));
} }
/**
* 获取项目总的进度信息
*
* @param projectId 项目主键
*/
@SaCheckPermission("progress:progressCategory:query")
@GetMapping("/project/number/{projectId}")
public R<PgsProgressCategoryProjectVo> getProjectNumber(@NotNull(message = "项目主键不能为空")
@PathVariable Long projectId) {
return R.ok(pgsProgressCategoryService.getProjectNumber(projectId));
}
/** /**
* 获取进度类别最后一次进度信息 * 获取进度类别最后一次进度信息
* *

View File

@ -0,0 +1,60 @@
package org.dromara.progress.domain.vo.progresscategory;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.dromara.common.json.handler.BigDecimalToIntegerSerializer;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lcj
* @date 2025/6/5 15:41
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PgsProgressCategoryMatrixVo implements Serializable {
@Serial
private static final long serialVersionUID = 3061735290740592145L;
/**
* 方阵id
*/
private Long matrixId;
/**
* 总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal total;
/**
* 已完成数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal completed;
/**
* 计划总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal planTotal;
/**
* 已完成数量百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal completedPercentage;
/**
* 计划中数量百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal planTotalPercentage;
}

View File

@ -0,0 +1,62 @@
package org.dromara.progress.domain.vo.progresscategory;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import org.dromara.common.json.handler.BigDecimalToIntegerSerializer;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author lcj
* @date 2025/6/5 15:36
*/
@Data
public class PgsProgressCategoryProjectVo implements Serializable {
@Serial
private static final long serialVersionUID = -8208751933207899365L;
/**
* 项目id
*/
private Long projectId;
/**
* 总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal total;
/**
* 已完成数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal completed;
/**
* 计划总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal planTotal;
/**
* 已完成数量百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal completedPercentage;
/**
* 计划中数量百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal planTotalPercentage;
/**
* 子项目列表
*/
private List<PgsProgressCategorySubProjectVo> children;
}

View File

@ -0,0 +1,66 @@
package org.dromara.progress.domain.vo.progresscategory;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.dromara.common.json.handler.BigDecimalToIntegerSerializer;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author lcj
* @date 2025/6/5 15:39
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PgsProgressCategorySubProjectVo implements Serializable {
@Serial
private static final long serialVersionUID = 7523695525881518366L;
/**
* 子项目id
*/
private Long subProjectId;
/**
* 总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal total;
/**
* 已完成数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal completed;
/**
* 计划总数量/百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal planTotal;
/**
* 已完成数量百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal completedPercentage;
/**
* 计划中数量百分比
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal planTotalPercentage;
/**
* 方阵列表
*/
private List<PgsProgressCategoryMatrixVo> children;
}

View File

@ -1,11 +1,15 @@
package org.dromara.progress.domain.vo.progressplandetail; package org.dromara.progress.domain.vo.progressplandetail;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.json.handler.BigDecimalToIntegerSerializer;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* @author lcj * @author lcj
@ -27,4 +31,15 @@ public class PgsProgressPlanDetailDateVo {
@JsonFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd")
private Date date; private Date date;
/**
* 已完成数量
*/
@JsonSerialize(using = BigDecimalToIntegerSerializer.class)
private BigDecimal finishedNumber;
/**
* 完成详情
*/
private List<PgsProgressPlanDetailFinishedVo> finishedDetail;
} }

View File

@ -8,6 +8,7 @@ import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryQuery
import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryUpdateReq; import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryUpdateReq;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryCoordinateVo; import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryCoordinateVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryLastTimeVo; import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryLastTimeVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryProjectVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo; import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import java.util.Collection; import java.util.Collection;
@ -111,4 +112,12 @@ public interface IPgsProgressCategoryService extends IService<PgsProgressCategor
*/ */
PgsProgressCategoryCoordinateVo getCoordinate(Long id); PgsProgressCategoryCoordinateVo getCoordinate(Long id);
/**
* 根据项目id获取项目进度类别数量信息
*
* @param projectId 项目id
* @return 项目进度类别数量信息
*/
PgsProgressCategoryProjectVo getProjectNumber(Long projectId);
} }

View File

@ -11,14 +11,9 @@ import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.facility.domain.FacBoxTransformer; import org.dromara.common.core.utils.StringUtils;
import org.dromara.facility.domain.FacInverter; import org.dromara.facility.domain.*;
import org.dromara.facility.domain.FacPercentageFacility; import org.dromara.facility.service.*;
import org.dromara.facility.domain.FacPhotovoltaicPanel;
import org.dromara.facility.service.IFacBoxTransformerService;
import org.dromara.facility.service.IFacInverterService;
import org.dromara.facility.service.IFacPercentageFacilityService;
import org.dromara.facility.service.IFacPhotovoltaicPanelService;
import org.dromara.progress.constant.PgsProgressCategoryConstant; import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory; import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.PgsProgressCategoryTemplate; import org.dromara.progress.domain.PgsProgressCategoryTemplate;
@ -30,16 +25,16 @@ import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryUpdat
import org.dromara.progress.domain.enums.PgsCoordinateTypeEnum; import org.dromara.progress.domain.enums.PgsCoordinateTypeEnum;
import org.dromara.progress.domain.enums.PgsFinishStatusEnum; import org.dromara.progress.domain.enums.PgsFinishStatusEnum;
import org.dromara.progress.domain.enums.PgsProgressUnitTypeEnum; import org.dromara.progress.domain.enums.PgsProgressUnitTypeEnum;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryCoordinateVo; import org.dromara.progress.domain.vo.progresscategory.*;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryFacilityVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryLastTimeVo;
import org.dromara.progress.domain.vo.progresscategory.PgsProgressCategoryVo;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailDateVo; import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailDateVo;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo;
import org.dromara.progress.mapper.PgsProgressCategoryMapper; import org.dromara.progress.mapper.PgsProgressCategoryMapper;
import org.dromara.progress.service.IPgsProgressCategoryService; import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.progress.service.IPgsProgressCategoryTemplateService; import org.dromara.progress.service.IPgsProgressCategoryTemplateService;
import org.dromara.progress.service.IPgsProgressPlanDetailService; import org.dromara.progress.service.IPgsProgressPlanDetailService;
import org.dromara.progress.service.IPgsProgressPlanService; import org.dromara.progress.service.IPgsProgressPlanService;
import org.dromara.project.domain.BusProject;
import org.dromara.project.service.IBusProjectService;
import org.dromara.utils.BigDecimalUtil; import org.dromara.utils.BigDecimalUtil;
import org.dromara.utils.JsonDimensionUtil; import org.dromara.utils.JsonDimensionUtil;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@ -88,6 +83,13 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
@Resource @Resource
private IFacInverterService inverterService; private IFacInverterService inverterService;
@Resource
private IBusProjectService projectService;
@Lazy
@Resource
private IFacMatrixService matrixService;
/** /**
* 查询进度类别 * 查询进度类别
* *
@ -465,18 +467,136 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
return coordinateVo; return coordinateVo;
} }
List<PgsProgressPlanDetailDateVo> detailList = progressPlanDetailService.lambdaQuery() List<PgsProgressPlanDetailDateVo> detailList = progressPlanDetailService.lambdaQuery()
.select(PgsProgressPlanDetail::getId, PgsProgressPlanDetail::getDate) .select(PgsProgressPlanDetail::getId,
PgsProgressPlanDetail::getDate,
PgsProgressPlanDetail::getFinishedNumber,
PgsProgressPlanDetail::getFinishedDetail)
.eq(PgsProgressPlanDetail::getProgressCategoryId, id) .eq(PgsProgressPlanDetail::getProgressCategoryId, id)
.orderByAsc(PgsProgressPlanDetail::getDate) .orderByAsc(PgsProgressPlanDetail::getDate)
.list() .list()
.stream().map(detail -> .stream().map(detail -> {
new PgsProgressPlanDetailDateVo(detail.getId(), detail.getDate())) PgsProgressPlanDetailDateVo detailDateVo = new PgsProgressPlanDetailDateVo();
.toList(); detailDateVo.setId(detail.getId());
detailDateVo.setDate(detail.getDate());
detailDateVo.setFinishedNumber(new BigDecimal(detail.getFinishedNumber()));
String finishedDetail = detail.getFinishedDetail();
if (StringUtils.isNotBlank(finishedDetail)) {
List<PgsProgressPlanDetailFinishedVo> finishedVoList = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class);
detailDateVo.setFinishedDetail(finishedVoList);
}
return detailDateVo;
}).toList();
coordinateVo.setDetailList(detailList); coordinateVo.setDetailList(detailList);
coordinateVo.setFacilityList(facilityList); coordinateVo.setFacilityList(facilityList);
return coordinateVo; return coordinateVo;
} }
/**
* 根据项目id获取项目进度类别数量信息
*
* @param projectId 项目id
* @return 项目进度类别数量信息
*/
@Override
public PgsProgressCategoryProjectVo getProjectNumber(Long projectId) {
// 获取项目信息
BusProject project = projectService.getById(projectId);
if (project == null) {
throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
}
// 获取子项目信息
List<BusProject> subProjectList = projectService.lambdaQuery()
.select(BusProject::getId)
.eq(BusProject::getPId, projectId)
.list();
if (CollUtil.isEmpty(subProjectList)) {
return null;
}
List<Long> subProjectIdList = subProjectList.stream().map(BusProject::getId).toList();
// 获取方阵信息
List<FacMatrix> matrixList = matrixService.lambdaQuery()
.select(FacMatrix::getId)
.in(FacMatrix::getProjectId, subProjectIdList)
.list();
if (CollUtil.isEmpty(matrixList)) {
return null;
}
List<Long> matrixIdList = matrixList.stream().map(FacMatrix::getId).toList();
// 分组projectId -> matrixList
Map<Long, List<FacMatrix>> matrixGroupByProject = matrixList.stream()
.collect(Collectors.groupingBy(FacMatrix::getProjectId));
// 获取每个方阵下的进度类别信息
List<PgsProgressCategory> progressCategoryList = this.lambdaQuery()
.select(PgsProgressCategory::getId, PgsProgressCategory::getStatus, PgsProgressCategory::getMatrixId)
.in(PgsProgressCategory::getMatrixId, matrixIdList)
.list();
// 分组matrixId -> categoryList
Map<Long, List<PgsProgressCategory>> categoryGroupByMatrix = progressCategoryList.
stream().collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId));
// 封装结果
List<PgsProgressCategorySubProjectVo> subProjectVoList = new ArrayList<>();
BigDecimal totalAll = BigDecimal.ZERO;
BigDecimal completedAll = BigDecimal.ZERO;
BigDecimal planTotalAll = BigDecimal.ZERO;
for (BusProject subProject : subProjectList) {
Long subProjectId = subProject.getId();
List<FacMatrix> subMatrices = matrixGroupByProject.get(subProjectId);
if (CollUtil.isEmpty(subMatrices)) {
continue;
}
List<PgsProgressCategoryMatrixVo> matrixVoList = new ArrayList<>();
BigDecimal total = BigDecimal.ZERO;
BigDecimal completed = BigDecimal.ZERO;
BigDecimal planTotal = BigDecimal.ZERO;
for (FacMatrix matrix : subMatrices) {
Long matrixId = matrix.getId();
List<PgsProgressCategory> categories = categoryGroupByMatrix.get(matrixId);
if (CollUtil.isEmpty(categories)) {
continue;
}
BigDecimal matrixTotal = categories.stream().map(PgsProgressCategory::getTotal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal matrixCompleted = categories.stream().map(PgsProgressCategory::getCompleted).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal matrixPlanTotal = categories.stream().map(PgsProgressCategory::getPlanTotal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
total = total.add(matrixTotal);
completed = completed.add(matrixCompleted);
planTotal = planTotal.add(matrixPlanTotal);
// 构建 matrixVo
PgsProgressCategoryMatrixVo matrixVo = new PgsProgressCategoryMatrixVo();
matrixVo.setMatrixId(matrixId);
matrixVo.setTotal(matrixTotal);
matrixVo.setCompleted(matrixCompleted);
matrixVo.setPlanTotal(matrixPlanTotal);
matrixVo.setCompletedPercentage(BigDecimalUtil.toPercentage(matrixCompleted, matrixTotal));
matrixVo.setPlanTotalPercentage(BigDecimalUtil.toPercentage(matrixPlanTotal, matrixTotal));
matrixVoList.add(matrixVo);
}
// 构建子项目VO
PgsProgressCategorySubProjectVo subProjectVo = new PgsProgressCategorySubProjectVo();
subProjectVo.setSubProjectId(subProjectId);
subProjectVo.setTotal(total);
subProjectVo.setCompleted(completed);
subProjectVo.setPlanTotal(planTotal);
subProjectVo.setCompletedPercentage(BigDecimalUtil.toPercentage(completed, total));
subProjectVo.setPlanTotalPercentage(BigDecimalUtil.toPercentage(planTotal, total));
subProjectVo.setChildren(matrixVoList);
// 累加总项目数据
totalAll = totalAll.add(total);
completedAll = completedAll.add(completed);
planTotalAll = planTotalAll.add(planTotal);
subProjectVoList.add(subProjectVo);
}
// 构建项目VO
PgsProgressCategoryProjectVo projectVo = new PgsProgressCategoryProjectVo();
projectVo.setProjectId(projectId);
projectVo.setTotal(totalAll);
projectVo.setCompleted(completedAll);
projectVo.setPlanTotal(planTotalAll);
projectVo.setCompletedPercentage(BigDecimalUtil.toPercentage(completedAll, totalAll));
projectVo.setPlanTotalPercentage(BigDecimalUtil.toPercentage(planTotalAll, totalAll));
projectVo.setChildren(subProjectVoList);
return projectVo;
}
/** /**
* 根据子节点完成状态获取父节点完成状态 * 根据子节点完成状态获取父节点完成状态
* *

View File

@ -499,8 +499,12 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
int pageNum = ObjectUtil.defaultIfNull(pageQuery.getPageNum(), PageQuery.DEFAULT_PAGE_NUM); int pageNum = ObjectUtil.defaultIfNull(pageQuery.getPageNum(), PageQuery.DEFAULT_PAGE_NUM);
int pageSize = ObjectUtil.defaultIfNull(pageQuery.getPageSize(), PageQuery.DEFAULT_PAGE_SIZE); int pageSize = ObjectUtil.defaultIfNull(pageQuery.getPageSize(), PageQuery.DEFAULT_PAGE_SIZE);
// 保底 // 保底
if (pageNum < 1) pageNum = 1; if (pageNum < 1) {
if (pageSize < 1) pageSize = PageQuery.DEFAULT_PAGE_SIZE; pageNum = 1;
}
if (pageSize < 1) {
pageSize = PageQuery.DEFAULT_PAGE_SIZE;
}
int fromIndex = (pageNum - 1) * pageSize; int fromIndex = (pageNum - 1) * pageSize;
int toIndex = Math.min(fromIndex + pageSize, fullList.size()); int toIndex = Math.min(fromIndex + pageSize, fullList.size());
// 防止越界 // 防止越界

View File

@ -133,6 +133,15 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
throw new ServiceException("对应方阵不存在", HttpStatus.NOT_FOUND); throw new ServiceException("对应方阵不存在", HttpStatus.NOT_FOUND);
} }
Long progressCategoryId = progressPlan.getProgressCategoryId(); Long progressCategoryId = progressPlan.getProgressCategoryId();
// 校验日期是否合法
PgsProgressPlan lastProgressPlan = this.lambdaQuery()
.eq(PgsProgressPlan::getProgressCategoryId, progressCategoryId)
.orderByDesc(PgsProgressPlan::getEndDate)
.last("limit 1")
.one();
if (lastProgressPlan != null && startDate.before(lastProgressPlan.getEndDate())) {
throw new ServiceException("开始日期不能早于上一条进度计划结束日期", HttpStatus.BAD_REQUEST);
}
PgsProgressCategory progressCategory = progressCategoryService.getById(progressCategoryId); PgsProgressCategory progressCategory = progressCategoryService.getById(progressCategoryId);
this.validPlanNumber(req.getPlanNumber(), progressCategory); this.validPlanNumber(req.getPlanNumber(), progressCategory);
progressPlan.setProgressCategoryName(progressCategory.getName()); progressPlan.setProgressCategoryName(progressCategory.getName());
@ -146,7 +155,7 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
Long id = progressPlan.getId(); Long id = progressPlan.getId();
List<PgsProgressPlanDetailCreateDto> detailList = req.getDetailList(); List<PgsProgressPlanDetailCreateDto> detailList = req.getDetailList();
if (CollUtil.isNotEmpty(detailList)) { if (CollUtil.isNotEmpty(detailList)) {
List<PgsProgressPlanDetail> detailList1 = detailList.stream().map(detail -> { List<PgsProgressPlanDetail> newDetailList = detailList.stream().map(detail -> {
PgsProgressPlanDetail progressPlanDetail = new PgsProgressPlanDetail(); PgsProgressPlanDetail progressPlanDetail = new PgsProgressPlanDetail();
BeanUtils.copyProperties(detail, progressPlanDetail); BeanUtils.copyProperties(detail, progressPlanDetail);
progressPlanDetail.setProgressPlanId(id); progressPlanDetail.setProgressPlanId(id);
@ -154,7 +163,7 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
progressPlanDetail.setProgressCategoryId(progressPlan.getProgressCategoryId()); progressPlanDetail.setProgressCategoryId(progressPlan.getProgressCategoryId());
return progressPlanDetail; return progressPlanDetail;
}).toList(); }).toList();
boolean result = progressPlanDetailService.saveBatch(detailList1); boolean result = progressPlanDetailService.saveBatch(newDetailList);
if (!result) { if (!result) {
throw new ServiceException("新增进度计划详情失败,数据库操作失败", HttpStatus.ERROR); throw new ServiceException("新增进度计划详情失败,数据库操作失败", HttpStatus.ERROR);
} }
@ -164,6 +173,7 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
.eq(PgsProgressCategory::getId, progressCategoryId) .eq(PgsProgressCategory::getId, progressCategoryId)
.set(PgsProgressCategory::getPlanTotal, progressPlan.getPlanNumber()) .set(PgsProgressCategory::getPlanTotal, progressPlan.getPlanNumber())
.set(PgsProgressCategory::getStatus, PgsFinishStatusEnum.INPROGRESS.getValue()) .set(PgsProgressCategory::getStatus, PgsFinishStatusEnum.INPROGRESS.getValue())
.set(PgsProgressCategory::getIsDelay, PgsDelayStatusEnum.UNDELAY.getValue())
.update(); .update();
if (!update) { if (!update) {
throw new ServiceException("更新进度分类计划总数量失败,数据库操作失败", HttpStatus.ERROR); throw new ServiceException("更新进度分类计划总数量失败,数据库操作失败", HttpStatus.ERROR);

View File

@ -21,4 +21,9 @@ public interface BusProjectConstant {
*/ */
String PROJECT_CACHE_REDIS_KEY_PREFIX = "project"; String PROJECT_CACHE_REDIS_KEY_PREFIX = "project";
/**
* 父级项目id
*/
Long PARENT_PROJECT_ID = 0L;
} }

View File

@ -1,10 +1,10 @@
package org.dromara.project.controller; package org.dromara.project.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
@ -18,12 +18,10 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.project.domain.dto.project.BusProjectCreateReq; import org.dromara.project.domain.dto.project.BusProjectCreateReq;
import org.dromara.project.domain.dto.project.BusProjectCreateSubReq;
import org.dromara.project.domain.dto.project.BusProjectQueryReq; import org.dromara.project.domain.dto.project.BusProjectQueryReq;
import org.dromara.project.domain.dto.project.BusProjectUpdateReq; import org.dromara.project.domain.dto.project.BusProjectUpdateReq;
import org.dromara.project.domain.vo.project.BusProjectContractorListVo; import org.dromara.project.domain.vo.project.*;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -37,12 +35,12 @@ import java.util.List;
* @date 2025-03-04 * @date 2025-03-04
*/ */
@Validated @Validated
@RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/project/project") @RequestMapping("/project/project")
public class BusProjectController extends BaseController { public class BusProjectController extends BaseController {
private final IBusProjectService projectService; @Resource
private IBusProjectService projectService;
/** /**
* 查询项目列表 * 查询项目列表
@ -53,6 +51,16 @@ public class BusProjectController extends BaseController {
return projectService.queryPageList(req, pageQuery); return projectService.queryPageList(req, pageQuery);
} }
/**
* 查询项目下的子项目列表
*/
@SaCheckPermission("project:project:list")
@GetMapping("/list/sub/{id}")
public R<List<BusSubProjectVo>> listSubProject(@NotNull(message = "项目id不能为空")
@PathVariable Long id) {
return R.ok(projectService.querySubList(id));
}
/** /**
* 导出项目列表 * 导出项目列表
*/ */
@ -99,6 +107,20 @@ public class BusProjectController extends BaseController {
return R.ok(projectService.insertByBo(req)); return R.ok(projectService.insertByBo(req));
} }
/**
* 新增子项目
*/
@SaCheckPermission("project:project:add")
@Log(title = "项目", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/sub")
public R<Long> addSub(@Validated(AddGroup.class) @RequestBody BusProjectCreateSubReq req) {
if (req == null) {
throw new ServiceException("参数不能为空", HttpStatus.BAD_REQUEST);
}
return R.ok(projectService.insertSubByProject(req));
}
/** /**
* 修改项目 * 修改项目
*/ */

View File

@ -56,7 +56,6 @@ public class BusUserProjectRelevancyController extends BaseController {
/** /**
* 查询登录用户与项目关联列表 * 查询登录用户与项目关联列表
*/ */
@SaCheckPermission("project:projectRelevancy:list")
@GetMapping("/login/list") @GetMapping("/login/list")
public R<List<BusLoginUserProjectRelevancyVo>> listByLoginUser() { public R<List<BusLoginUserProjectRelevancyVo>> listByLoginUser() {
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();

View File

@ -25,11 +25,6 @@ public class BusProjectCreateReq implements Serializable {
*/ */
private String shortName; private String shortName;
/**
* 父项目id
*/
private Long pId;
/** /**
* 项目图片 * 项目图片
*/ */

View File

@ -0,0 +1,28 @@
package org.dromara.project.domain.dto.project;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/6/6 11:57
*/
@Data
public class BusProjectCreateSubReq implements Serializable {
@Serial
private static final long serialVersionUID = 6380055877986391291L;
/**
* 项目名称
*/
private String projectName;
/**
* 父项目id
*/
private Long pId;
}

View File

@ -11,6 +11,7 @@ import org.dromara.project.domain.BusProject;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
@ -183,4 +184,9 @@ public class BusProjectVo implements Serializable {
@ExcelProperty(value = "创建时间") @ExcelProperty(value = "创建时间")
private Date createTime; private Date createTime;
/**
* 子项目
*/
private List<BusSubProjectVo> children;
} }

View File

@ -0,0 +1,34 @@
package org.dromara.project.domain.vo.project;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* @author lcj
* @date 2025/6/4 9:53
*/
@Data
public class BusSubProjectVo implements Serializable {
@Serial
private static final long serialVersionUID = -5283786195929619472L;
/**
* id
*/
private Long id;
/**
* 项目名称
*/
private String projectName;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -7,12 +7,10 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.dto.project.BusProjectCreateReq; import org.dromara.project.domain.dto.project.BusProjectCreateReq;
import org.dromara.project.domain.dto.project.BusProjectCreateSubReq;
import org.dromara.project.domain.dto.project.BusProjectQueryReq; import org.dromara.project.domain.dto.project.BusProjectQueryReq;
import org.dromara.project.domain.dto.project.BusProjectUpdateReq; import org.dromara.project.domain.dto.project.BusProjectUpdateReq;
import org.dromara.project.domain.vo.project.BusProjectContractorListVo; import org.dromara.project.domain.vo.project.*;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -50,6 +48,14 @@ public interface IBusProjectService extends IService<BusProject> {
*/ */
List<BusProjectVo> queryList(BusProjectQueryReq req); List<BusProjectVo> queryList(BusProjectQueryReq req);
/**
* 查询项目下的子项目列表
*
* @param id 父项目id
* @return 项目下的子项目列表
*/
List<BusSubProjectVo> querySubList(Long id);
/** /**
* 查询当前登录用户项目列表以及项目列表下的分包公司列表 * 查询当前登录用户项目列表以及项目列表下的分包公司列表
* *
@ -65,6 +71,14 @@ public interface IBusProjectService extends IService<BusProject> {
*/ */
Long insertByBo(BusProjectCreateReq dto); Long insertByBo(BusProjectCreateReq dto);
/**
* 新增子项目
*
* @param dto 子项目
* @return 子项目 id
*/
Long insertSubByProject(BusProjectCreateSubReq dto);
/** /**
* 修改项目 * 修改项目
* *
@ -91,7 +105,7 @@ public interface IBusProjectService extends IService<BusProject> {
BusProjectVo getVo(BusProject project); BusProjectVo getVo(BusProject project);
/** /**
* 获取项目查询条件封装 * 获取项目查询条件封装(不查询子项目)
* *
* @param req 查询条件 * @param req 查询条件
* @return 查询条件封装 * @return 查询条件封装

View File

@ -32,6 +32,7 @@ import org.dromara.project.service.IBusProjectFileService;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.utils.Dxf2JsonUtil; import org.dromara.utils.Dxf2JsonUtil;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -67,6 +68,9 @@ public class BusProjectFileServiceImpl extends ServiceImpl<BusProjectFileMapper,
private static final ConcurrentHashMap<String, Boolean> USER_TASK_RUNNING = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, Boolean> USER_TASK_RUNNING = new ConcurrentHashMap<>();
@Value("${dxf2GeoJson.file-name}")
private String dxf2GeoJsonFileName;
/** /**
* 查询项目文件存储 * 查询项目文件存储
* *
@ -258,7 +262,7 @@ public class BusProjectFileServiceImpl extends ServiceImpl<BusProjectFileMapper,
// 构造 JSON 输出路径 // 构造 JSON 输出路径
String outputJSONPath = filePath + File.separator + uuid + "." + DesignMapFileConstant.JSONFileSuffix; String outputJSONPath = filePath + File.separator + uuid + "." + DesignMapFileConstant.JSONFileSuffix;
// 获取 dxf2json.exe 路径 // 获取 dxf2json.exe 路径
String exePath = projectRoot + File.separator + DesignMapFileConstant.DXF_BASE_PATH + File.separator + "main.exe"; String exePath = projectRoot + File.separator + DesignMapFileConstant.DXF_BASE_PATH + File.separator + dxf2GeoJsonFileName;
String sourceEPSG = DesignMapFileConstant.EPSG4524; String sourceEPSG = DesignMapFileConstant.EPSG4524;
String targetEPSG = DesignMapFileConstant.EPSG4326; String targetEPSG = DesignMapFileConstant.EPSG4326;
BusProjectFile oldProjectFile = this.lambdaQuery() BusProjectFile oldProjectFile = this.lambdaQuery()

View File

@ -34,12 +34,10 @@ import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.BusProjectFile; import org.dromara.project.domain.BusProjectFile;
import org.dromara.project.domain.BusUserProjectRelevancy; import org.dromara.project.domain.BusUserProjectRelevancy;
import org.dromara.project.domain.dto.project.BusProjectCreateReq; import org.dromara.project.domain.dto.project.BusProjectCreateReq;
import org.dromara.project.domain.dto.project.BusProjectCreateSubReq;
import org.dromara.project.domain.dto.project.BusProjectQueryReq; import org.dromara.project.domain.dto.project.BusProjectQueryReq;
import org.dromara.project.domain.dto.project.BusProjectUpdateReq; import org.dromara.project.domain.dto.project.BusProjectUpdateReq;
import org.dromara.project.domain.vo.project.BusProjectContractorListVo; import org.dromara.project.domain.vo.project.*;
import org.dromara.project.domain.vo.project.BusProjectSafetyDayVo;
import org.dromara.project.domain.vo.project.BusProjectVo;
import org.dromara.project.domain.vo.project.BusProjectWeatherVo;
import org.dromara.project.mapper.BusProjectMapper; import org.dromara.project.mapper.BusProjectMapper;
import org.dromara.project.service.IBusContractorService; import org.dromara.project.service.IBusContractorService;
import org.dromara.project.service.IBusProjectFileService; import org.dromara.project.service.IBusProjectFileService;
@ -115,8 +113,21 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
*/ */
@Override @Override
public TableDataInfo<BusProjectVo> queryPageList(BusProjectQueryReq req, PageQuery pageQuery) { public TableDataInfo<BusProjectVo> queryPageList(BusProjectQueryReq req, PageQuery pageQuery) {
// 获取当前登录用户项目列表
Long userId = LoginHelper.getUserId();
List<Long> projectIdList = userProjectRelevancyService.lambdaQuery()
.select(BusUserProjectRelevancy::getProjectId)
.eq(BusUserProjectRelevancy::getUserId, userId)
.list()
.stream().map(BusUserProjectRelevancy::getProjectId).toList();
LambdaQueryWrapper<BusProject> lqw = this.buildQueryWrapper(req);
if (CollUtil.isEmpty(projectIdList)) {
return TableDataInfo.build(new Page<>());
} else {
lqw.in(BusProject::getId, projectIdList);
}
// 查询数据库 // 查询数据库
Page<BusProject> result = this.page(pageQuery.build(), this.buildQueryWrapper(req)); Page<BusProject> result = this.page(pageQuery.build(), lqw);
return TableDataInfo.build(this.getVoPage(result)); return TableDataInfo.build(this.getVoPage(result));
} }
@ -132,6 +143,27 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
return this.list(lqw).stream().map(this::getVo).toList(); return this.list(lqw).stream().map(this::getVo).toList();
} }
/**
* 查询项目下的子项目列表
*
* @param id 父项目id
* @return 项目下的子项目列表
*/
@Override
public List<BusSubProjectVo> querySubList(Long id) {
BusProject project = this.getById(id);
if (project == null) {
throw new ServiceException("查询项目不存在", HttpStatus.NOT_FOUND);
}
List<BusProject> subProjectList = this.list(new LambdaQueryWrapper<BusProject>()
.eq(BusProject::getPId, id));
return subProjectList.stream().map(subProject -> {
BusSubProjectVo subProjectVo = new BusSubProjectVo();
BeanUtils.copyProperties(subProject, subProjectVo);
return subProjectVo;
}).toList();
}
/** /**
* 查询当前登录用户项目列表以及项目列表下的分包公司列表 * 查询当前登录用户项目列表以及项目列表下的分包公司列表
* *
@ -214,6 +246,49 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
return projectId; return projectId;
} }
/**
* 新增子项目
*
* @param dto 子项目
* @return 子项目 id
*/
@Override
public Long insertSubByProject(BusProjectCreateSubReq dto) {
String projectName = dto.getProjectName();
Long pId = dto.getPId();
if (StringUtils.isBlank(projectName)) {
throw new ServiceException("子项目名称不能为空", HttpStatus.BAD_REQUEST);
}
BusProject project = this.getById(pId);
if (project == null) {
throw new ServiceException("父项目不存在", HttpStatus.NOT_FOUND);
}
// 权限校验
Long userId = LoginHelper.getUserId();
validAuth(project.getId(), userId);
BusProject subProject = new BusProject();
subProject.setPId(pId);
subProject.setProjectName(projectName);
boolean save = this.save(subProject);
if (!save) {
throw new ServiceException("新增子项目失败,数据库异常", HttpStatus.ERROR);
}
Long subProjectId = subProject.getId();
// 同步保存用户与项目关联
Set<Long> userIdList = new HashSet<>(List.of(userId, SystemConstants.SUPER_ADMIN_ID));
List<BusUserProjectRelevancy> userProjectRelevancyList = userIdList.stream().map(id -> {
BusUserProjectRelevancy userProjectRelevancy = new BusUserProjectRelevancy();
userProjectRelevancy.setUserId(id);
userProjectRelevancy.setProjectId(subProjectId);
return userProjectRelevancy;
}).toList();
boolean saveRelevancy = userProjectRelevancyService.saveBatch(userProjectRelevancyList);
if (!saveRelevancy) {
throw new ServiceException("新增用户与项目关联失败,数据库异常", HttpStatus.ERROR);
}
return subProjectId;
}
/** /**
* 修改项目 * 修改项目
* *
@ -287,6 +362,13 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
if (isValid) { if (isValid) {
// 做一些业务上的校验,判断是否需要校验 // 做一些业务上的校验,判断是否需要校验
this.validAuth(ids, userId); this.validAuth(ids, userId);
// 查看是否有子项目
Long count = this.lambdaQuery()
.in(BusProject::getPId, ids)
.count();
if (count > 0) {
throw new ServiceException("删除项目中存在子项目,请先删除子项目", HttpStatus.BAD_REQUEST);
}
} }
// 删除项目 // 删除项目
boolean removeProjectList = this.removeBatchByIds(ids); boolean removeProjectList = this.removeBatchByIds(ids);
@ -330,11 +412,22 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
if (projectFile != null) { if (projectFile != null) {
projectVo.setDesignId(projectFile.getId()); projectVo.setDesignId(projectFile.getId());
} }
// 关联子项目列表
List<BusProject> subProjectList = this.lambdaQuery()
.select(BusProject::getId, BusProject::getProjectName, BusProject::getCreateTime)
.eq(BusProject::getPId, project.getId())
.list();
List<BusSubProjectVo> subProjectVoList = subProjectList.stream().map(subProject -> {
BusSubProjectVo subProjectVo = new BusSubProjectVo();
BeanUtils.copyProperties(subProject, subProjectVo);
return subProjectVo;
}).toList();
projectVo.setChildren(subProjectVoList);
return projectVo; return projectVo;
} }
/** /**
* 获取项目查询条件封装 * 获取项目查询条件封装(不查询子项目)
* *
* @param req 查询条件 * @param req 查询条件
* @return 查询条件封装 * @return 查询条件封装
@ -382,7 +475,11 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
lqw.eq(ObjectUtils.isNotEmpty(projectCategory), BusProject::getProjectCategory, projectCategory); lqw.eq(ObjectUtils.isNotEmpty(projectCategory), BusProject::getProjectCategory, projectCategory);
lqw.eq(ObjectUtils.isNotEmpty(designTotal), BusProject::getDesignTotal, designTotal); lqw.eq(ObjectUtils.isNotEmpty(designTotal), BusProject::getDesignTotal, designTotal);
lqw.eq(ObjectUtils.isNotEmpty(showHidden), BusProject::getShowHidden, showHidden); lqw.eq(ObjectUtils.isNotEmpty(showHidden), BusProject::getShowHidden, showHidden);
// 排序
lqw.orderByAsc(BusProject::getSort); lqw.orderByAsc(BusProject::getSort);
// 不查询子项目
final Long PID = 0L;
lqw.eq(BusProject::getPId, PID);
return lqw; return lqw;
} }
@ -399,6 +496,12 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
Map<Long, List<BusProjectFile>> projectFileMap = projectFileService.lambdaQuery() Map<Long, List<BusProjectFile>> projectFileMap = projectFileService.lambdaQuery()
.in(BusProjectFile::getProjectId, projectIdList).list() .in(BusProjectFile::getProjectId, projectIdList).list()
.stream().collect(Collectors.groupingBy(BusProjectFile::getProjectId)); .stream().collect(Collectors.groupingBy(BusProjectFile::getProjectId));
// 获取子项目列表
List<BusProject> subProjectList = this.lambdaQuery()
.select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getCreateTime)
.in(BusProject::getPId, projectIdList)
.list();
Map<Long, List<BusProject>> subProjectMap = subProjectList.stream().collect(Collectors.groupingBy(BusProject::getPId));
// 对象列表 => 封装对象列表 // 对象列表 => 封装对象列表
List<BusProjectVo> projectVoList = projectList.stream().map(project -> { List<BusProjectVo> projectVoList = projectList.stream().map(project -> {
// 对象转封装类 // 对象转封装类
@ -415,6 +518,16 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
if (CollUtil.isNotEmpty(projectFileList)) { if (CollUtil.isNotEmpty(projectFileList)) {
projectVo.setDesignId(projectFileList.getFirst().getId()); projectVo.setDesignId(projectFileList.getFirst().getId());
} }
// 关联子项目
List<BusSubProjectVo> subProjectVoList = new ArrayList<>();
if (subProjectMap.containsKey(project.getId())){
subProjectVoList = subProjectMap.get(project.getId()).stream().map(subProject -> {
BusSubProjectVo subProjectVo = new BusSubProjectVo();
BeanUtils.copyProperties(subProject, subProjectVo);
return subProjectVo;
}).toList();
}
projectVo.setChildren(subProjectVoList);
return projectVo; return projectVo;
}).toList(); }).toList();
projectVoPage.setRecords(projectVoList); projectVoPage.setRecords(projectVoList);

View File

@ -13,6 +13,7 @@ import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.project.constant.BusProjectConstant;
import org.dromara.project.domain.BusProject; import org.dromara.project.domain.BusProject;
import org.dromara.project.domain.BusUserProjectRelevancy; import org.dromara.project.domain.BusUserProjectRelevancy;
import org.dromara.project.domain.dto.project.BusProjectBatchByProjectListReq; import org.dromara.project.domain.dto.project.BusProjectBatchByProjectListReq;
@ -29,10 +30,8 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays; import java.util.*;
import java.util.Collection; import java.util.stream.Collectors;
import java.util.List;
import java.util.Objects;
/** /**
* 系统用户与项目关联Service业务层处理 * 系统用户与项目关联Service业务层处理
@ -209,14 +208,22 @@ public class BusUserProjectRelevancyServiceImpl extends ServiceImpl<BusUserProje
queryWrapper.eq(BusUserProjectRelevancy::getUserId, userId); queryWrapper.eq(BusUserProjectRelevancy::getUserId, userId);
// 查询数据库,获取数据 // 查询数据库,获取数据
List<BusUserProjectRelevancy> list = this.list(queryWrapper); List<BusUserProjectRelevancy> list = this.list(queryWrapper);
List<Long> projectIdList = list.stream().map(BusUserProjectRelevancy::getProjectId).toList();
Map<Long, List<BusProject>> projectMap = projectService.lambdaQuery()
.select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getShortName)
.in(BusProject::getId, projectIdList)
.eq(BusProject::getPId, BusProjectConstant.PARENT_PROJECT_ID)
.list()
.stream().collect(Collectors.groupingBy(BusProject::getId));
// 获取封装 // 获取封装
return list.stream() return list.stream()
.map(userProjectRelevancy -> { .map(userProjectRelevancy -> {
Long projectId = userProjectRelevancy.getProjectId(); Long projectId = userProjectRelevancy.getProjectId();
QueryWrapper<BusProject> projectQueryWrapper = new QueryWrapper<>(); BusProject project = null;
projectQueryWrapper.eq("id", projectId); if (projectMap.containsKey(projectId)) {
BusProject project = projectService.getOne(projectQueryWrapper); project = projectMap.get(projectId).getFirst();
if (project != null) { }
if (project != null && project.getPId().equals(BusProjectConstant.PARENT_PROJECT_ID)) {
BusLoginUserProjectRelevancyVo loginUserProjectRelevancy = new BusLoginUserProjectRelevancyVo(); BusLoginUserProjectRelevancyVo loginUserProjectRelevancy = new BusLoginUserProjectRelevancyVo();
loginUserProjectRelevancy.setId(userProjectRelevancy.getId()); loginUserProjectRelevancy.setId(userProjectRelevancy.getId());
loginUserProjectRelevancy.setUserId(userProjectRelevancy.getUserId()); loginUserProjectRelevancy.setUserId(userProjectRelevancy.getUserId());

View File

@ -1,7 +1,7 @@
worker_processes 1; worker_processes 1;
error_log /var/log/nginx/error.log warn; error_log /mnt/disk1/docker/nginx/log/error.log warn;
pid /var/run/nginx.pid; pid /mnt/disk1/docker/nginx/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
@ -19,12 +19,11 @@ http {
'$status $body_bytes_sent "$http_referer" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; access_log /mnt/disk1/docker/nginx/log/access.log main;
upstream server { upstream server {
ip_hash; ip_hash;
server 127.0.0.1:8080; server 127.0.0.1:8899;
server 127.0.0.1:8081;
} }
upstream monitor-admin { upstream monitor-admin {
@ -68,12 +67,12 @@ http {
} }
location / { location / {
root /usr/share/nginx/html; # docker映射路径 不允许更改 root /mnt/disk1/docker/nginx/html; # docker映射路径 不允许更改
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
index index.html index.htm; index index.html index.htm;
} }
location /prod-api/ { location /api/ {
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header REMOTE-HOST $remote_addr;