[feat] 1.项目信息管理增加序号自增

[fix] 1.修改附件存储数据格式
This commit is contained in:
hhyykk 2024-07-08 20:53:09 +08:00
parent 55e5265152
commit c0e572b4b4
8 changed files with 169 additions and 32 deletions

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.framework.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author hhyykk
* @description 流程状态枚举
* @date 2024/7/8
*/
@Getter
@AllArgsConstructor
public enum ProcessStatusEnum {
// 审批中
APPROVAL_IN_PROGRESS(1, "审批中"),
// 审批通过
APPROVAL_PASS(2, "审批通过"),
// 审批不通过
APPROVAL_NOT_PASS(3, "审批不通过"),
// 已取消
CANCELLED(4, "已取消");
/**
* 类型
*/
private final Integer interval;
/**
* 名称
*/
private final String name;
}

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.framework.common.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author hhyykk
* @description
* @date 2024/7/8
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FileDTO implements Serializable {
/**
* 文件名
*/
private String name;
/**
* 文件地址
*/
private String url;
}

View File

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.pms.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author hhyykk
* @description 项目类型枚举
* @date 2024/7/8
*/
@Getter
@AllArgsConstructor
public enum ProjectTypeEnum {
// 设计
DESIGN("design", "SJ"),
// 检查
CHECK("check", "JC"),
// 勘察设计
SURVEY("survey", "KS"),
// 数智
DIGITAL("digital", "SZ"),
// 咨询
CONSULTING("consulting", "ZX");
/**
* 类型编号
*/
private final String code;
/**
* 类型编码
*/
private final String no;
/**
* 通过code获取no
* @param code 字典编号
* @return 类型编码
*/
public static String getNoByCode(String code) {
for (ProjectTypeEnum value : values()) {
if (value.getCode().equals(code)) {
return value.getNo();
}
}
return null;
}
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.pms.controller.admin.project.vo;
import cn.iocoder.yudao.framework.common.pojo.FileDTO;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.*;
import cn.iocoder.yudao.module.pms.enums.DictTypeConstants;
@ -21,7 +22,7 @@ import java.util.List;
@ExcelIgnoreUnannotated
public class ProjectRespDetailVO {
@Schema(description = "id", example = "11213")
@ExcelProperty("id")
// @ExcelProperty("id")
private Long id;
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@ -137,11 +138,11 @@ public class ProjectRespDetailVO {
private String customerCompanyName;
@Schema(description = "评审附件", example = "http://ryoyi.pro")
@ExcelProperty(value = "评审附件", converter = ListToStringConvert.class)
private List<String> reviewFileUrl;
// @ExcelProperty(value = "评审附件", converter = ListToStringConvert.class)
private List<FileDTO> reviewFileUrl;
@Schema(description = "中标附件", example = "http://ryoyi.pro")
@ExcelProperty(value = "中标附件", converter = ListToStringConvert.class)
private List<String> winFileUrl;
// @ExcelProperty(value = "中标附件", converter = ListToStringConvert.class)
private List<FileDTO> winFileUrl;
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.pms.controller.admin.project.vo;
import cn.iocoder.yudao.framework.common.pojo.FileDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@ -74,13 +75,13 @@ public class ProjectSaveReqVO {
private String situation;
@Schema(description = "评审附件", example = "https://www.iocoder.cn")
private List<String> reviewFileUrl;
private List<FileDTO> reviewFileUrl;
@Schema(description = "是否落地")
private Boolean confirmation;
@Schema(description = "中标附件", example = "https://www.iocoder.cn")
private List<String> winFileUrl;
private List<FileDTO> winFileUrl;
@Schema(description = "预计合同金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private String contractAmount;

View File

@ -59,4 +59,10 @@ public interface ProjectMapper extends BaseMapperX<ProjectDO> {
);
}
default ProjectDO selectLastSequence(String prefix) {
return selectOne(new LambdaQueryWrapperX<ProjectDO>()
.likeRight(ProjectDO::getCode, prefix)
.orderByDesc(ProjectDO::getCode)
);
}
}

View File

@ -1,23 +1,26 @@
package cn.iocoder.yudao.module.pms.service.project;
import cn.iocoder.yudao.framework.common.enums.ProcessStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.pms.controller.admin.project.vo.ProjectPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.project.vo.ProjectSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDetailDO;
import cn.iocoder.yudao.module.pms.enums.EntrustMethodConstants;
import org.springframework.stereotype.Service;
import cn.iocoder.yudao.module.pms.dal.mysql.project.ProjectMapper;
import cn.iocoder.yudao.module.pms.enums.ProjectTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.pms.controller.admin.project.vo.*;
import cn.iocoder.yudao.module.pms.dal.dataobject.project.ProjectDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pms.dal.mysql.project.ProjectMapper;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;
/**
* 项目基本信息 Service 实现类
@ -40,25 +43,16 @@ public class ProjectServiceImpl implements ProjectService {
@Override
public Long createProject(Long loginUserId, ProjectSaveReqVO createReqVO) {
// 非公开招标或者邀请招标的无需审批
if (!EntrustMethodConstants.ENTRUST_PUBLIC_BIDDING.equals(createReqVO.getEntrustMethod()) &&
!EntrustMethodConstants.ENTRUST_INVITED_BIDDING.equals(createReqVO.getEntrustMethod())) {
createReqVO.setProcessStatus(2); //审批通过
}
// 插入
ProjectDO project = BeanUtils.toBean(createReqVO, ProjectDO.class);
projectMapper.insert(project);
// 启动流程
if (createReqVO.getId() == null) {
if (EntrustMethodConstants.ENTRUST_PUBLIC_BIDDING.equals(project.getEntrustMethod()) ||
EntrustMethodConstants.ENTRUST_INVITED_BIDDING.equals(project.getEntrustMethod())) {
// 公开中标或邀请招标需要走流程
String processInstanceId = processInstanceApi.createProcessInstance(loginUserId,
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setBusinessKey(String.valueOf(project.getId())));
// 写入工作流编号
projectMapper.updateById(new ProjectDO().setId(project.getId()).setProcessInstanceId(processInstanceId));
}
String processInstanceId = processInstanceApi.createProcessInstance(loginUserId,
new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
.setBusinessKey(String.valueOf(project.getId())));
// 写入工作流编号
projectMapper.updateById(new ProjectDO().setId(project.getId()).setProcessInstanceId(processInstanceId));
}
// 返回
return project.getId();
@ -68,6 +62,12 @@ public class ProjectServiceImpl implements ProjectService {
public void updateProject(ProjectSaveReqVO updateReqVO) {
// 校验存在
validateProjectExists(updateReqVO.getId());
// 如果审批通过,且项目落地则生成项目编号 eg. 勘察设计KS20240001检测监测JC20240001咨询ZX20240001数智SZ20240001
if (ProcessStatusEnum.APPROVAL_PASS.getInterval().equals(updateReqVO.getProcessStatus())
&& Boolean.TRUE.equals(updateReqVO.getConfirmation())) {
String codeNo = this.generator(ProjectTypeEnum.getNoByCode(updateReqVO.getType()), 1);
updateReqVO.setCode(codeNo);
}
// 更新
ProjectDO updateObj = BeanUtils.toBean(updateReqVO, ProjectDO.class);
projectMapper.updateById(updateObj);
@ -125,4 +125,27 @@ public class ProjectServiceImpl implements ProjectService {
projectMapper.updateById(new ProjectDO().setId(id).setProcessStatus(status));
}
/**
* 序号自增
* @param prefix 前缀
* @param number 步进
* @return 自增后的序列
*/
private String generator(String prefix, Integer number) {
// 获取当前年月日
prefix += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy"));
ProjectDO projectDO = projectMapper.selectLastSequence(prefix);
if (projectDO == null) {
return prefix + "0001";
} else {
String sequence = projectDO.getCode();
// 截取最后四位
String lastSequence = sequence.substring(sequence.length() - 4);
// 自增1
int lastNumber = Integer.parseInt(lastSequence);
lastNumber = lastNumber + number;
return prefix + String.format("%04d", lastNumber);
}
}
}

View File

@ -20,7 +20,7 @@ spring:
# throw-exception-if-no-handler-found: true # 404 错误时抛出异常,方便统一处理
# static-path-pattern: /static/** # 静态资源路径; 注意:如果不配置,则 throw-exception-if-no-handler-found 不生效!!! TODO 芋艿:不能配置,会导致 swagger 不生效
# Jackson 配置项
# Jackson 配置项y
jackson:
serialization:
write-dates-as-timestamps: true # 设置 Date 的格式,使用时间戳
@ -107,7 +107,7 @@ aj:
cache-number: 1000 # local 缓存的阈值,达到这个值,清除缓存
timing-clear: 180 # local定时清除过期缓存(单位秒),设置为0代表不执行
type: blockPuzzle # 验证码类型 default两种都实例化。 blockPuzzle 滑块拼图 clickWord 文字点选
water-mark: 芋道源码 # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 UnicodeLinux 可能需要转 unicode
water-mark: hhyykk # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 UnicodeLinux 可能需要转 unicode
interference-options: 0 # 滑动干扰项(0/1/2)
req-frequency-limit-enable: false # 接口请求次数一分钟限制是否开启 true|false
req-get-lock-limit: 5 # 验证失败 5 次get接口锁定