进度管理app、注解翻译项目名称

This commit is contained in:
lcj
2025-09-10 16:43:49 +08:00
parent ab332c462f
commit 4d627af3a1
19 changed files with 239 additions and 62 deletions

View File

@ -80,4 +80,9 @@ public interface CacheNames {
*/
String ONLINE_TOKEN = "online_tokens";
/**
* 项目名称
*/
String PROJECT_NAME = "project_name#30d";
}

View File

@ -0,0 +1,17 @@
package org.dromara.common.core.service;
/**
* @author lilemy
* @date 2025-09-10 16:15
*/
public interface ProjectService {
/**
* 通过项目ID查询项目名称
*
* @param projectId 项目ID
* @return 项目名称
*/
String selectProjectNameById(Long projectId);
}

View File

@ -32,4 +32,9 @@ public interface TransConstant {
*/
String OSS_ID_TO_URL = "oss_id_to_url";
/**
* 项目id转名称
*/
String PROJECT_ID_TO_NAME = "project_id_to_name";
}

View File

@ -0,0 +1,35 @@
package org.dromara.common.translation.core.impl;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import org.dromara.common.core.service.ProjectService;
import org.dromara.common.translation.annotation.TranslationType;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.common.translation.core.TranslationInterface;
/**
* @author lilemy
* @date 2025-09-10 16:13
*/
@AllArgsConstructor
@TranslationType(type = TransConstant.PROJECT_ID_TO_NAME)
public class ProjectNameTranslationImpl implements TranslationInterface<String> {
@Resource
private ProjectService projectService;
/**
* 翻译
*
* @param key 需要被翻译的键(不为空)
* @param other 其他参数
* @return 返回键对应的值
*/
@Override
public String translation(Object key, String other) {
if (key instanceof Long id) {
return projectService.selectProjectNameById(id);
}
return null;
}
}

View File

@ -4,3 +4,4 @@ org.dromara.common.translation.core.impl.DictTypeTranslationImpl
org.dromara.common.translation.core.impl.OssUrlTranslationImpl
org.dromara.common.translation.core.impl.UserNameTranslationImpl
org.dromara.common.translation.core.impl.NicknameTranslationImpl
org.dromara.common.translation.core.impl.ProjectNameTranslationImpl

View File

@ -4,6 +4,8 @@ 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.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.other.domain.OthYs7Device;
import java.io.Serial;
@ -40,6 +42,7 @@ public class OthYs7DeviceVo implements Serializable {
/**
* 项目名称
*/
@Translation(type = TransConstant.PROJECT_ID_TO_NAME, mapper = "projectId")
private String projectName;
/**

View File

@ -262,11 +262,6 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl<OthYs7DeviceMapper, Oth
return ys7DeviceVo;
}
BeanUtils.copyProperties(ys7Device, ys7DeviceVo);
Long projectId = ys7Device.getProjectId();
if (projectId != null && !projectId.equals(0L)) {
BusProject project = projectService.getById(projectId);
ys7DeviceVo.setProjectName(project.getProjectName());
}
return ys7DeviceVo;
}
@ -315,22 +310,10 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl<OthYs7DeviceMapper, Oth
if (CollUtil.isEmpty(ys7DeviceList)) {
return ys7DeviceVoPage;
}
// 获取项目列表
Set<Long> projectIdList = ys7DeviceList.stream().map(OthYs7Device::getProjectId).collect(Collectors.toSet());
List<BusProject> projectList = projectService.lambdaQuery()
.select(BusProject::getId, BusProject::getProjectName)
.in(BusProject::getId, projectIdList)
.list();
Map<Long, BusProject> projectMap = projectList.stream().collect(Collectors.toMap(BusProject::getId, project -> project));
// 对象列表 => 封装对象列表
List<OthYs7DeviceVo> ys7DeviceVoList = ys7DeviceList.stream().map(ys7Device -> {
OthYs7DeviceVo ys7DeviceVo = new OthYs7DeviceVo();
BeanUtils.copyProperties(ys7Device, ys7DeviceVo);
Long projectId = ys7Device.getProjectId();
if (projectId != null && !projectId.equals(0L)) {
BusProject project = projectMap.get(projectId);
ys7DeviceVo.setProjectName(project.getProjectName());
}
return ys7DeviceVo;
}).toList();
ys7DeviceVoPage.setRecords(ys7DeviceVoList);

View File

@ -55,8 +55,8 @@ public class PgsProgressPlanDetailController extends BaseController {
@SaCheckPermission("progress:progressPlanDetail:insertPercentage")
@RepeatSubmit()
@PostMapping("/insert/percentage")
public R<Void> insertPercentageDetail(@Validated @RequestBody PgsProgressPlanDetailPercentageCreateReq req) {
return toAjax(pgsProgressPlanDetailService.insertPercentageDetail(req));
public R<Void> insertPercentageDetail(@Validated @RequestBody PgsProgressPlanDetailCreateReq req) {
return toAjax(pgsProgressPlanDetailService.insertPercentageNumberDetail(req));
}
/**

View File

@ -1,7 +1,7 @@
package org.dromara.progress.controller.app;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.domain.R;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
@ -38,6 +38,17 @@ public class PgsProgressPlanAppController extends BaseController {
return progressPlanService.queryPageList(req, pageQuery);
}
/**
* 获取进度计划详细信息
*
* @param id 主键
*/
@GetMapping("/{id}")
public R<PgsProgressPlanVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(progressPlanService.queryById(id));
}
/**
* 新增进度计划
*/

View File

@ -7,14 +7,19 @@ import org.dromara.common.idempotent.annotation.RepeatSubmit;
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.progressplandetail.PgsProgressPlanDetailCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailFinishedCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailQueryReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailRemoveReq;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailNumVo;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailUnFinishVo;
import org.dromara.progress.service.IPgsProgressPlanDetailService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 进度计划详情 app 接口
*
@ -29,6 +34,14 @@ public class PgsProgressPlanDetailAppController extends BaseController {
@Resource
private IPgsProgressPlanDetailService progressPlanDetailService;
/**
* 查询进度计划详情列表
*/
@GetMapping("/list")
public R<List<PgsProgressPlanDetailNumVo>> list(PgsProgressPlanDetailQueryReq req) {
return R.ok(progressPlanDetailService.queryNumberList(req));
}
/**
* 新增进度计划详情(普通设施)
*/
@ -38,6 +51,15 @@ public class PgsProgressPlanDetailAppController extends BaseController {
return toAjax(progressPlanDetailService.insertFinishedDetail(req));
}
/**
* 新增进度计划详情(百分比、数量设施)
*/
@RepeatSubmit()
@PostMapping("/insert")
public R<Void> insertDetail(@Validated @RequestBody PgsProgressPlanDetailCreateReq req) {
return toAjax(progressPlanDetailService.insertPercentageNumberDetail(req));
}
/**
* 获取进度计划详情已完成设施详细信息
*

View File

@ -11,7 +11,7 @@ import java.math.BigDecimal;
* @date 2025/5/28 16:06
*/
@Data
public class PgsProgressPlanDetailPercentageCreateReq implements Serializable {
public class PgsProgressPlanDetailCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = -2987044313320050949L;

View File

@ -1,31 +0,0 @@
package org.dromara.progress.domain.dto.progressplandetail;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author lilemy
* @date 2025-09-09 18:06
*/
@Data
public class PgsProgressPlanDetailNumberCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = 6264982582390127674L;
/**
* 主键id
*/
@NotNull(message = "主键id不能为空")
private Long id;
/**
* 完成数量
*/
@NotNull(message = "完成数量不能为空")
private BigDecimal finishedNumber;
}

View File

@ -96,6 +96,21 @@ public class PgsProgressPlanVo implements Serializable {
*/
private BigDecimal aiFill;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
/**
* 工作类型
*/
private String workType;
/**
* 关联结构(1子项目 2方阵)
*/
private String relevancyStructure;
/**
* 进度计划详情
*/

View File

@ -41,4 +41,19 @@ public class PgsProgressPlanDetailNumVo {
*/
private BigDecimal aiFill;
/**
* 计量方式0无 1数量 2百分比
*/
private String unitType;
/**
* 工作类型
*/
private String workType;
/**
* 关联结构(1子项目 2方阵)
*/
private String relevancyStructure;
}

View File

@ -7,7 +7,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.progress.domain.PgsProgressPlanDetail;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailFinishedCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailPercentageCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailQueryReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailRemoveReq;
import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo;
@ -49,7 +49,7 @@ public interface IPgsProgressPlanDetailService extends IService<PgsProgressPlanD
* @param req 插入进度计划详情设施参数
* @return 是否插入成功
*/
Boolean insertPercentageDetail(PgsProgressPlanDetailPercentageCreateReq req);
Boolean insertPercentageNumberDetail(PgsProgressPlanDetailCreateReq req);
/**
* 插入进度计划详情设施
@ -131,4 +131,11 @@ public interface IPgsProgressPlanDetailService extends IService<PgsProgressPlanD
*/
Boolean syncPlanDetail2ConstructionValue(LocalDate localDate, Long projectId);
/**
* 查询计划详情设施数量
*
* @param req 查询条件
* @return 计划详情设施数量
*/
List<PgsProgressPlanDetailNumVo> queryNumberList(PgsProgressPlanDetailQueryReq req);
}

View File

@ -174,13 +174,14 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl<PgsProgressCateg
.orderByDesc(PgsProgressPlan::getEndDate)
.last("limit 1")
.one();
LocalDate now = LocalDate.now();
/* LocalDate now = LocalDate.now();
if (progressPlan != null && progressPlan.getEndDate().isAfter(now)) {
lastTimeVo.setEndDate(progressPlan.getEndDate());
} else {
LocalDate yesterday = now.minusDays(1);
lastTimeVo.setEndDate(yesterday);
}
}*/
lastTimeVo.setEndDate(LocalDate.of(2024, 1, 1));
return lastTimeVo;
}

View File

@ -26,8 +26,8 @@ import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.domain.PgsProgressPlan;
import org.dromara.progress.domain.PgsProgressPlanDetail;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailFinishedCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailPercentageCreateReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailQueryReq;
import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailRemoveReq;
import org.dromara.progress.domain.enums.PgsFinishStatusEnum;
@ -305,7 +305,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertPercentageDetail(PgsProgressPlanDetailPercentageCreateReq req) {
public Boolean insertPercentageNumberDetail(PgsProgressPlanDetailCreateReq req) {
// 校验
BigDecimal finishedNumber = req.getFinishedNumber();
if (finishedNumber == null) {
@ -612,9 +612,20 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
*/
@Override
public List<PgsProgressPlanDetailNumVo> getNumVoList(List<PgsProgressPlanDetail> progressPlanDetailList) {
List<Long> categoryIds = progressPlanDetailList.stream()
.map(PgsProgressPlanDetail::getProgressCategoryId).distinct().toList();
List<PgsProgressCategory> categoryList = progressCategoryService.listByIds(categoryIds);
Map<Long, PgsProgressCategory> categoryMap = categoryList.stream()
.collect(Collectors.toMap(PgsProgressCategory::getId, v -> v));
return progressPlanDetailList.stream().map(progressPlanDetail -> {
PgsProgressPlanDetailNumVo progressPlanDetailNumVo = new PgsProgressPlanDetailNumVo();
BeanUtils.copyProperties(progressPlanDetail, progressPlanDetailNumVo);
if (categoryMap.containsKey(progressPlanDetail.getProgressCategoryId())) {
PgsProgressCategory category = categoryMap.get(progressPlanDetail.getProgressCategoryId());
progressPlanDetailNumVo.setUnitType(category.getUnitType());
progressPlanDetailNumVo.setWorkType(category.getWorkType());
progressPlanDetailNumVo.setRelevancyStructure(category.getRelevancyStructure());
}
return progressPlanDetailNumVo;
}).toList();
}
@ -814,7 +825,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
Long progressPlanId = req.getProgressPlanId();
Long progressCategoryId = req.getProgressCategoryId();
lqw.eq(ObjectUtils.isNotEmpty(projectId), PgsProgressPlanDetail::getProjectId, projectId);
lqw.eq(ObjectUtils.isNotEmpty(progressPlanId), PgsProgressPlanDetail::getId, progressPlanId);
lqw.eq(ObjectUtils.isNotEmpty(progressPlanId), PgsProgressPlanDetail::getProgressPlanId, progressPlanId);
lqw.eq(ObjectUtils.isNotEmpty(progressCategoryId), PgsProgressPlanDetail::getProgressCategoryId, progressCategoryId);
return lqw;
}
@ -929,6 +940,19 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl<PgsProgressPla
return true;
}
/**
* 查询计划详情设施数量
*
* @param req 查询条件
* @return 计划详情设施数量
*/
@Override
public List<PgsProgressPlanDetailNumVo> queryNumberList(PgsProgressPlanDetailQueryReq req) {
LambdaQueryWrapper<PgsProgressPlanDetail> lqw = this.buildQueryWrapper(req);
List<PgsProgressPlanDetail> progressPlanDetailList = this.list(lqw);
return getNumVoList(progressPlanDetailList);
}
/**
* 分页
*

View File

@ -124,6 +124,10 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
if (endDate.isBefore(startDate)) {
throw new ServiceException("结束日期不能早于开始日期");
}
boolean overlap = this.hasOverlap(req.getProgressCategoryId(), startDate, endDate);
if (overlap) {
throw new ServiceException("该进度类型下,时间区间已存在重叠的数据");
}
Long projectId = progressPlan.getProjectId();
if (projectService.getById(projectId) == null) {
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
@ -136,14 +140,14 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
}
Long progressCategoryId = progressPlan.getProgressCategoryId();
// 校验日期是否合法
PgsProgressPlan lastProgressPlan = this.lambdaQuery()
/* PgsProgressPlan lastProgressPlan = this.lambdaQuery()
.eq(PgsProgressPlan::getProgressCategoryId, progressCategoryId)
.orderByDesc(PgsProgressPlan::getEndDate)
.last("limit 1")
.one();
if (lastProgressPlan != null && startDate.isBefore(lastProgressPlan.getEndDate())) {
throw new ServiceException("开始日期不能早于上一条进度计划结束日期", HttpStatus.BAD_REQUEST);
}
}*/
PgsProgressCategory progressCategory = progressCategoryService.getById(progressCategoryId);
this.validPlanNumber(req.getPlanNumber(), progressCategory);
progressPlan.setProgressCategoryName(progressCategory.getName());
@ -246,6 +250,13 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
.eq(PgsProgressPlanDetail::getProjectId, progressPlan.getProjectId())
.list();
progressPlanVo.setDetailList(progressPlanDetailService.getNumVoList(detailList));
// 获取进度类别
PgsProgressCategory progressCategory = progressCategoryService.getById(progressPlan.getProgressCategoryId());
if (progressCategory != null) {
progressPlanVo.setUnitType(progressCategory.getUnitType());
progressPlanVo.setWorkType(progressCategory.getWorkType());
progressPlanVo.setRelevancyStructure(progressCategory.getRelevancyStructure());
}
return progressPlanVo;
}
@ -291,6 +302,14 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
if (CollUtil.isEmpty(progressPlanList)) {
return progressPlanVoPage;
}
// 获取进度类别列表
List<Long> progressCategoryIdList = progressPlanList.stream()
.map(PgsProgressPlan::getProgressCategoryId)
.distinct()
.toList();
List<PgsProgressCategory> progressCategoryList = progressCategoryService.listByIds(progressCategoryIdList);
Map<Long, PgsProgressCategory> progressCategoryMap = progressCategoryList.stream()
.collect(Collectors.toMap(PgsProgressCategory::getId, category -> category));
// 获取详情列表
List<Long> idList = progressPlanList.stream().map(PgsProgressPlan::getId).toList();
List<PgsProgressPlanDetail> detailList = progressPlanDetailService.lambdaQuery()
@ -304,6 +323,7 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
BeanUtils.copyProperties(progressPlan, progressPlanVo);
// 获取详情列表
Long id = progressPlan.getId();
Long progressCategoryId = progressPlan.getProgressCategoryId();
List<PgsProgressPlanDetailNumVo> numDetailList = new ArrayList<>();
BigDecimal aiFill = BigDecimal.ZERO;
if (detailMap.containsKey(id)) {
@ -312,6 +332,12 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
aiFill = aiFill.add(detailNumVo.getAiFill());
}
}
if (progressCategoryMap.containsKey(progressCategoryId)) {
PgsProgressCategory category = progressCategoryMap.get(progressCategoryId);
progressPlanVo.setUnitType(category.getUnitType());
progressPlanVo.setWorkType(category.getWorkType());
progressPlanVo.setRelevancyStructure(category.getRelevancyStructure());
}
progressPlanVo.setDetailList(numDetailList);
progressPlanVo.setAiFill(aiFill);
return progressPlanVo;
@ -456,4 +482,21 @@ public class PgsProgressPlanServiceImpl extends ServiceImpl<PgsProgressPlanMappe
}
return true;
}
/**
* 校验是否存在时间重叠的数据
*
* @param progressCategoryId 进度类型id
* @param startDate 新增开始时间
* @param endDate 新增结束时间
*/
public boolean hasOverlap(Long progressCategoryId, LocalDate startDate, LocalDate endDate) {
return this.lambdaQuery()
.eq(PgsProgressPlan::getProgressCategoryId, progressCategoryId)
.and(wrapper -> wrapper
.le(PgsProgressPlan::getStartDate, endDate) // 数据库中的开始 <= 新增的结束
.ge(PgsProgressPlan::getEndDate, startDate) // 数据库中的结束 >= 新增的开始
)
.exists(); // 是否存在
}
}

View File

@ -14,11 +14,13 @@ import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.vo.IdAndNameVO;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.ProjectService;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
@ -51,6 +53,7 @@ import org.dromara.quality.service.IQltKnowledgeDocumentService;
import org.dromara.safety.service.IHseKnowledgeDocumentService;
import org.dromara.workflow.service.IFlwDefinitionService;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@ -75,7 +78,7 @@ import static org.dromara.common.satoken.utils.LoginHelper.LOGIN_USER_KEY;
@Slf4j
@Service
public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProject>
implements IBusProjectService {
implements IBusProjectService, ProjectService {
@Lazy
@Resource
@ -1137,4 +1140,22 @@ public class BusProjectServiceImpl extends ServiceImpl<BusProjectMapper, BusProj
return roots;
}
/**
* 通过项目ID查询项目名称
*
* @param projectId 项目ID
* @return 项目名称
*/
@Cacheable(cacheNames = CacheNames.PROJECT_NAME, key = "#projectId")
@Override
public String selectProjectNameById(Long projectId) {
if (projectId == 0) {
return null;
}
BusProject project = this.lambdaQuery()
.select(BusProject::getProjectName)
.eq(BusProject::getId, projectId)
.one();
return project != null ? project.getProjectName() : null;
}
}