pull/1/head
siontion 9 months ago
commit c081840950

@ -3,6 +3,7 @@ package com.chanko.yunxi.mes.framework.common.util.io;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
@ -64,7 +65,7 @@ public class FileUtils {
}
/**
*
* 使
*
* @param content
* @param originalName
@ -81,4 +82,20 @@ public class FileUtils {
return sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content));
}
/**
* uuid
*
* @param originalName
* @return path
*/
public static String generatePath(String originalName) {
String uuid = UUID.randomUUID().toString(true);
// 情况一:如果存在 name则优先使用 name 的后缀
if (StrUtil.isNotBlank(originalName)) {
String extName = FileNameUtil.extName(originalName);
return StrUtil.isBlank(extName) ? uuid : uuid + "." + extName;
}
return uuid;
}
}

@ -10,7 +10,8 @@ import lombok.Getter;
@Getter
public enum BusinesTypeEnum {
PROJECT_ORDER("销售订单");
PROJECT_ORDER("销售订单"),
PROJECT_ORDER_SNAPSHOT("销售订单快照");
private String description;

@ -11,6 +11,7 @@ import lombok.Getter;
public enum ProjectOrderStatusEnum {
REPULSE(3, "已打回"),
SAVE(4, "已保存"),
ALTER(8, "发起变更"),
SUBMIT_AUDIT(8, "已送审"),
AUDIT(16, "已审核"),
APPROVE(32, "已启动"),

@ -32,6 +32,11 @@
<artifactId>mes-module-system-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.chanko.yunxi</groupId>
<artifactId>mes-module-infra-biz</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
@ -117,6 +122,12 @@
<artifactId>mes-spring-boot-starter-file</artifactId>
</dependency>
<dependency>
<groupId>com.github.dadiyang</groupId>
<artifactId>equator</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
</project>

@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -67,6 +68,7 @@ public class ProjectOrderController {
@Operation(summary = "操作项目订单")
@PreAuthorize("@ss.hasPermission('heli:project-order:update')")
@OperateLog(enable = false)
@Transactional(rollbackFor = Exception.class)
public CommonResult<Long> operateProjectOrder(@Valid @RequestBody ProjectOrderSaveReqVO operateReqVO) {
LocalDateTime startTime = LocalDateTime.now();
projectOrderService.operateProjectOrder(operateReqVO);
@ -78,6 +80,14 @@ public class ProjectOrderController {
operateReqVO.getId(),
OperateTypeEnum.valueOf(operateReqVO.getActive()).getType(),
operateReqVO.getActiveOpinion());
// 批准、终止记录快照
switch (OperateTypeEnum.valueOf(operateReqVO.getActive())){
case APPROVE:
case TERMINATE:
projectOrderService.createProjectOrderSnapshot(operateReqVO);
break;
}
return success(operateReqVO.getId());
}

@ -113,4 +113,21 @@ public class ProjectOrderPageReqVO extends PageParam {
@Schema(description = "客户名称")
private String businessManName;
@Schema(description = "是否快照")
private Integer isSnapshot;
@Schema(description = "快照原始id", example = "19436")
private Long snapshotId;
@Schema(description = "快照原始单据号")
private String snapshotCode;
@Schema(description = "单据日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] orderTime;
@Schema(description = "快照原始单据日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] snapshotOrderTime;
}

@ -1,15 +1,15 @@
package com.chanko.yunxi.mes.module.heli.controller.admin.projectorder.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.chanko.yunxi.mes.framework.excel.core.annotations.DictFormat;
import com.chanko.yunxi.mes.framework.excel.core.convert.DictConvert;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.util.*;
import lombok.Data;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
import com.chanko.yunxi.mes.framework.excel.core.annotations.DictFormat;
import com.chanko.yunxi.mes.framework.excel.core.convert.DictConvert;
import java.util.Set;
@Schema(description = "管理后台 - 项目订单 Response VO")
@Data
@ -152,4 +152,28 @@ public class ProjectOrderRespVO {
@ExcelProperty("合同编号")
private String contractNo;
@Schema(description = "是否快照", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty(value = "是否快照", converter = DictConvert.class)
@DictFormat("heli_common_is_or_not") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer isSnapshot;
@Schema(description = "快照原始id", example = "19436")
@ExcelProperty("快照原始id")
private Long snapshotId;
@Schema(description = "快照原始单据号")
@ExcelProperty("快照原始单据号")
private String snapshotCode;
@Schema(description = "单据日期", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("单据日期")
private LocalDateTime orderTime;
@Schema(description = "快照原始单据日期")
@ExcelProperty("快照原始单据日期")
private LocalDateTime snapshotOrderTime;
@Schema(description = "变更的字段列表")
private Set<String> alterFieldNames;
}

@ -102,7 +102,6 @@ public class ProjectOrderSaveReqVO {
private Integer hasBlueprint;
@Schema(description = "图纸/数模 说明", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
@NotEmpty(message = "图纸/数模 说明不能为空")
private String blueprintRemark;
@Schema(description = "状态,1表示正常2表示禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ -126,4 +125,19 @@ public class ProjectOrderSaveReqVO {
@Schema(description = "项目订单子项目列表")
private List<ProjectOrderSubDO> projectOrderSubs;
@Schema(description = "是否快照", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer isSnapshot;
@Schema(description = "快照原始id", example = "19436")
private Long snapshotId;
@Schema(description = "快照原始单据号")
private String snapshotCode;
@Schema(description = "单据日期", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime orderTime;
@Schema(description = "快照原始单据日期")
private LocalDateTime snapshotOrderTime;
}

@ -1,18 +1,18 @@
package com.chanko.yunxi.mes.module.heli.dal.dataobject.projectorder;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.chanko.yunxi.mes.framework.mybatis.core.dataobject.BaseDO;
import com.chanko.yunxi.mes.framework.operatelog.core.enums.OperateTypeEnum;
import com.chanko.yunxi.mes.module.heli.enums.ProjectOrderStatusEnum;
import com.chanko.yunxi.mes.module.heli.enums.YesOrNoEnum;
import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.chanko.yunxi.mes.framework.mybatis.core.dataobject.BaseDO;
import java.util.Set;
/**
* DO
@ -164,6 +164,28 @@ public class ProjectOrderDO extends BaseDO {
*
*/
private String contractNo;
/**
*
*
* {@link TODO heli_common_is_or_not }
*/
private Integer isSnapshot;
/**
* id
*/
private Long snapshotId;
/**
*
*/
private String snapshotCode;
/**
*
*/
private LocalDateTime orderTime;
/**
*
*/
private LocalDateTime snapshotOrderTime;
@TableField(exist = false)
private String businessDeptName;
@ -174,6 +196,12 @@ public class ProjectOrderDO extends BaseDO {
@TableField(exist = false)
private String businessManName;
/**
*
* */
@TableField(exist = false)
private Set<String> alterFieldNames;
public boolean canSave(){
return this.orderStatus.intValue() <= ProjectOrderStatusEnum.SAVE.getCode();
}

@ -1,11 +1,13 @@
package com.chanko.yunxi.mes.module.heli.dal.dataobject.projectordersub;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.chanko.yunxi.mes.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
import java.util.Set;
/**
* DO
@ -64,5 +66,10 @@ public class ProjectOrderSubDO extends BaseDO {
*
*/
private Boolean deleted;
/**
*
* */
@TableField(exist = false)
private Set<String> alterFieldNames;
}

@ -35,7 +35,10 @@ public interface ProjectOrderMapper extends BaseMapperX<ProjectOrderDO> {
.eq(reqVO.getHasPrice() != null, ProjectOrderDO::getHasPrice, reqVO.getHasPrice())
.eq(reqVO.getOrderStatus() != null, ProjectOrderDO::getOrderStatus, reqVO.getOrderStatus())
.eq(reqVO.getDeliveryStatus() != null, ProjectOrderDO::getDeliveryStatus, reqVO.getDeliveryStatus())
.in(reqVO.getOrderStatusList() != null && !reqVO.getOrderStatusList().isEmpty(), ProjectOrderDO::getOrderStatus, reqVO.getOrderStatusList());
.in(reqVO.getOrderStatusList() != null && !reqVO.getOrderStatusList().isEmpty(), ProjectOrderDO::getOrderStatus, reqVO.getOrderStatusList())
.eq(reqVO.getIsSnapshot() != null, ProjectOrderDO::getIsSnapshot, reqVO.getIsSnapshot())
.like(!StringUtils.isEmpty(reqVO.getSnapshotCode()), ProjectOrderDO::getSnapshotCode, reqVO.getSnapshotCode());
;
return selectPage(reqVO, query);
}

@ -68,4 +68,10 @@ public interface ProjectOrderService {
* @param operateReqVO
*/
void operateProjectOrder(ProjectOrderSaveReqVO operateReqVO);
/**
*
* @param operateReqVO
*/
void createProjectOrderSnapshot(ProjectOrderSaveReqVO operateReqVO);
}

@ -14,16 +14,24 @@ import com.chanko.yunxi.mes.module.heli.dal.mysql.projectorder.ProjectOrderMappe
import com.chanko.yunxi.mes.module.heli.dal.mysql.projectorder.ProjectOrderSubMapper;
import com.chanko.yunxi.mes.module.heli.enums.BusinesTypeEnum;
import com.chanko.yunxi.mes.module.heli.enums.ProjectOrderStatusEnum;
import com.chanko.yunxi.mes.module.heli.enums.YesOrNoEnum;
import com.chanko.yunxi.mes.module.heli.service.customer.CustomerService;
import com.chanko.yunxi.mes.module.heli.service.serialnumber.SerialNumberService;
import com.chanko.yunxi.mes.module.infra.controller.admin.file.vo.file.FilePageReqVO;
import com.chanko.yunxi.mes.module.infra.dal.dataobject.file.FileDO;
import com.chanko.yunxi.mes.module.infra.service.file.FileService;
import com.github.dadiyang.equator.FieldInfo;
import com.github.dadiyang.equator.GetterBaseEquator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.chanko.yunxi.mes.module.heli.enums.CodeEnum.PROJECT_ORDER;
@ -35,10 +43,13 @@ import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.PROJECT_
*
* @author
*/
@Slf4j
@Service
@Validated
public class ProjectOrderServiceImpl implements ProjectOrderService {
private static final GetterBaseEquator FIELD_EQUATOR = new GetterBaseEquator();
@Resource
private ProjectOrderMapper projectOrderMapper;
@Resource
@ -50,10 +61,14 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
@Resource
private CustomerService customerService;
@Resource
private FileService fileService;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createProjectOrder(ProjectOrderSaveReqVO createReqVO) {
// 插入
createReqVO.setOrderTime(LocalDateTime.now());
ProjectOrderDO projectOrder = BeanUtils.toBean(createReqVO, ProjectOrderDO.class);
// 月度流水号
SerialNumberDO serialNumberDO = serialNumberService.getSerialNumber(BusinesTypeEnum.PROJECT_ORDER.name(), new SimpleDateFormat("yyyyMM").format(new Date()));
@ -65,7 +80,7 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
// 插入子表
createProjectOrderSubList(projectOrder.getId(), createReqVO.getProjectOrderSubs());
createReqVO.setId(projectOrder.getId());
createReqVO.setId(projectOrder.getId()).setCode(projectOrder.getCode());
// 回写序列记录
serialNumberService.updateSerialNumber(serialNumberDO);
@ -73,6 +88,44 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
return projectOrder.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void createProjectOrderSnapshot(ProjectOrderSaveReqVO createReqVO) {
ProjectOrderDO projectOrder = BeanUtils.toBean(createReqVO, ProjectOrderDO.class);
// 快照流水号
SerialNumberDO serialNumberDO = serialNumberService.getSerialNumber(BusinesTypeEnum.PROJECT_ORDER_SNAPSHOT.name(), projectOrder.getCode());
serialNumberDO.setSerialNumber(serialNumberDO.getSerialNumber()+1);
projectOrder.setId(null)
.setIsSnapshot(YesOrNoEnum.YES.getCode())
.setSnapshotId(createReqVO.getId())
.setSnapshotCode(createReqVO.getCode())
.setSnapshotOrderTime(createReqVO.getOrderTime())
.setCode(String.format("%s-%s", createReqVO.getCode(), serialNumberDO.getSerialNumber().intValue()))
.setOrderTime(LocalDateTime.now())
;
projectOrderMapper.insert(projectOrder);
// 子项目
createProjectOrderSubList(projectOrder.getId(), createReqVO.getProjectOrderSubs());
// 附件
PageResult<FileDO> filePage = fileService.getFilePage(new FilePageReqVO() {{
setPageNo(1);
setPageSize(99);
setBusinessId(createReqVO.getId());
setBusinessType(BusinesTypeEnum.PROJECT_ORDER.name());
}});
if(filePage.getTotal() > 0){
List<FileDO> list = filePage.getList();
list.forEach(fileDO -> {
fileDO.setId(null)
.setBusinessId(projectOrder.getId())
.setBusinessType(BusinesTypeEnum.PROJECT_ORDER_SNAPSHOT.name());
});
fileService.insertBatch(list);
}
// 回写序列记录
serialNumberService.updateSerialNumber(serialNumberDO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateProjectOrder(ProjectOrderSaveReqVO updateReqVO) {
@ -85,6 +138,7 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
ProjectOrderDO updateObj = BeanUtils.toBean(updateReqVO, ProjectOrderDO.class);
updateObj.setOrderStatus(ProjectOrderStatusEnum.valueOf(updateReqVO.getActive()).getCode());
projectOrderMapper.updateById(updateObj);
updateReqVO.setOrderStatus(updateObj.getOrderStatus());
// 更新子表
updateProjectOrderSubList(updateReqVO.getId(), updateReqVO.getProjectOrderSubs());
@ -118,7 +172,55 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
@Override
public ProjectOrderDO getProjectOrder(Long id) {
return projectOrderMapper.selectById(id);
ProjectOrderDO projectOrderDO = projectOrderMapper.selectById(id);
// 查询最近归档历史并对比变化字段
try {
ProjectOrderDO lastSnapshot = projectOrderMapper.selectOne(new LambdaQueryWrapper<ProjectOrderDO>() {{
eq(ProjectOrderDO::getSnapshotId, id);
orderByDesc(ProjectOrderDO::getId);
last("LIMIT 1");
}});
if(lastSnapshot != null){
List<FieldInfo> diffFields = FIELD_EQUATOR.getDiffFields(projectOrderDO, lastSnapshot);
projectOrderDO.setAlterFieldNames(diffFields.stream().map(FieldInfo::getFieldName).collect(Collectors.toSet()));
// 附件
List<FileDO> fileList = new ArrayList<>(16);
PageResult<FileDO> filePage = fileService.getFilePage(new FilePageReqVO() {{
setPageNo(1);
setPageSize(99);
setBusinessId(id);
setBusinessType(BusinesTypeEnum.PROJECT_ORDER.name());
}});
if(filePage.getTotal() > 0) {
fileList.addAll(filePage.getList());
}
List<FileDO> lastSnapshotFilelist = new ArrayList<>(16);;
PageResult<FileDO> lastSnapshotFilePage = fileService.getFilePage(new FilePageReqVO() {{
setPageNo(1);
setPageSize(99);
setBusinessId(lastSnapshot.getId());
setBusinessType(BusinesTypeEnum.PROJECT_ORDER_SNAPSHOT.name());
}});
if(lastSnapshotFilePage.getTotal() > 0) {
lastSnapshotFilelist.addAll(lastSnapshotFilePage.getList());
}
if(fileList.size() != lastSnapshotFilelist.size()){
projectOrderDO.getAlterFieldNames().add("attachments");
}else{
boolean allMatch = fileList.stream().allMatch(fileDO -> lastSnapshotFilelist.stream().anyMatch(sFile -> fileDO.getPath().equals(sFile.getPath())));
if(!allMatch){
projectOrderDO.getAlterFieldNames().add("attachments");
}
}
}
}catch (Exception e){
// do nothing
log.error("generate alterFieldNames error, id: {}, exception: {}", id, e.getMessage(), e);
}
return projectOrderDO;
}
@Override
@ -130,7 +232,31 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
@Override
public List<ProjectOrderSubDO> getProjectOrderSubListByProjectOrderId(Long projectOrderId) {
return projectOrderSubMapper.selectListByProjectOrderId(projectOrderId);
List<ProjectOrderSubDO> projectOrderSubDOList = projectOrderSubMapper.selectListByProjectOrderId(projectOrderId);
if(!projectOrderSubDOList.isEmpty()){
// 查询最近归档历史并对比变化字段
try {
ProjectOrderDO lastSnapshot = projectOrderMapper.selectOne(new LambdaQueryWrapper<ProjectOrderDO>() {{
eq(ProjectOrderDO::getSnapshotId, projectOrderId);
orderByDesc(ProjectOrderDO::getId);
last("LIMIT 1");
}});
if(lastSnapshot != null){
List<ProjectOrderSubDO> lastSnapshotSubDOList = projectOrderSubMapper.selectList(ProjectOrderSubDO::getProjectOrderId, lastSnapshot.getId());
Map<String, List<ProjectOrderSubDO>> nameGroups = lastSnapshotSubDOList.stream().collect(Collectors.groupingBy(ProjectOrderSubDO::getName));
projectOrderSubDOList.forEach(projectOrderSubDO -> {
List<ProjectOrderSubDO> lastSnapshotSubs = nameGroups.get(projectOrderSubDO.getName());
if(lastSnapshotSubs.isEmpty()) return;
List<FieldInfo> diffFields = FIELD_EQUATOR.getDiffFields(projectOrderSubDO, lastSnapshotSubs.get(0));
projectOrderSubDO.setAlterFieldNames(diffFields.stream().map(FieldInfo::getFieldName).collect(Collectors.toSet()));
});
}
}catch (Exception e){
log.error("generate sub alterFieldNames error, id: {}, exception: {}", projectOrderId, e.getMessage(), e);
}
}
return projectOrderSubDOList;
}
@Override
@ -144,7 +270,7 @@ public class ProjectOrderServiceImpl implements ProjectOrderService {
}
private void createProjectOrderSubList(Long projectOrderId, List<ProjectOrderSubDO> list) {
list.forEach(o -> o.setProjectOrderId(projectOrderId));
list.forEach(o -> o.setId(null).setProjectOrderId(projectOrderId));
projectOrderSubMapper.insertBatch(list);
}

@ -83,7 +83,7 @@ public class SerialNumberServiceImpl implements SerialNumberService {
@Transactional(rollbackFor = Exception.class)
public SerialNumberDO getSerialNumber(String businessType, String segment) {
LambdaQueryWrapperX<SerialNumberDO> query = new LambdaQueryWrapperX<SerialNumberDO>() {{
eq(SerialNumberDO::getBusinessType, BusinesTypeEnum.PROJECT_ORDER.name());
eq(SerialNumberDO::getBusinessType, businessType);
eq(SerialNumberDO::getSegment, segment);
last("LIMIT 1 FOR UPDATE");
}};

@ -71,6 +71,15 @@ public class FileController {
return success(true);
}
@DeleteMapping("/deleteLogic")
@Operation(summary = "删除文件(逻辑删除)")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
public CommonResult<Boolean> deleteFileLogic(@RequestParam("id") Long id) throws Exception {
fileService.deleteFileLogic(id);
return success(true);
}
@GetMapping("/{configId}/get/**")
@PermitAll
@Operation(summary = "下载文件")

@ -4,6 +4,8 @@ import com.chanko.yunxi.mes.framework.common.pojo.PageResult;
import com.chanko.yunxi.mes.module.infra.controller.admin.file.vo.file.FilePageReqVO;
import com.chanko.yunxi.mes.module.infra.dal.dataobject.file.FileDO;
import java.util.List;
/**
* Service
*
@ -48,4 +50,15 @@ public interface FileService {
*/
byte[] getFileContent(Long configId, String path) throws Exception;
/**
*
* @param id
*/
void deleteFileLogic(Long id);
/**
*
* @param fileDOList
*/
void insertBatch(List<FileDO> fileDOList);
}

@ -14,6 +14,8 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.chanko.yunxi.mes.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
@ -42,7 +44,7 @@ public class FileServiceImpl implements FileService {
// 计算默认的 path 名
String type = FileTypeUtils.getMineType(content, name);
if (StrUtil.isEmpty(path)) {
path = FileUtils.generatePath(content, name);
path = FileUtils.generatePath(name);
}
// 如果 name 为空,则使用 path 填充
if (StrUtil.isEmpty(name)) {
@ -98,4 +100,17 @@ public class FileServiceImpl implements FileService {
return client.getContent(path);
}
@Override
public void deleteFileLogic(Long id) {
// 校验存在
validateFileExists(id);
// 删除记录
fileMapper.deleteById(id);
}
@Override
public void insertBatch(List<FileDO> fileDOList){
fileMapper.insertBatch(fileDOList);
}
}

@ -20,6 +20,18 @@
</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.chanko.yunxi</groupId>
<artifactId>mes-module-system-biz</artifactId>
@ -39,11 +51,6 @@
<artifactId>mes-module-heli-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.dadiyang</groupId>
<artifactId>equator</artifactId>
<version>1.0.4</version>
</dependency>
<!-- 会员中心。默认注释,保证编译速度 -->
<!-- <dependency>-->

@ -32,7 +32,11 @@ export interface ProjectOrderVO {
active: string
activeOpinion: string
projectOrderSubs: any
isSnapshot: number
snapshotId: number
snapshotCode: string
orderTime: Date
snapshotOrderTime: Date
}
// 查询项目订单分页

@ -23,3 +23,8 @@ export const deleteFile = (id: number) => {
export const downloadFile = async (url) => {
return await request.download({ url: url })
}
// 删除文件
export const deleteFileLogic = (id: number) => {
return request.delete({ url: '/infra/file/deleteLogic?id=' + id })
}

@ -300,6 +300,8 @@ export default {
audit: 'Audit',
approve: 'Approve',
terminate: 'Terminate',
detailArchive: 'Detail',
alter: 'Alter',
typeCreate: 'Dict Type Create',
typeUpdate: 'Dict Type Eidt',
dataCreate: 'Dict Data Create',

@ -301,6 +301,8 @@ export default {
audit: '审核',
approve: '批准',
terminate: '终止',
detailArchive: '详情',
alter: '变更',
typeCreate: '字典类型新增',
typeUpdate: '字典类型编辑',
dataCreate: '字典数据新增',

@ -232,4 +232,5 @@ export enum DICT_TYPE {
HELI_PROJECT_ORDER_SUB_UNIT = 'heli_project_order_sub_unit', // 子项目单位
HELI_PROJECT_ORDER_AUDIT_STATUS = 'heli_project_order_audit_status', // 项目单据审核页状态
HELI_PROJECT_ORDER_APPROVE_STATUS = 'heli_project_order_approve_status', // 项目单据批准页状态
HELI_PROJECT_ORDER_ALTER_STATUS = 'heli_project_order_alter_status', // 项目单据变更页状态
}

@ -123,7 +123,7 @@
fixed
label="订单日期"
align="center"
prop="createTime"
prop="orderTime"
:formatter="dateFormatter2"
width="180"
/>
@ -263,6 +263,11 @@ const queryParams = reactive({
status: undefined,
createTime: [],
businessManName: undefined,
isSnapshot: 0,
snapshotId: undefined,
snapshotCode: undefined,
orderTime: [],
snapshotOrderTime: [],
})
const queryFormRef = ref() //
const exportLoading = ref(false) //

@ -0,0 +1,338 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="项目编号" prop="snapshotCode">
<el-input
v-model="queryParams.snapshotCode"
placeholder="请输入项目编号"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="客户名称" prop="customerName">
<el-input
v-model="queryParams.customerName"
placeholder="请输入客户名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="业务员" prop="businessManName">
<el-input
v-model="queryParams.businessManName"
placeholder="请输入业务员"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="模具名称" prop="mouldName">
<el-input
v-model="queryParams.mouldName"
placeholder="请输入模具名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="是否有价格" prop="hasPrice">
<el-select
v-model="queryParams.hasPrice"
placeholder="请选择是否有价格"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_COMMON_IS_OR_NOT)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="单据状态" prop="orderStatus">
<el-select
v-model="queryParams.orderStatus"
placeholder="请选择单据状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_PROJECT_ORDER_ALTER_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="发货状态" prop="deliveryStatus">
<el-select
v-model="queryParams.deliveryStatus"
placeholder="请选择发货状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_DELIVERY_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<!-- <el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['heli:project-order:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>-->
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column fixed label="序号" type="index" width="100"/>
<el-table-column fixed label="项目编号" align="center" prop="snapshotCode" width="240"/>
<el-table-column
fixed
label="归档日期"
align="center"
prop="orderTime"
:formatter="dateFormatter2"
width="180"
/>
<el-table-column
fixed
label="订单日期"
align="center"
prop="snapshotOrderTime"
:formatter="dateFormatter2"
width="180"
/>
<el-table-column label="提出部门" align="center" prop="businessDeptName" width="150" />
<el-table-column label="业务员" align="center" prop="businessManName" width="150" />
<el-table-column label="客户名称" align="center" prop="customerName" width="240" />
<el-table-column label="合同编号" align="center" prop="contractNo" width="180"/>
<el-table-column label="模具名称" align="center" prop="mouldName" width="180" />
<el-table-column label="所属业务线" align="center" prop="businessLine" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_BUSINESS_LINE" :value="scope.row.businessLine" />
</template>
</el-table-column>
<el-table-column label="是否有价格" align="center" prop="hasPrice" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_COMMON_IS_OR_NOT" :value="scope.row.hasPrice" />
</template>
</el-table-column>
<el-table-column label="价格(元)" align="center" prop="price" width="150"/>
<el-table-column label="币种" align="center" prop="currency" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_CURRENCY" :value="scope.row.currency" />
</template>
</el-table-column>
<el-table-column label="是否紧急" align="center" prop="isUrgency" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_COMMON_IS_OR_NOT" :value="scope.row.isUrgency" />
</template>
</el-table-column>
<el-table-column label="性质" align="center" prop="property" width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_PROJECT_PROPERTY" :value="scope.row.property" />
</template>
</el-table-column>
<el-table-column label="起止日期" align="center" prop="projectStartTime" width="260">
<template #default="scope">
{{formatDate(scope.row.projectStartTime,'YYYY-MM-DD') + '~' + formatDate(scope.row.projectEndTime, 'YYYY-MM-DD')}}
</template>
</el-table-column>
<el-table-column label="是否已变更" align="center" prop="hasAlter" width="150">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_COMMON_IS_OR_NOT" :value="scope.row.hasAlter" />
</template>
</el-table-column>
<el-table-column label="单据状态" align="center" prop="orderStatus" fixed="right" width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_PROJECT_ORDER_STATUS" :value="scope.row.orderStatus" />
</template>
</el-table-column>
<el-table-column label="发货状态" align="center" prop="deliveryStatus" fixed="right" width="120">
<template #default="scope">
<dict-tag :type="DICT_TYPE.HELI_DELIVERY_STATUS" :value="scope.row.deliveryStatus" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="260">
<template #default="scope">
<el-button
link
type="primary"
@click="openDetail('detailArchive', scope.row.id)"
>
查看详情
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
</template>
<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import {dateFormatter, dateFormatter2, formatDate} from '@/utils/formatTime'
import download from '@/utils/download'
import * as ProjectOrderApi from '@/api/heli/projectorder'
defineOptions({ name: 'ProjectOrderArchive' })
const message = useMessage() //
const { t } = useI18n() //
const router = useRouter();
const { query } = useRoute()
const loading = ref(true) //
const list = ref([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
orderStatus: undefined,
deliveryStatus: undefined,
businessDeptId: undefined,
customerName: undefined,
mouldName: undefined,
businessLine: undefined,
blueprintNo: undefined,
hasPrice: undefined,
price: undefined,
currency: undefined,
projectStartTime: [],
projectEndTime: [],
isUrgency: undefined,
property: undefined,
referenceTechnology: undefined,
hasAlter: undefined,
lastAlterTime: [],
qualityRequirement: undefined,
remark: undefined,
hasContract: undefined,
hasTechnologyProtocol: undefined,
hasBlueprint: undefined,
blueprintRemark: undefined,
status: undefined,
createTime: [],
businessManName: undefined,
isSnapshot: 1,
snapshotId: undefined,
snapshotCode: query.code,
orderTime: [],
snapshotOrderTime: [],
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ProjectOrderApi.getProjectOrderPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const openDetail = (type: string, id?: number) => {
router.push({
name: 'ProjectOrderDetail',
query: {
active: type,
id: id
}
})
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await ProjectOrderApi.deleteProjectOrder(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await ProjectOrderApi.exportProjectOrder(queryParams)
download.excel(data, '项目订单.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
onActivated(() => {
getList()
})
</script>
<style scoped>
.el-dropdown-link {
cursor: pointer;
color: var(--el-color-primary);
display: flex;
align-items: center;
}
</style>

@ -123,7 +123,7 @@
fixed
label="订单日期"
align="center"
prop="createTime"
prop="orderTime"
:formatter="dateFormatter2"
width="180"
/>
@ -255,6 +255,11 @@ const queryParams = reactive({
status: undefined,
createTime: [],
businessManName: undefined,
isSnapshot: 0,
snapshotId: undefined,
snapshotCode: undefined,
orderTime: [],
snapshotOrderTime: [],
})
const queryFormRef = ref() //
const exportLoading = ref(false) //

@ -7,7 +7,7 @@
<img src="/src/assets/imgs/status/status16.png" v-if="formData.orderStatus == 16" alt="" />
<img src="/src/assets/imgs/status/status3.png" v-else-if="formData.orderStatus == 3" alt="" />
<img src="/src/assets/imgs/status/status8.png" v-else-if="formData.orderStatus == 8" alt="" />
<div v-else-if="formData.orderStatus == 32" class="shipments">
<div v-else-if="query.active != 'detailArchive' && formData.orderStatus == 32" class="shipments">
<div v-if="formData.deliveryStatus == 3">
<span class="shipmentsfont">已发货</span>
</div>
@ -27,9 +27,9 @@
>距交货还有{{ betweenDay(new Date(), new Date(formData.projectEndTime)) + 1 }}
</span>
</div>
<img src="/src/assets/imgs/status/status32.png" alt="" />
</div>
</div>
<img v-else-if="formData.orderStatus == 32" src="/src/assets/imgs/status/status32.png" alt="" />
<img
src="/src/assets/imgs/status/status64.png"
v-else-if="formData.orderStatus == 64"
@ -53,11 +53,19 @@
<el-col :span="24">
<el-form-item label="项目编号" prop="code">
<el-input
v-if="query.active != 'detailArchive'"
disabled
v-model="formData.code"
class="!w-250px"
placeholder="系统自动生成"
/>
<el-input
v-else
disabled
v-model="formData.snapshotCode"
class="!w-250px"
placeholder="系统自动生成"
/>
</el-form-item>
</el-col>
</el-row>
@ -101,7 +109,6 @@
<el-col :span="24">
<el-form-item label="项目开始日期" prop="projectStartTime">
<el-date-picker
class="!w-250px"
v-model="formData.projectStartTime"
type="date"
value-format="x"
@ -119,6 +126,7 @@
:disabled="detailDisabled"
v-model="formData.referenceTechnology"
placeholder="请输入可引用的原有技术"
:class="{'alter-class': fieldHasAlter('referenceTechnology')}"
/>
</el-form-item>
</el-col>
@ -134,6 +142,7 @@
placeholder="请输入检验要求"
show-word-limit
maxlength="200"
:class="{'alter-class': fieldHasAlter('referenceTechnology')}"
/>
</el-form-item>
</el-col>
@ -143,7 +152,7 @@
<el-row>
<el-col :span="24">
<el-form-item label="单据日期" prop="orderTime">
{{ formatDate(formData.orderTime, 'YYYY-MM-DD') }}
{{ query.active != 'detailArchive' ? formatDate(formData.orderTime, 'YYYY-MM-DD') : formatDate(formData.snapshotOrderTime, 'YYYY-MM-DD')}}
</el-form-item>
</el-col>
</el-row>
@ -190,6 +199,7 @@
<el-form-item label="项目结束日期" prop="projectEndTime">
<el-date-picker
class="!w-250px"
:class="{'alter-class': fieldHasAlter('projectEndTime')}"
v-model="formData.projectEndTime"
type="date"
value-format="x"
@ -249,7 +259,9 @@
<el-row>
<el-col :span="24">
<el-form-item label="是否有价格" prop="hasPrice">
<el-radio-group v-model="formData.hasPrice" :disabled="detailDisabled">
<el-radio-group v-model="formData.hasPrice" :disabled="detailDisabled"
:class="{'alter-class': fieldHasAlter('hasPrice')}"
>
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_COMMON_IS_OR_NOT)"
:key="dict.value"
@ -264,7 +276,9 @@
<el-row>
<el-col :span="24">
<el-form-item label="是否紧急" prop="isUrgency">
<el-radio-group v-model="formData.isUrgency" :disabled="detailDisabled">
<el-radio-group v-model="formData.isUrgency" :disabled="detailDisabled"
:class="{'alter-class': fieldHasAlter('isUrgency')}"
>
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_COMMON_IS_OR_NOT)"
:key="dict.value"
@ -301,6 +315,7 @@
v-model="formData.remark"
show-word-limit
maxlength="200"
:class="{'alter-class': fieldHasAlter('remark')}"
/>
</el-form-item>
</el-col>
@ -350,12 +365,14 @@
:min="0"
:precision="6"
style="width: 150px"
:class="{'alter-class': fieldHasAlter('price')}"
/>
<el-select
:disabled="detailDisabled"
v-model="formData.currency"
placeholder="请选择币种"
style="width: 100px"
:class="{'alter-class': fieldHasAlter('currency')}"
>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.HELI_CURRENCY)"
@ -373,6 +390,7 @@
<el-form-item label="性质" prop="property">
<el-select
class="!w-250px"
:class="{'alter-class': fieldHasAlter('property')}"
:disabled="detailDisabled"
v-model="formData.property"
placeholder="请选择性质"
@ -398,7 +416,9 @@
<el-row>
<el-col :span="6">
<el-form-item label="有无合同" prop="hasContract">
<el-radio-group :disabled="detailDisabled" v-model="formData.hasContract">
<el-radio-group :disabled="detailDisabled" v-model="formData.hasContract"
:class="{'alter-class': fieldHasAlter('hasContract')}"
>
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_COMMON_IS_OR_NOT)"
:key="dict.value"
@ -411,7 +431,9 @@
</el-col>
<el-col :span="6">
<el-form-item label="有无技术协议" prop="hasTechnologyProtocol">
<el-radio-group :disabled="detailDisabled" v-model="formData.hasTechnologyProtocol">
<el-radio-group :disabled="detailDisabled" v-model="formData.hasTechnologyProtocol"
:class="{'alter-class': fieldHasAlter('hasTechnologyProtocol')}"
>
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_COMMON_IS_OR_NOT)"
:key="dict.value"
@ -424,7 +446,9 @@
</el-col>
<el-col :span="6">
<el-form-item label="有无图纸/数模" prop="hasBlueprint">
<el-radio-group :disabled="detailDisabled" v-model="formData.hasBlueprint">
<el-radio-group :disabled="detailDisabled" v-model="formData.hasBlueprint"
:class="{'alter-class': fieldHasAlter('hasBlueprint')}"
>
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.HELI_COMMON_IS_OR_NOT)"
:key="dict.value"
@ -443,6 +467,7 @@
:disabled="
detailDisabled || (formData.hasBlueprint == 0 && (formData.blueprintRemark = ''))
"
:class="{'alter-class': fieldHasAlter('blueprintRemark')}"
/>
</el-form-item>
</el-col>
@ -455,7 +480,7 @@
<el-row>
<el-col>
<el-card class="hl-incard">
<el-col v-if="'update,create'.indexOf(query.active) > -1">
<el-col v-if="'update,create,alter'.indexOf(query.active) > -1">
<el-button class="hl-addbutton" type="primary" size="large" @click="onAddItem"
>新增</el-button
>
@ -477,7 +502,7 @@
class="mb-0px!"
>
<el-input
:disabled="detailDisabled"
:disabled="detailDisabled || row.id"
v-model="row.name"
placeholder="请输入子项目名称"
/>
@ -492,7 +517,7 @@
class="mb-0px!"
>
<el-input
:disabled="detailDisabled"
:disabled="detailDisabled || (alterDisabled && row.id)"
v-model="row.deviceModel"
placeholder="请输入设备型号"
/>
@ -512,6 +537,7 @@
placeholder="请输入数量"
:min="0"
:precision="0"
:class="{'alter-class': fieldHasAlterInRow('amount', row)}"
/>
</el-form-item>
</template>
@ -527,6 +553,7 @@
:disabled="detailDisabled"
v-model="row.unit"
placeholder="请选择单位"
:class="{'alter-class': fieldHasAlterInRow('unit', row)}"
>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.HELI_PROJECT_ORDER_SUB_UNIT)"
@ -556,6 +583,7 @@
filterable
:loading="compositionSelectLoading"
:disabled="detailDisabled"
:class="{'alter-class': fieldHasAlterInRow('compositionId', row)}"
>
<el-option
v-for="item in compositionSelectList"
@ -578,6 +606,7 @@
:disabled="detailDisabled"
v-model="row.remark"
placeholder="请输入备注"
:class="{'alter-class': fieldHasAlterInRow('remark', row)}"
/>
</el-form-item>
</template>
@ -603,11 +632,15 @@
</el-card>
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">附件信息</span>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text"
>附件信息</span>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-card class="hl-incard"
:class="{'alter-class': fieldHasAlter('attachments')}"
>
<el-col v-if="'update,create,alter'.indexOf(query.active) > -1">
<el-upload
ref="contractUploadRef"
@ -689,7 +722,7 @@
</el-col>
</el-row>
</el-card>
<el-card class="hl-card-info">
<el-card class="hl-card-info" v-if="query.active != 'detailArchive'">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">操作日志</span>
</template>
@ -707,7 +740,7 @@
label="操作时间"
align="center"
prop="startTime"
width="180"
width="220"
:formatter="dateFormatter"
/>
<el-table-column prop="content" label="操作意见" align="center" />
@ -752,7 +785,7 @@
@click="submitForm('ALTER')"
type="danger"
size="large"
>确定变更</el-button
>发起变更</el-button
>
<el-button
v-if="
@ -806,7 +839,7 @@ import * as CustomerApi from '@/api/heli/customer/index'
import * as CompositionApi from '@/api/heli/composition/index'
import { getAccessToken, getTenantId } from '@/utils/auth'
import { UploadUserFile } from 'element-plus'
import { deleteFile, downloadFile, getFilePage } from '@/api/infra/file'
import { deleteFileLogic, downloadFile, getFilePage } from '@/api/infra/file'
import { propTypes } from '@/utils/propTypes'
import download from '@/utils/download'
import { useUserStore } from '@/store/modules/user'
@ -862,7 +895,8 @@ const formData = ref({
snapshotId: undefined,
snapshotCode: undefined,
orderTime: new Date(),
snapshotOrderTime: undefined
snapshotOrderTime: undefined,
alterFieldNames: []
})
const formRules = reactive({
businessDeptId: [{ required: true, message: '提出部门不能为空', trigger: 'blur' }],
@ -891,6 +925,14 @@ const subFormRules = reactive({
status: [{ required: true, message: '状态,1表示正常2表示禁用不能为空', trigger: 'blur' }]
})
const fieldHasAlter = (fieldName) => {
return formData.value.alterFieldNames && formData.value.alterFieldNames.indexOf(fieldName) > -1
}
const fieldHasAlterInRow = (fieldName, row) => {
return row.alterFieldNames && row.alterFieldNames.indexOf(fieldName) > -1
}
const deptList = ref<Tree[]>([]) //
const userList = ref<UserApi.UserVO[]>([]) //
const userSelectList = ref<UserApi.UserVO[]>([])
@ -963,24 +1005,29 @@ const queryData = async (type: string, id?: number) => {
if (id) {
formData.value = await ProjectOrderApi.getProjectOrder(id)
//
formData.value.projectOrderSubs =
await ProjectOrderApi.getProjectOrderSubListByProjectOrderId(id)
formData.value.projectOrderSubs = await ProjectOrderApi.getProjectOrderSubListByProjectOrderId(id)
//
let businessType = 'PROJECT_ORDER';
if(type == 'detailArchive'){
businessType = 'PROJECT_ORDER_SNAPSHOT'
}else{
//
let logParams = {
pageNo: 1,
pageSize: 99,
businessId: id,
businessType: 'PROJECT_ORDER'
businessType: businessType
}
formData.value.operateLogs = (await getOperateLogPage(logParams)).list
}
//
let attParams = {
pageNo: 1,
pageSize: 99,
businessId: id,
businessType: 'PROJECT_ORDER'
businessType: businessType
}
formData.value.attachments = (await getFilePage(attParams)).list
}
@ -1045,9 +1092,13 @@ const submitForm = async (active) => {
if (active != 'REPULSE') {
formData.value.activeOpinion = ''
}
//
if (active == 'ALTER') {
formData.value.hasAlter = 1;
}
const data = formData.value as unknown as ProjectOrderApi.ProjectOrderVO
if (active == 'SUBMIT_AUDIT') {
if ('SUBMIT_AUDIT,ALTER'.indexOf(active) > -1) {
//
if (!data.projectOrderSubs || data.projectOrderSubs.length == 0) {
message.error('子项目信息不能为空')
@ -1055,7 +1106,7 @@ const submitForm = async (active) => {
}
}
if ((active == 'SAVE' || active == 'SUBMIT_AUDIT') && !formData.value.hasAlter) {
if ((active == 'SAVE' || active == 'SUBMIT_AUDIT') && active != 'ALTER') {
// 0
if (data.projectOrderSubs && data.projectOrderSubs.length > 0) {
if (data.projectOrderSubs.some((sub) => !sub.amount || sub.amount <= 0)) {
@ -1065,11 +1116,12 @@ const submitForm = async (active) => {
}
}
//
if (active == 'ALTER') {
// 0
if (data.projectOrderSubs && data.projectOrderSubs.length > 0) {
const total = data.projectOrderSubs.reduce((acc, cur) => {
return acc + cur
return acc + cur.amount
}, 0)
if (total <= 0) {
message.error('子项目数量和不能为0')
@ -1136,7 +1188,8 @@ const onAddItem = () => {
compositionId: undefined,
unit: undefined,
remark: undefined,
status: 1
status: 1,
alterFieldNames: []
}
row.projectOrderId = formData.value.id
formData.value.projectOrderSubs.push(row)
@ -1173,7 +1226,7 @@ const protocolUploadChange = (file, files) => {
}
const refreshAttachments = (files, type) => {
formData.value.attachments = formData.value.attachments.filter((value, index, array) => {
return value.businessFileType != type
return value.businessFileType != type || value.id
})
for (let i = 0; i < files.length; i++) {
let file = files[i]
@ -1183,7 +1236,7 @@ const refreshAttachments = (files, type) => {
}
//
formData.value.attachments.sort((v1, v2) => {
return v1.createTime - v2.createTime < 0
return (v1.createTime - v2.createTime) > 0
})
}
@ -1194,7 +1247,7 @@ const handleDeleteAttachment = async (index, type) => {
const attachment = deletedAttachments[i]
if (attachment.id) {
//
await deleteFile(attachment.id)
await deleteFileLogic(attachment.id)
}
//
contractUploadFiles.value = contractUploadFiles.value.filter((file1) => {
@ -1249,7 +1302,13 @@ const resetForm = () => {
operateLogs: [],
contractNo: undefined,
active: '',
activeOpinion: ''
activeOpinion: '',
isSnapshot: 0,
snapshotId: undefined,
snapshotCode: undefined,
orderTime: new Date(),
snapshotOrderTime: undefined,
alterFieldNames: []
}
formRef.value?.resetFields()
}
@ -1264,7 +1323,7 @@ onMounted(() => {
if (query.active == 'alter') {
alterDisabled.value = true
}
if ('detail,audit,approve,terminate'.indexOf(query.active) > -1) {
if('detail,audit,approve,terminate,detailArchive'.indexOf(query.active) > -1){
detailDisabled.value = true
}
queryData(query.active, query.id)
@ -1281,4 +1340,10 @@ a {
display: inline-block;
margin-right: 20px;
}
.hl-card .alter-class {
position: relative;
border: solid 1px orange;
outline: solid 1px orange;
}
</style>

@ -123,7 +123,7 @@
fixed
label="订单日期"
align="center"
prop="createTime"
prop="orderTime"
:formatter="dateFormatter2"
width="180"
/>
@ -196,7 +196,7 @@
>
编辑
</el-button>
<el-dropdown @command="(command) => handleCommand(command, scope.row.id)">
<el-dropdown @command="(command) => handleCommand(command, scope.row.id, scope.row.code)">
<span class="el-dropdown-link">更多
<el-icon class="el-icon--right">
<arrow-down />
@ -205,9 +205,9 @@
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="detail">查看详情</el-dropdown-item>
<el-dropdown-item command="printProject">打印开发项目启动单</el-dropdown-item>
<el-dropdown-item v-if="scope.row.orderStatus == 32" command="printProject"></el-dropdown-item>
<el-dropdown-item v-if="scope.row.orderStatus == 32" command="alter"></el-dropdown-item>
<el-dropdown-item command="viewAlter">查看变更日志</el-dropdown-item>
<el-dropdown-item v-if="scope.row.hasAlter" command="viewArchive"></el-dropdown-item>
<el-dropdown-item v-if="scope.row.orderStatus == 32" command="delivery"></el-dropdown-item>
</el-dropdown-menu>
</template>
@ -271,6 +271,11 @@ const queryParams = reactive({
status: undefined,
createTime: [],
businessManName: undefined,
isSnapshot: 0,
snapshotId: undefined,
snapshotCode: undefined,
orderTime: [],
snapshotOrderTime: [],
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
@ -338,11 +343,28 @@ const handleExport = async () => {
}
}
const handleCommand = async (command, id) => {
const handleCommand = async (command, id, code) => {
switch (command){
case 'detail':
openDetail('detail', id);
break;
case 'printProject':
// TODO
break;
case 'alter':
openDetail('alter', id);
break;
case 'viewArchive':
router.push({
name: 'ProjectOrderArchive',
query: {
code: code
}
})
break;
case 'delivery':
// TODO
break;
}
}

@ -118,12 +118,17 @@ CREATE TABLE `project_order_sub` (
ALTER TABLE project_order ADD COLUMN `contract_no` VARCHAR ( 128 ) COMMENT '模具名称' AFTER customer_id;
ALTER TABLE project_order_sub ADD COLUMN `unit` CHAR ( 1 ) NOT NULL COMMENT '单位' AFTER amount;
ALTER TABLE project_order ADD COLUMN `order_time` datetime NOT NULL COMMENT '单据日期' AFTER order_status;
ALTER TABLE project_order ADD COLUMN `snapshot_order_time` datetime COMMENT '快照原始单据日期' AFTER blueprint_remark;
ALTER TABLE project_order ADD COLUMN `snapshot_code` VARCHAR ( 64 ) COMMENT '快照原始单据号' AFTER blueprint_remark;
ALTER TABLE project_order ADD COLUMN `snapshot_id` BIGINT ( 20 ) COMMENT '快照原始id' AFTER blueprint_remark;
ALTER TABLE project_order ADD COLUMN `is_snapshot` TINYINT ( 1 ) NOT NULL DEFAULT '0' COMMENT '是否快照' AFTER blueprint_remark;
DROP TABLE IF EXISTS `base_serial_number`;
CREATE TABLE `base_serial_number` (
`id` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT COMMENT '自增字段,唯一',
`business_type` VARCHAR ( 32 ) NOT NULL COMMENT '业务类型 用于业务关联',
`segment` VARCHAR ( 16 ) NOT NULL COMMENT '序列参考段',
`segment` VARCHAR ( 64 ) NOT NULL COMMENT '序列参考段',
`serial_number` BIGINT ( 20 ) NOT NULL DEFAULT '0' COMMENT '序列号',
`status` TINYINT ( 1 ) NOT NULL DEFAULT '1' COMMENT '状态,1表示正常2表示禁用',
`creator` VARCHAR ( 64 ) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',

Loading…
Cancel
Save