Merge branch 'development' of http://pms.dtyx.net:3000/cuizhibin/znpt-backend into development
# Conflicts: # core/src/main/java/com/dite/znpt/service/impl/ProjectServiceImpl.java
This commit is contained in:
commit
e7df0aa244
|
@ -180,6 +180,12 @@ public class EquipmentEntity extends AuditableEntity implements Serializable {
|
||||||
@ApiModelProperty("采购状态,NOT_STARTED-未开始,PENDING_APPROVAL-待审批,APPROVED-已通过,REJECTED-已拒绝,COMPLETED-已完成")
|
@ApiModelProperty("采购状态,NOT_STARTED-未开始,PENDING_APPROVAL-待审批,APPROVED-已通过,REJECTED-已拒绝,COMPLETED-已完成")
|
||||||
private String procurementStatus;
|
private String procurementStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("收货状态,NOT_RECEIVED-未收货,PARTIALLY_RECEIVED-部分收货,RECEIVED-已收货")
|
||||||
|
private String receiptStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("支付状态,NOT_PAID-未支付,PARTIALLY_PAID-部分支付,PAID-已支付")
|
||||||
|
private String paymentStatus;
|
||||||
|
|
||||||
@ApiModelProperty("附件")
|
@ApiModelProperty("附件")
|
||||||
private String attachments;
|
private String attachments;
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,15 @@ public class EquipmentResp implements Serializable {
|
||||||
@ApiModelProperty("采购状态,NOT_STARTED-未开始,PENDING_APPROVAL-待审批,APPROVED-已通过,REJECTED-已拒绝,COMPLETED-已完成")
|
@ApiModelProperty("采购状态,NOT_STARTED-未开始,PENDING_APPROVAL-待审批,APPROVED-已通过,REJECTED-已拒绝,COMPLETED-已完成")
|
||||||
private String procurementStatus;
|
private String procurementStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("收货状态,NOT_RECEIVED-未收货,PARTIALLY_RECEIVED-部分收货,RECEIVED-已收货")
|
||||||
|
private String receiptStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("支付状态,NOT_PAID-未支付,PARTIALLY_PAID-部分支付,PAID-已支付")
|
||||||
|
private String paymentStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("审批状态,PENDING-待审批,APPROVED-已通过,REJECTED-已拒绝")
|
||||||
|
private String approvalStatus;
|
||||||
|
|
||||||
// 移除备用状态字段,使用现有的 location_status 字段
|
// 移除备用状态字段,使用现有的 location_status 字段
|
||||||
// @ApiModelProperty("备用状态")
|
// @ApiModelProperty("备用状态")
|
||||||
// private String spareStatus;
|
// private String spareStatus;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.dite.znpt.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘特图查询请求类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "GanttChartReq", description = "甘特图查询请求")
|
||||||
|
public class GanttChartReq {
|
||||||
|
|
||||||
|
@ApiModelProperty("项目ID")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务组ID")
|
||||||
|
private String taskGroupId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@ApiModelProperty("负责人ID")
|
||||||
|
private String mainUserId;
|
||||||
|
|
||||||
|
@ApiModelProperty("开始时间范围-开始")
|
||||||
|
private LocalDate startDateFrom;
|
||||||
|
|
||||||
|
@ApiModelProperty("开始时间范围-结束")
|
||||||
|
private LocalDate startDateTo;
|
||||||
|
|
||||||
|
@ApiModelProperty("结束时间范围-开始")
|
||||||
|
private LocalDate endDateFrom;
|
||||||
|
|
||||||
|
@ApiModelProperty("结束时间范围-结束")
|
||||||
|
private LocalDate endDateTo;
|
||||||
|
|
||||||
|
@ApiModelProperty("是否包含已完成任务")
|
||||||
|
private Boolean includeCompleted = true;
|
||||||
|
|
||||||
|
@ApiModelProperty("是否只显示逾期任务")
|
||||||
|
private Boolean overdueOnly = false;
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.dite.znpt.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘特图数据响应类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "GanttChartResp", description = "甘特图数据响应")
|
||||||
|
public class GanttChartResp {
|
||||||
|
|
||||||
|
@ApiModelProperty("任务ID")
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务名称")
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务编号")
|
||||||
|
private String taskCode;
|
||||||
|
|
||||||
|
@ApiModelProperty("上级任务ID")
|
||||||
|
private String parentTaskId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务组ID")
|
||||||
|
private String taskGroupId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务组名称")
|
||||||
|
private String taskGroupName;
|
||||||
|
|
||||||
|
@ApiModelProperty("计划开始时间")
|
||||||
|
private LocalDate planStartDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("计划结束时间")
|
||||||
|
private LocalDate planEndDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("实际开始时间")
|
||||||
|
private LocalDate actualStartDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("实际结束时间")
|
||||||
|
private LocalDate actualEndDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务状态:0未开始,1进行中,2已结束")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务状态描述")
|
||||||
|
private String statusDesc;
|
||||||
|
|
||||||
|
@ApiModelProperty("是否逾期:0未逾期,1已逾期")
|
||||||
|
private Integer overdueStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务负责人ID")
|
||||||
|
private String mainUserId;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务负责人姓名")
|
||||||
|
private String mainUserName;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务参与人")
|
||||||
|
private String userIds;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务参与人姓名列表")
|
||||||
|
private List<String> participantNames;
|
||||||
|
|
||||||
|
@ApiModelProperty("进度百分比")
|
||||||
|
private Integer progress;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务层级")
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务在时间轴上的位置(天数)")
|
||||||
|
private Integer position;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务持续时间(天数)")
|
||||||
|
private Integer duration;
|
||||||
|
|
||||||
|
@ApiModelProperty("子任务列表")
|
||||||
|
private List<GanttChartResp> children;
|
||||||
|
|
||||||
|
@ApiModelProperty("任务备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@ApiModelProperty("项目ID")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@ApiModelProperty("项目名称")
|
||||||
|
private String projectName;
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
package com.dite.znpt.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收货请求参数(扩展版,包含完整设备信息)
|
||||||
|
*
|
||||||
|
* @author system
|
||||||
|
* @date 2025-01-08
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "收货请求参数", description = "收货请求参数,包含收货信息和设备信息")
|
||||||
|
public class ReceiptRequest {
|
||||||
|
|
||||||
|
@ApiModelProperty("设备序列号(收货时自动生成)")
|
||||||
|
private String equipmentSn;
|
||||||
|
|
||||||
|
@ApiModelProperty("库存条码(收货时自动生成)")
|
||||||
|
private String inventoryBarcode;
|
||||||
|
|
||||||
|
// 收货特有信息
|
||||||
|
@NotBlank(message = "收货时间不能为空")
|
||||||
|
@ApiModelProperty("收货时间")
|
||||||
|
private String receiptTime;
|
||||||
|
|
||||||
|
@NotBlank(message = "收货人不能为空")
|
||||||
|
@ApiModelProperty("收货人")
|
||||||
|
private String receiptPerson;
|
||||||
|
|
||||||
|
@NotNull(message = "收货数量不能为空")
|
||||||
|
@ApiModelProperty("收货数量")
|
||||||
|
private Integer receiptQuantity;
|
||||||
|
|
||||||
|
@ApiModelProperty("收货备注")
|
||||||
|
private String receiptRemark;
|
||||||
|
|
||||||
|
@NotBlank(message = "外观检查结果不能为空")
|
||||||
|
@ApiModelProperty("外观检查结果")
|
||||||
|
private String appearanceCheck;
|
||||||
|
|
||||||
|
@NotBlank(message = "功能测试结果不能为空")
|
||||||
|
@ApiModelProperty("功能测试结果")
|
||||||
|
private String functionTest;
|
||||||
|
|
||||||
|
@NotBlank(message = "包装完整性不能为空")
|
||||||
|
@ApiModelProperty("包装完整性")
|
||||||
|
private String packageIntegrity;
|
||||||
|
|
||||||
|
@NotBlank(message = "配件完整性不能为空")
|
||||||
|
@ApiModelProperty("配件完整性")
|
||||||
|
private String accessoryIntegrity;
|
||||||
|
|
||||||
|
@NotBlank(message = "检查结果不能为空")
|
||||||
|
@ApiModelProperty("检查结果")
|
||||||
|
private String checkResult;
|
||||||
|
|
||||||
|
@ApiModelProperty("检查备注")
|
||||||
|
private String checkRemark;
|
||||||
|
|
||||||
|
@NotBlank(message = "入库位置不能为空")
|
||||||
|
@ApiModelProperty("入库位置")
|
||||||
|
private String storageLocation;
|
||||||
|
|
||||||
|
@NotBlank(message = "库管员不能为空")
|
||||||
|
@ApiModelProperty("库管员")
|
||||||
|
private String storageManager;
|
||||||
|
|
||||||
|
// 设备基本信息(从采购数据继承)
|
||||||
|
@ApiModelProperty("设备名称")
|
||||||
|
private String equipmentName;
|
||||||
|
|
||||||
|
@ApiModelProperty("设备型号")
|
||||||
|
private String equipmentModel;
|
||||||
|
|
||||||
|
@ApiModelProperty("设备类型")
|
||||||
|
private String equipmentType;
|
||||||
|
|
||||||
|
@ApiModelProperty("品牌")
|
||||||
|
private String brand;
|
||||||
|
|
||||||
|
@ApiModelProperty("配置规格/参数")
|
||||||
|
private String specification;
|
||||||
|
|
||||||
|
@ApiModelProperty("资产编号")
|
||||||
|
private String assetCode;
|
||||||
|
|
||||||
|
// 采购信息(从采购数据继承)
|
||||||
|
@ApiModelProperty("采购订单号")
|
||||||
|
private String purchaseOrder;
|
||||||
|
|
||||||
|
@ApiModelProperty("供应商名称")
|
||||||
|
private String supplierName;
|
||||||
|
|
||||||
|
@ApiModelProperty("采购价格")
|
||||||
|
private BigDecimal purchasePrice;
|
||||||
|
|
||||||
|
@ApiModelProperty("采购时间")
|
||||||
|
private String purchaseTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("数量")
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
@ApiModelProperty("单价")
|
||||||
|
private BigDecimal unitPrice;
|
||||||
|
|
||||||
|
@ApiModelProperty("总价")
|
||||||
|
private BigDecimal totalPrice;
|
||||||
|
|
||||||
|
// 入库信息
|
||||||
|
@ApiModelProperty("入库时间")
|
||||||
|
private String inStockTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("物理位置")
|
||||||
|
private String physicalLocation;
|
||||||
|
|
||||||
|
@ApiModelProperty("位置状态")
|
||||||
|
private String locationStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("负责人")
|
||||||
|
private String responsiblePerson;
|
||||||
|
|
||||||
|
// 状态信息
|
||||||
|
@ApiModelProperty("设备状态")
|
||||||
|
private String equipmentStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("使用状态")
|
||||||
|
private String useStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("健康状态")
|
||||||
|
private String healthStatus;
|
||||||
|
|
||||||
|
@ApiModelProperty("收货状态")
|
||||||
|
private String receiptStatus;
|
||||||
|
|
||||||
|
// 其他管理信息
|
||||||
|
@ApiModelProperty("折旧方法")
|
||||||
|
private String depreciationMethod;
|
||||||
|
|
||||||
|
@ApiModelProperty("折旧年限")
|
||||||
|
private Integer depreciationYears;
|
||||||
|
|
||||||
|
@ApiModelProperty("残值")
|
||||||
|
private BigDecimal salvageValue;
|
||||||
|
|
||||||
|
@ApiModelProperty("当前净值")
|
||||||
|
private BigDecimal currentNetValue;
|
||||||
|
|
||||||
|
// 系统字段
|
||||||
|
@ApiModelProperty("创建时间")
|
||||||
|
private String createTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("更新时间")
|
||||||
|
private String updateTime;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.dite.znpt.enums;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态枚举
|
||||||
|
*
|
||||||
|
* @author system
|
||||||
|
* @date 2025-01-08
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum PaymentStatusEnum {
|
||||||
|
NOT_PAID("NOT_PAID", "未支付"),
|
||||||
|
PARTIALLY_PAID("PARTIALLY_PAID", "部分支付"),
|
||||||
|
PAID("PAID", "已支付");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
PaymentStatusEnum(String code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PaymentStatusEnum getByCode(String code) {
|
||||||
|
for (PaymentStatusEnum e : PaymentStatusEnum.values()) {
|
||||||
|
if (e.code.equals(code)) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescByCode(String code) {
|
||||||
|
PaymentStatusEnum e = getByCode(code);
|
||||||
|
return null == e ? null : e.desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<JSONObject> listAll() {
|
||||||
|
List<JSONObject> list = new ArrayList<>(PaymentStatusEnum.values().length);
|
||||||
|
for (PaymentStatusEnum e : PaymentStatusEnum.values()) {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.set(e.code, e.desc);
|
||||||
|
list.add(jsonObject);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.dite.znpt.enums;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收货状态枚举
|
||||||
|
*
|
||||||
|
* @author system
|
||||||
|
* @date 2025-01-08
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ReceiptStatusEnum {
|
||||||
|
NOT_RECEIVED("NOT_RECEIVED", "未收货"),
|
||||||
|
PARTIALLY_RECEIVED("PARTIALLY_RECEIVED", "部分收货"),
|
||||||
|
RECEIVED("RECEIVED", "已收货");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
ReceiptStatusEnum(String code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReceiptStatusEnum getByCode(String code) {
|
||||||
|
for (ReceiptStatusEnum e : ReceiptStatusEnum.values()) {
|
||||||
|
if (e.code.equals(code)) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescByCode(String code) {
|
||||||
|
ReceiptStatusEnum e = getByCode(code);
|
||||||
|
return null == e ? null : e.desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<JSONObject> listAll() {
|
||||||
|
List<JSONObject> list = new ArrayList<>(ReceiptStatusEnum.values().length);
|
||||||
|
for (ReceiptStatusEnum e : ReceiptStatusEnum.values()) {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.set(e.code, e.desc);
|
||||||
|
list.add(jsonObject);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,4 +36,15 @@ public interface BusinessDataFileMapper {
|
||||||
@Param("newFileName") String newFileName,
|
@Param("newFileName") String newFileName,
|
||||||
@Param("newFilePath") String newFilePath);
|
@Param("newFilePath") String newFilePath);
|
||||||
|
|
||||||
|
// // 批量更新文件路径
|
||||||
|
// void updateFilePathByFolderId(
|
||||||
|
// @Param("folderId") Long folderId,
|
||||||
|
// @Param("newFolderPath") String newFolderPath,
|
||||||
|
// @Param("separator") String separator);
|
||||||
|
|
||||||
|
// 批量更新子文件夹下文件的路径
|
||||||
|
void updateSubFilePaths(@Param("oldParentPath1") String oldParentPath1,
|
||||||
|
@Param("newParentPath1") String newParentPath1,
|
||||||
|
@Param("oldParentPath2") String oldParentPath2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,4 +29,12 @@ public interface BusinessDataMapper {
|
||||||
void reName(BusinessDataEntity businessDataEntity);
|
void reName(BusinessDataEntity businessDataEntity);
|
||||||
|
|
||||||
public List<BusinessDataEntity> ListWithCondition(@Param("folderName") String folderName);
|
public List<BusinessDataEntity> ListWithCondition(@Param("folderName") String folderName);
|
||||||
|
|
||||||
|
// 批量更新子文件夹路径
|
||||||
|
void updateSubFolderPaths(@Param("oldParentPath1") String oldParentPath,
|
||||||
|
@Param("newParentPath1") String newParentPath,
|
||||||
|
@Param("processedOldParentPath") String processedOldParentPath,
|
||||||
|
@Param("processedNewParentPath") String processedNewParentPath,
|
||||||
|
@Param("folderId") Long folderId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.dite.znpt.domain.entity.ProjectTaskEntity;
|
import com.dite.znpt.domain.entity.ProjectTaskEntity;
|
||||||
import com.dite.znpt.domain.vo.ProjectTaskListReq;
|
import com.dite.znpt.domain.vo.ProjectTaskListReq;
|
||||||
import com.dite.znpt.domain.vo.ProjectTaskResp;
|
import com.dite.znpt.domain.vo.ProjectTaskResp;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -13,6 +14,7 @@ import java.util.List;
|
||||||
* @date 2025/06/24 16:44
|
* @date 2025/06/24 16:44
|
||||||
* @Description: 项目任务信息表数据库访问层
|
* @Description: 项目任务信息表数据库访问层
|
||||||
*/
|
*/
|
||||||
|
@Mapper
|
||||||
public interface ProjectTaskMapper extends BaseMapper<ProjectTaskEntity> {
|
public interface ProjectTaskMapper extends BaseMapper<ProjectTaskEntity> {
|
||||||
List<ProjectTaskResp> queryBySelective(ProjectTaskListReq projectTaskReq);
|
List<ProjectTaskResp> queryBySelective(ProjectTaskListReq projectTaskReq);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
@ApiOperation("商务资料文件service")
|
@ApiOperation("商务资料文件service")
|
||||||
@Service
|
@Service
|
||||||
|
@ -40,4 +41,11 @@ public interface BusinessDataFileService {
|
||||||
|
|
||||||
@ApiOperation("预览文件")
|
@ApiOperation("预览文件")
|
||||||
void preview(Long fileId, HttpServletResponse response);
|
void preview(Long fileId, HttpServletResponse response);
|
||||||
|
|
||||||
|
// @ApiOperation("批量更新文件路径")
|
||||||
|
// public void updateFilePathByFolderId(Long folderId, String newFolderPath);
|
||||||
|
|
||||||
|
@ApiOperation("批量更新子文件夹下文件的路径")
|
||||||
|
void updateSubFilePaths(String oldParentPath, String newParentPath);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,6 @@ public interface BusinessDataService {
|
||||||
Result delete(Long folderId);
|
Result delete(Long folderId);
|
||||||
Result reName(Long folderId, String newName);
|
Result reName(Long folderId, String newName);
|
||||||
|
|
||||||
|
void updateSubFolderPaths(String oldParentPath1, String newParentPath1, Long folderId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.dite.znpt.domain.entity.EquipmentEntity;
|
||||||
import com.dite.znpt.domain.vo.EquipmentListReq;
|
import com.dite.znpt.domain.vo.EquipmentListReq;
|
||||||
import com.dite.znpt.domain.vo.EquipmentReq;
|
import com.dite.znpt.domain.vo.EquipmentReq;
|
||||||
import com.dite.znpt.domain.vo.EquipmentResp;
|
import com.dite.znpt.domain.vo.EquipmentResp;
|
||||||
|
import com.dite.znpt.domain.vo.ReceiptRequest;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -53,6 +54,11 @@ public interface EquipmentService extends IService<EquipmentEntity> {
|
||||||
*/
|
*/
|
||||||
Object getProcurementStats();
|
Object getProcurementStats();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认收货并自动入库
|
||||||
|
*/
|
||||||
|
void receiveGoodsAndStockIn(String equipmentId, ReceiptRequest req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出采购记录
|
* 导出采购记录
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.dite.znpt.service;
|
||||||
|
|
||||||
|
import com.dite.znpt.domain.vo.GanttChartReq;
|
||||||
|
import com.dite.znpt.domain.vo.GanttChartResp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘特图服务接口
|
||||||
|
*/
|
||||||
|
public interface GanttChartService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目甘特图数据
|
||||||
|
*
|
||||||
|
* @param req 查询条件
|
||||||
|
* @return 甘特图数据列表
|
||||||
|
*/
|
||||||
|
List<GanttChartResp> getGanttChartData(GanttChartReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目甘特图统计信息
|
||||||
|
*
|
||||||
|
* @param projectId 项目ID
|
||||||
|
* @return 统计信息
|
||||||
|
*/
|
||||||
|
Object getGanttChartStatistics(String projectId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目甘特图时间轴信息
|
||||||
|
*
|
||||||
|
* @param projectId 项目ID
|
||||||
|
* @return 时间轴信息
|
||||||
|
*/
|
||||||
|
Object getGanttChartTimeline(String projectId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新任务进度
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param progress 进度百分比
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
boolean updateTaskProgress(String taskId, Integer progress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拖拽更新任务时间
|
||||||
|
*
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param startDate 开始时间
|
||||||
|
* @param endDate 结束时间
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
boolean updateTaskTime(String taskId, String startDate, String endDate);
|
||||||
|
}
|
|
@ -81,7 +81,8 @@ public class BusinessDataFileServiceImpl implements BusinessDataFileService {
|
||||||
}
|
}
|
||||||
@ApiOperation("删除文件")
|
@ApiOperation("删除文件")
|
||||||
public Result delete(Long fileId, Long folderId) {
|
public Result delete(Long fileId, Long folderId) {
|
||||||
//删除数据库数据
|
//删除文件夹时候,调用这个方法,才会删除所有文件的数据库数据,
|
||||||
|
// 至于具体文件,不用在这个方法删除
|
||||||
if (folderId != null){
|
if (folderId != null){
|
||||||
businessDataFileMapper.delete(null,folderId);
|
businessDataFileMapper.delete(null,folderId);
|
||||||
return Result.okM("删除成功");
|
return Result.okM("删除成功");
|
||||||
|
@ -155,8 +156,11 @@ public class BusinessDataFileServiceImpl implements BusinessDataFileService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建新文件路径
|
// 构建新文件路径
|
||||||
|
// 获取父目录
|
||||||
String parentPath = oldFile.getParent();
|
String parentPath = oldFile.getParent();
|
||||||
|
// 获取文件扩展名
|
||||||
String fileExtension = "";
|
String fileExtension = "";
|
||||||
|
// 获取文件名(不包含扩展名)
|
||||||
String fileNameWithoutExt = newFileName;
|
String fileNameWithoutExt = newFileName;
|
||||||
|
|
||||||
// 获取原文件扩展名
|
// 获取原文件扩展名
|
||||||
|
@ -246,7 +250,7 @@ public class BusinessDataFileServiceImpl implements BusinessDataFileService {
|
||||||
byte[] bytes = file.getBytes();
|
byte[] bytes = file.getBytes();
|
||||||
String uploadDir = businessDataService.getPath(folderId);
|
String uploadDir = businessDataService.getPath(folderId);
|
||||||
|
|
||||||
File uploadedFile = new File(uploadDir + "/" + file.getOriginalFilename());
|
File uploadedFile = new File(uploadDir + File.separator + file.getOriginalFilename());
|
||||||
if (uploadedFile.exists()) {
|
if (uploadedFile.exists()) {
|
||||||
return Result.error("文件已存在");
|
return Result.error("文件已存在");
|
||||||
}
|
}
|
||||||
|
@ -256,7 +260,7 @@ public class BusinessDataFileServiceImpl implements BusinessDataFileService {
|
||||||
BusinessDataFileEntity fileEntity = new BusinessDataFileEntity();
|
BusinessDataFileEntity fileEntity = new BusinessDataFileEntity();
|
||||||
fileEntity.setFolderId(folderId);
|
fileEntity.setFolderId(folderId);
|
||||||
fileEntity.setFileName(file.getOriginalFilename());
|
fileEntity.setFileName(file.getOriginalFilename());
|
||||||
fileEntity.setFilePath(uploadDir + "/" + file.getOriginalFilename());
|
fileEntity.setFilePath(uploadDir + File.separator + file.getOriginalFilename());
|
||||||
fileEntity.setFileType(file.getContentType());
|
fileEntity.setFileType(file.getContentType());
|
||||||
fileEntity.setFileSize(file.getSize()/1024);
|
fileEntity.setFileSize(file.getSize()/1024);
|
||||||
fileEntity.setUploadTime(new Date());
|
fileEntity.setUploadTime(new Date());
|
||||||
|
@ -544,4 +548,21 @@ public class BusinessDataFileServiceImpl implements BusinessDataFileService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ApiOperation("批量更新文件路径")
|
||||||
|
// @Override
|
||||||
|
// public void updateFilePathByFolderId(Long folderId, String newFolderPath) {
|
||||||
|
// businessDataFileMapper.updateFilePathByFolderId(folderId, newFolderPath, File.separator);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@ApiOperation("批量更新子文件夹下文件的路径")
|
||||||
|
@Override
|
||||||
|
public void updateSubFilePaths(String oldParentPath1, String newParentPath1) {
|
||||||
|
// 处理路径中的分隔符,如果是反斜杠则替换为双反斜杠
|
||||||
|
String oldParentPath2 = oldParentPath1;
|
||||||
|
if ("\\".equals(File.separator)) {
|
||||||
|
oldParentPath2 = oldParentPath1.replace("\\", "\\\\");
|
||||||
|
}
|
||||||
|
businessDataFileMapper.updateSubFilePaths(oldParentPath1, newParentPath1, oldParentPath2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class BusinessDataServiceImpl implements BusinessDataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件夹名称前置一个/
|
// 文件夹名称前置一个/
|
||||||
String folderName1 = "/" + folderName;
|
String folderName1 = File.separator + folderName;
|
||||||
// 目标文件夹
|
// 目标文件夹
|
||||||
File targetDir = Paths.get(businessDataPath, folderName1).toFile();
|
File targetDir = Paths.get(businessDataPath, folderName1).toFile();
|
||||||
if (parentId != 0L) {
|
if (parentId != 0L) {
|
||||||
|
@ -147,23 +147,37 @@ public class BusinessDataServiceImpl implements BusinessDataService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("批量更新子文件夹路径")
|
||||||
|
@Override
|
||||||
|
public void updateSubFolderPaths(String oldParentPath1, String newParentPath1,Long folderId) {
|
||||||
|
// 处理路径中的分隔符,如果是反斜杠则替换为双反斜杠
|
||||||
|
String processedOldParentPath = oldParentPath1;
|
||||||
|
String processedNewParentPath = newParentPath1;
|
||||||
|
if ("\\".equals(File.separator)) {
|
||||||
|
processedOldParentPath = oldParentPath1.replace("\\", "\\\\");
|
||||||
|
processedNewParentPath = newParentPath1.replace("\\", "\\\\");
|
||||||
|
}
|
||||||
|
|
||||||
|
businessDataMapper.updateSubFolderPaths(oldParentPath1,newParentPath1,processedOldParentPath, processedNewParentPath, folderId);
|
||||||
|
}
|
||||||
@ApiOperation("重命名文件夹")
|
@ApiOperation("重命名文件夹")
|
||||||
@Override
|
@Override
|
||||||
public Result reName(Long folderId, String newName) {
|
public Result reName(Long folderId, String newName) {
|
||||||
// 获取文件夹路径
|
// 获取文件夹路径
|
||||||
String folderPath = businessDataMapper.getPath(folderId);
|
String folderPath = businessDataMapper.getPath(folderId);
|
||||||
String newPath = folderPath.substring(0, folderPath.lastIndexOf('\\')) + "\\" + newName;
|
String newPath = folderPath.substring(0, folderPath.lastIndexOf(File.separator)) + File.separator + newName;
|
||||||
//
|
|
||||||
// //想命名的原文件的路径
|
// 重命名物理文件夹
|
||||||
// File file = new File("f:/a/a.xlsx");
|
|
||||||
// //将原文件更改为f:\a\b.xlsx,其中路径是必要的。注意
|
|
||||||
// file.renameTo(new File("f:/a/b.xlsx"));
|
|
||||||
// 想命名的原文件夹的路径
|
|
||||||
File file1 = new File(folderPath);
|
File file1 = new File(folderPath);
|
||||||
// 将原文件夹更改为A,其中路径是必要的。注意
|
boolean renameSuccess = file1.renameTo(new File(newPath));
|
||||||
file1.renameTo(new File(newPath));
|
|
||||||
|
if (!renameSuccess) {
|
||||||
|
return Result.error("文件夹重命名失败");
|
||||||
|
}
|
||||||
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
|
// 更新文件夹信息
|
||||||
BusinessDataEntity businessDataEntity = new BusinessDataEntity(
|
BusinessDataEntity businessDataEntity = new BusinessDataEntity(
|
||||||
folderId,
|
folderId,
|
||||||
newName,
|
newName,
|
||||||
|
@ -174,6 +188,21 @@ public class BusinessDataServiceImpl implements BusinessDataService {
|
||||||
null,
|
null,
|
||||||
newPath);
|
newPath);
|
||||||
businessDataMapper.reName(businessDataEntity);
|
businessDataMapper.reName(businessDataEntity);
|
||||||
|
|
||||||
|
// // 批量更新该文件夹下所有文件的路径
|
||||||
|
// businessDataFileService.updateFilePathByFolderId(folderId, newPath);
|
||||||
|
|
||||||
|
|
||||||
|
String folderPath1 = folderPath+File.separator;
|
||||||
|
String newPath1 = newPath+File.separator;
|
||||||
|
|
||||||
|
// 批量更新子文件夹下所有文件的路径
|
||||||
|
businessDataFileService.updateSubFilePaths(folderPath1, newPath1);
|
||||||
|
// 批量更新子文件夹的路径
|
||||||
|
updateSubFolderPaths(folderPath1, newPath1,folderId);
|
||||||
|
|
||||||
return Result.okM("重命名成功");
|
return Result.okM("重命名成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,13 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import com.dite.znpt.domain.vo.ReceiptRequest;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bear.G
|
* @author Bear.G
|
||||||
|
@ -474,6 +478,15 @@ public class EquipmentServiceImpl extends ServiceImpl<EquipmentMapper, Equipment
|
||||||
// 设置采购状态字段
|
// 设置采购状态字段
|
||||||
resp.setProcurementStatus(entity.getProcurementStatus());
|
resp.setProcurementStatus(entity.getProcurementStatus());
|
||||||
|
|
||||||
|
// 设置收货状态和支付状态字段
|
||||||
|
resp.setReceiptStatus(entity.getReceiptStatus());
|
||||||
|
resp.setPaymentStatus(entity.getPaymentStatus());
|
||||||
|
|
||||||
|
// 设置审批状态(根据采购状态推断)
|
||||||
|
// 这里需要注入 EquipmentApprovalService 来获取审批状态
|
||||||
|
// 暂时根据采购状态推断,后续通过关联查询获取
|
||||||
|
resp.setApprovalStatus(getApprovalStatus(entity.getEquipmentId(), entity.getProcurementStatus()));
|
||||||
|
|
||||||
// 新增字段转换
|
// 新增字段转换
|
||||||
resp.setUsingDepartment(entity.getUsingDepartment());
|
resp.setUsingDepartment(entity.getUsingDepartment());
|
||||||
resp.setBorrowingTime(entity.getBorrowingTime());
|
resp.setBorrowingTime(entity.getBorrowingTime());
|
||||||
|
@ -500,6 +513,34 @@ public class EquipmentServiceImpl extends ServiceImpl<EquipmentMapper, Equipment
|
||||||
|
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备的审批状态
|
||||||
|
*/
|
||||||
|
private String getApprovalStatus(String equipmentId, String procurementStatus) {
|
||||||
|
try {
|
||||||
|
// 根据采购状态推断审批状态
|
||||||
|
if (procurementStatus == null) {
|
||||||
|
return "PENDING_APPROVAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (procurementStatus) {
|
||||||
|
case "PENDING_APPROVAL":
|
||||||
|
return "PENDING";
|
||||||
|
case "APPROVED":
|
||||||
|
return "APPROVED";
|
||||||
|
case "REJECTED":
|
||||||
|
return "REJECTED";
|
||||||
|
case "COMPLETED":
|
||||||
|
return "APPROVED"; // 已完成表示之前已审批通过
|
||||||
|
default:
|
||||||
|
return "PENDING_APPROVAL";
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取设备审批状态失败,设备ID: {}, 错误: {}", equipmentId, e.getMessage());
|
||||||
|
return "PENDING_APPROVAL"; // 出错时返回待审批状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 采购管理相关方法实现
|
// 采购管理相关方法实现
|
||||||
@Override
|
@Override
|
||||||
|
@ -840,4 +881,93 @@ public class EquipmentServiceImpl extends ServiceImpl<EquipmentMapper, Equipment
|
||||||
|
|
||||||
log.info("批量设备盘库执行成功,处理设备数量: {}", equipmentIds.size());
|
log.info("批量设备盘库执行成功,处理设备数量: {}", equipmentIds.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void receiveGoodsAndStockIn(String equipmentId, ReceiptRequest req) {
|
||||||
|
log.info("开始处理设备收货和入库,设备ID: {}", equipmentId);
|
||||||
|
log.info("收货请求数据: {}", req);
|
||||||
|
|
||||||
|
// 1. 查找采购记录
|
||||||
|
EquipmentEntity procurementRecord = this.getById(equipmentId);
|
||||||
|
if (procurementRecord == null) {
|
||||||
|
throw new ServiceException("采购记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("找到采购记录: {}", procurementRecord);
|
||||||
|
|
||||||
|
// 2. 更新现有设备记录(而不是创建新记录)
|
||||||
|
EquipmentEntity equipment = new EquipmentEntity();
|
||||||
|
equipment.setEquipmentId(equipmentId);
|
||||||
|
|
||||||
|
// 设置收货相关信息
|
||||||
|
if (StringUtils.hasText(req.getReceiptTime())) {
|
||||||
|
try {
|
||||||
|
equipment.setInStockTime(LocalDateTime.parse(req.getReceiptTime().replace(" ", "T")));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("解析收货时间失败,使用当前时间: {}", req.getReceiptTime());
|
||||||
|
equipment.setInStockTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
equipment.setInStockTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置收货状态为已收货
|
||||||
|
equipment.setReceiptStatus("RECEIVED");
|
||||||
|
|
||||||
|
// 设置采购状态为已完成(而不是已收货)
|
||||||
|
equipment.setProcurementStatus("COMPLETED");
|
||||||
|
|
||||||
|
// 设置设备状态为库存中
|
||||||
|
equipment.setLocationStatus("in_stock");
|
||||||
|
equipment.setUseStatus("0"); // 空闲中
|
||||||
|
|
||||||
|
// 设置其他收货相关字段
|
||||||
|
if (StringUtils.hasText(req.getStorageLocation())) {
|
||||||
|
equipment.setPhysicalLocation(req.getStorageLocation());
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(req.getStorageManager())) {
|
||||||
|
equipment.setResponsiblePerson(req.getStorageManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录收货人信息到资产备注中
|
||||||
|
if (StringUtils.hasText(req.getReceiptPerson())) {
|
||||||
|
String currentRemark = procurementRecord.getAssetRemark();
|
||||||
|
String receiptInfo = String.format("收货人:%s,收货时间:%s",
|
||||||
|
req.getReceiptPerson(),
|
||||||
|
req.getReceiptTime() != null ? req.getReceiptTime() : LocalDateTime.now().toString());
|
||||||
|
|
||||||
|
if (StringUtils.hasText(currentRemark)) {
|
||||||
|
equipment.setAssetRemark(currentRemark + ";" + receiptInfo);
|
||||||
|
} else {
|
||||||
|
equipment.setAssetRemark(receiptInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置设备序列号(如果收货时生成了新的)
|
||||||
|
if (StringUtils.hasText(req.getEquipmentSn())) {
|
||||||
|
equipment.setEquipmentSn(req.getEquipmentSn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置库存条码
|
||||||
|
if (StringUtils.hasText(req.getInventoryBarcode())) {
|
||||||
|
equipment.setInventoryBarcode(req.getInventoryBarcode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置更新时间和操作人
|
||||||
|
equipment.setUpdateTime(LocalDateTime.now());
|
||||||
|
equipment.setUpdateBy(StpUtil.getLoginIdAsString());
|
||||||
|
|
||||||
|
log.info("准备更新设备记录,设备ID: {}, 收货状态: {}, 采购状态: {}",
|
||||||
|
equipmentId, equipment.getReceiptStatus(), equipment.getProcurementStatus());
|
||||||
|
|
||||||
|
// 3. 更新设备记录
|
||||||
|
boolean updateResult = this.updateById(equipment);
|
||||||
|
if (!updateResult) {
|
||||||
|
throw new ServiceException("更新设备记录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("设备收货和入库成功,设备ID: {}, 收货状态: {}, 采购状态: {}",
|
||||||
|
equipmentId, equipment.getReceiptStatus(), equipment.getProcurementStatus());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,486 @@
|
||||||
|
package com.dite.znpt.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.dite.znpt.domain.entity.ProjectTaskEntity;
|
||||||
|
import com.dite.znpt.domain.entity.UserEntity;
|
||||||
|
import com.dite.znpt.domain.vo.GanttChartReq;
|
||||||
|
import com.dite.znpt.domain.vo.GanttChartResp;
|
||||||
|
import com.dite.znpt.mapper.ProjectTaskMapper;
|
||||||
|
import com.dite.znpt.service.GanttChartService;
|
||||||
|
import com.dite.znpt.service.UserService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘特图服务实现类
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GanttChartServiceImpl implements GanttChartService {
|
||||||
|
|
||||||
|
private final ProjectTaskMapper projectTaskMapper;
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GanttChartResp> getGanttChartData(GanttChartReq req) {
|
||||||
|
// 查询所有任务
|
||||||
|
QueryWrapper<ProjectTaskEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(req.getProjectId())) {
|
||||||
|
queryWrapper.eq("project_id", req.getProjectId());
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(req.getTaskGroupId())) {
|
||||||
|
queryWrapper.eq("task_group_id", req.getTaskGroupId());
|
||||||
|
}
|
||||||
|
if (req.getStatus() != null) {
|
||||||
|
queryWrapper.eq("status", req.getStatus());
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(req.getMainUserId())) {
|
||||||
|
queryWrapper.eq("main_user_id", req.getMainUserId());
|
||||||
|
}
|
||||||
|
if (req.getStartDateFrom() != null) {
|
||||||
|
queryWrapper.ge("plan_start_date", req.getStartDateFrom());
|
||||||
|
}
|
||||||
|
if (req.getStartDateTo() != null) {
|
||||||
|
queryWrapper.le("plan_start_date", req.getStartDateTo());
|
||||||
|
}
|
||||||
|
if (req.getEndDateFrom() != null) {
|
||||||
|
queryWrapper.ge("plan_end_date", req.getEndDateFrom());
|
||||||
|
}
|
||||||
|
if (req.getEndDateTo() != null) {
|
||||||
|
queryWrapper.le("plan_end_date", req.getEndDateTo());
|
||||||
|
}
|
||||||
|
if (req.getOverdueOnly() != null && req.getOverdueOnly()) {
|
||||||
|
queryWrapper.eq("overdue_status", 1);
|
||||||
|
}
|
||||||
|
if (req.getIncludeCompleted() != null && !req.getIncludeCompleted()) {
|
||||||
|
queryWrapper.ne("status", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByAsc("plan_start_date");
|
||||||
|
|
||||||
|
List<ProjectTaskEntity> taskList = projectTaskMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
final Set<String> userIds = new HashSet<>();
|
||||||
|
taskList.forEach(task -> {
|
||||||
|
if (StrUtil.isNotBlank(task.getMainUserId())) {
|
||||||
|
userIds.add(task.getMainUserId());
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(task.getUserIds())) {
|
||||||
|
userIds.addAll(Arrays.asList(task.getUserIds().split(",")));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final Map<String, UserEntity> userMap = new HashMap<>();
|
||||||
|
if (CollUtil.isNotEmpty(userIds)) {
|
||||||
|
List<UserEntity> users = userService.listByIds(userIds);
|
||||||
|
userMap.putAll(users.stream().collect(Collectors.toMap(UserEntity::getUserId, user -> user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量获取项目时间范围,避免重复查询
|
||||||
|
final Map<String, LocalDate> projectStartDates = new HashMap<>();
|
||||||
|
if (StrUtil.isNotBlank(req.getProjectId())) {
|
||||||
|
// 如果指定了项目ID,直接获取该项目的时间范围
|
||||||
|
LocalDate projectStart = getProjectStartDate(req.getProjectId());
|
||||||
|
projectStartDates.put(req.getProjectId(), projectStart);
|
||||||
|
} else {
|
||||||
|
// 如果没有指定项目ID,获取所有相关项目的时间范围
|
||||||
|
Set<String> projectIds = taskList.stream()
|
||||||
|
.map(ProjectTaskEntity::getProjectId)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (String projectId : projectIds) {
|
||||||
|
LocalDate projectStart = getProjectStartDate(projectId);
|
||||||
|
projectStartDates.put(projectId, projectStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为甘特图数据
|
||||||
|
List<GanttChartResp> ganttData = taskList.stream().map(task -> {
|
||||||
|
GanttChartResp resp = BeanUtil.copyProperties(task, GanttChartResp.class);
|
||||||
|
|
||||||
|
// 设置状态描述
|
||||||
|
switch (task.getStatus()) {
|
||||||
|
case 0:
|
||||||
|
resp.setStatusDesc("未开始");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
resp.setStatusDesc("进行中");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
resp.setStatusDesc("已结束");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
resp.setStatusDesc("未知");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置负责人姓名
|
||||||
|
if (StrUtil.isNotBlank(task.getMainUserId()) && userMap.containsKey(task.getMainUserId())) {
|
||||||
|
resp.setMainUserName(userMap.get(task.getMainUserId()).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置参与人姓名列表
|
||||||
|
if (StrUtil.isNotBlank(task.getUserIds())) {
|
||||||
|
List<String> participantNames = Arrays.stream(task.getUserIds().split(","))
|
||||||
|
.filter(userId -> userMap.containsKey(userId))
|
||||||
|
.map(userId -> userMap.get(userId).getName())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
resp.setParticipantNames(participantNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算进度(这里可以根据实际业务逻辑调整)
|
||||||
|
if (task.getStatus() == 2) {
|
||||||
|
resp.setProgress(100);
|
||||||
|
} else if (task.getStatus() == 1) {
|
||||||
|
resp.setProgress(50); // 默认进度,实际应该从数据库字段获取
|
||||||
|
} else {
|
||||||
|
resp.setProgress(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算任务在时间轴上的位置和持续时间
|
||||||
|
LocalDate projectStart = projectStartDates.get(task.getProjectId());
|
||||||
|
if (projectStart != null && task.getPlanStartDate() != null) {
|
||||||
|
int position = (int) ChronoUnit.DAYS.between(projectStart, task.getPlanStartDate());
|
||||||
|
resp.setPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算任务持续时间
|
||||||
|
if (task.getPlanStartDate() != null && task.getPlanEndDate() != null) {
|
||||||
|
int duration = (int) ChronoUnit.DAYS.between(task.getPlanStartDate(), task.getPlanEndDate()) + 1;
|
||||||
|
resp.setDuration(duration);
|
||||||
|
} else {
|
||||||
|
resp.setDuration(1); // 默认持续1天
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 构建树形结构
|
||||||
|
return buildTreeStructure(ganttData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGanttChartStatistics(String projectId) {
|
||||||
|
QueryWrapper<ProjectTaskEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("project_id", projectId);
|
||||||
|
|
||||||
|
List<ProjectTaskEntity> taskList = projectTaskMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
Map<String, Object> statistics = new HashMap<>();
|
||||||
|
statistics.put("totalTasks", taskList.size());
|
||||||
|
statistics.put("notStarted", (int) taskList.stream().filter(task -> task.getStatus() == 0).count());
|
||||||
|
statistics.put("inProgress", (int) taskList.stream().filter(task -> task.getStatus() == 1).count());
|
||||||
|
statistics.put("completed", (int) taskList.stream().filter(task -> task.getStatus() == 2).count());
|
||||||
|
statistics.put("overdue", (int) taskList.stream().filter(task -> task.getOverdueStatus() == 1).count());
|
||||||
|
|
||||||
|
// 计算总体进度
|
||||||
|
if (taskList.size() > 0) {
|
||||||
|
final double avgProgress = taskList.stream()
|
||||||
|
.mapToInt(task -> {
|
||||||
|
if (task.getStatus() == 2) return 100;
|
||||||
|
else if (task.getStatus() == 1) return 50;
|
||||||
|
else return 0;
|
||||||
|
})
|
||||||
|
.average()
|
||||||
|
.orElse(0.0);
|
||||||
|
statistics.put("overallProgress", Math.round(avgProgress));
|
||||||
|
} else {
|
||||||
|
statistics.put("overallProgress", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return statistics;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGanttChartTimeline(String projectId) {
|
||||||
|
if (StrUtil.isBlank(projectId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate projectStartDate = getProjectStartDate(projectId);
|
||||||
|
LocalDate projectEndDate = getProjectEndDate(projectId);
|
||||||
|
|
||||||
|
Map<String, Object> timeline = new HashMap<>();
|
||||||
|
timeline.put("projectId", projectId);
|
||||||
|
timeline.put("startDate", projectStartDate);
|
||||||
|
timeline.put("endDate", projectEndDate);
|
||||||
|
timeline.put("totalDays", ChronoUnit.DAYS.between(projectStartDate, projectEndDate) + 1);
|
||||||
|
|
||||||
|
// 计算时间轴上的关键时间点(比如每周、每月)
|
||||||
|
List<Map<String, Object>> timePoints = new ArrayList<>();
|
||||||
|
LocalDate currentDate = projectStartDate;
|
||||||
|
|
||||||
|
while (!currentDate.isAfter(projectEndDate)) {
|
||||||
|
Map<String, Object> timePoint = new HashMap<>();
|
||||||
|
timePoint.put("date", currentDate);
|
||||||
|
timePoint.put("dayOfWeek", currentDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.SHORT, java.util.Locale.CHINESE));
|
||||||
|
timePoint.put("isWeekend", currentDate.getDayOfWeek().getValue() >= 6);
|
||||||
|
timePoints.add(timePoint);
|
||||||
|
|
||||||
|
currentDate = currentDate.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeline.put("timePoints", timePoints);
|
||||||
|
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTaskProgress(String taskId, Integer progress) {
|
||||||
|
ProjectTaskEntity task = projectTaskMapper.selectById(taskId);
|
||||||
|
if (task == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新进度
|
||||||
|
// 这里需要根据实际业务逻辑添加进度字段
|
||||||
|
// task.setProgress(progress);
|
||||||
|
|
||||||
|
// 根据进度更新状态
|
||||||
|
if (progress >= 100) {
|
||||||
|
task.setStatus(2); // 已完成
|
||||||
|
task.setActualEndDate(LocalDate.now());
|
||||||
|
} else if (progress > 0) {
|
||||||
|
task.setStatus(1); // 进行中
|
||||||
|
if (task.getActualStartDate() == null) {
|
||||||
|
task.setActualStartDate(LocalDate.now());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectTaskMapper.updateById(task) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTaskTime(String taskId, String startDate, String endDate) {
|
||||||
|
ProjectTaskEntity task = projectTaskMapper.selectById(taskId);
|
||||||
|
if (task == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
LocalDate newStartDate = null;
|
||||||
|
LocalDate newEndDate = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (StrUtil.isNotBlank(startDate)) {
|
||||||
|
newStartDate = LocalDate.parse(startDate, formatter);
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(endDate)) {
|
||||||
|
newEndDate = LocalDate.parse(endDate, formatter);
|
||||||
|
}
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
return false; // 日期格式错误
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证时间约束
|
||||||
|
if (!validateTaskTimeConstraints(task, newStartDate, newEndDate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新任务时间
|
||||||
|
if (newStartDate != null) {
|
||||||
|
task.setPlanStartDate(newStartDate);
|
||||||
|
}
|
||||||
|
if (newEndDate != null) {
|
||||||
|
task.setPlanEndDate(newEndDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新逾期状态
|
||||||
|
updateOverdueStatus(task);
|
||||||
|
|
||||||
|
return projectTaskMapper.updateById(task) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建树形结构
|
||||||
|
*/
|
||||||
|
private List<GanttChartResp> buildTreeStructure(List<GanttChartResp> allTasks) {
|
||||||
|
final Map<String, GanttChartResp> taskMap = allTasks.stream()
|
||||||
|
.collect(Collectors.toMap(GanttChartResp::getTaskId, task -> task));
|
||||||
|
|
||||||
|
final List<GanttChartResp> rootTasks = new ArrayList<>();
|
||||||
|
|
||||||
|
for (GanttChartResp task : allTasks) {
|
||||||
|
if (StrUtil.isBlank(task.getParentTaskId())) {
|
||||||
|
// 根任务
|
||||||
|
task.setLevel(0);
|
||||||
|
rootTasks.add(task);
|
||||||
|
} else {
|
||||||
|
// 子任务
|
||||||
|
GanttChartResp parentTask = taskMap.get(task.getParentTaskId());
|
||||||
|
if (parentTask != null) {
|
||||||
|
task.setLevel(parentTask.getLevel() + 1);
|
||||||
|
if (parentTask.getChildren() == null) {
|
||||||
|
parentTask.setChildren(new ArrayList<>());
|
||||||
|
}
|
||||||
|
parentTask.getChildren().add(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootTasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目开始时间
|
||||||
|
* 从项目任务中计算最早的计划开始时间作为项目开始时间
|
||||||
|
*/
|
||||||
|
private LocalDate getProjectStartDate(String projectId) {
|
||||||
|
if (StrUtil.isBlank(projectId)) {
|
||||||
|
return LocalDate.now().minusDays(30); // 默认值
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询项目中所有任务的计划开始时间,取最早的时间
|
||||||
|
QueryWrapper<ProjectTaskEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("project_id", projectId)
|
||||||
|
.isNotNull("plan_start_date")
|
||||||
|
.orderByAsc("plan_start_date")
|
||||||
|
.last("LIMIT 1");
|
||||||
|
|
||||||
|
ProjectTaskEntity earliestTask = projectTaskMapper.selectOne(queryWrapper);
|
||||||
|
|
||||||
|
if (earliestTask != null && earliestTask.getPlanStartDate() != null) {
|
||||||
|
return earliestTask.getPlanStartDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到有效的开始时间,返回当前时间减去30天作为默认值
|
||||||
|
return LocalDate.now().minusDays(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目结束时间
|
||||||
|
* 从项目任务中计算最晚的计划结束时间作为项目结束时间
|
||||||
|
*/
|
||||||
|
private LocalDate getProjectEndDate(String projectId) {
|
||||||
|
if (StrUtil.isBlank(projectId)) {
|
||||||
|
return LocalDate.now().plusDays(30); // 默认值
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询项目中所有任务的计划结束时间,取最晚的时间
|
||||||
|
QueryWrapper<ProjectTaskEntity> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("project_id", projectId)
|
||||||
|
.isNotNull("plan_end_date")
|
||||||
|
.orderByDesc("plan_end_date")
|
||||||
|
.last("LIMIT 1");
|
||||||
|
|
||||||
|
ProjectTaskEntity latestTask = projectTaskMapper.selectOne(queryWrapper);
|
||||||
|
|
||||||
|
if (latestTask != null && latestTask.getPlanEndDate() != null) {
|
||||||
|
return latestTask.getPlanEndDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到有效的结束时间,返回当前时间加上30天作为默认值
|
||||||
|
return LocalDate.now().plusDays(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目时间范围
|
||||||
|
* 返回项目的开始时间和结束时间
|
||||||
|
*/
|
||||||
|
private Map<String, LocalDate> getProjectTimeRange(String projectId) {
|
||||||
|
Map<String, LocalDate> timeRange = new HashMap<>();
|
||||||
|
timeRange.put("startDate", getProjectStartDate(projectId));
|
||||||
|
timeRange.put("endDate", getProjectEndDate(projectId));
|
||||||
|
return timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量获取项目时间范围
|
||||||
|
* 通过一次查询获取多个项目的时间范围,提高性能
|
||||||
|
*/
|
||||||
|
private Map<String, Map<String, LocalDate>> getBatchProjectTimeRanges(Set<String> projectIds) {
|
||||||
|
Map<String, Map<String, LocalDate>> timeRanges = new HashMap<>();
|
||||||
|
|
||||||
|
for (String projectId : projectIds) {
|
||||||
|
Map<String, LocalDate> timeRange = getProjectTimeRange(projectId);
|
||||||
|
timeRanges.put(projectId, timeRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeRanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算任务进度
|
||||||
|
*/
|
||||||
|
private Integer calculateProgress(ProjectTaskEntity task) {
|
||||||
|
if (task.getStatus() == 2) return 100; // 已完成
|
||||||
|
else if (task.getStatus() == 1) return 50; // 进行中
|
||||||
|
else return 0; // 未开始
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算任务持续时间
|
||||||
|
*/
|
||||||
|
private Integer calculateDuration(ProjectTaskEntity task) {
|
||||||
|
if (task.getPlanStartDate() != null && task.getPlanEndDate() != null) {
|
||||||
|
return (int) ChronoUnit.DAYS.between(task.getPlanStartDate(), task.getPlanEndDate()) + 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算任务在时间轴上的位置
|
||||||
|
*/
|
||||||
|
private Integer calculatePosition(ProjectTaskEntity task) {
|
||||||
|
LocalDate projectStart = getProjectStartDate(task.getProjectId());
|
||||||
|
if (task.getPlanStartDate() != null && projectStart != null) {
|
||||||
|
return (int) ChronoUnit.DAYS.between(projectStart, task.getPlanStartDate());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证任务时间约束
|
||||||
|
*/
|
||||||
|
private boolean validateTaskTimeConstraints(ProjectTaskEntity task,
|
||||||
|
LocalDate newStartDate,
|
||||||
|
LocalDate newEndDate) {
|
||||||
|
// 验证子任务不能早于父任务开始
|
||||||
|
if (StrUtil.isNotBlank(task.getParentTaskId())) {
|
||||||
|
ProjectTaskEntity parentTask = projectTaskMapper.selectById(task.getParentTaskId());
|
||||||
|
if (parentTask != null && newStartDate != null) {
|
||||||
|
if (newStartDate.isBefore(parentTask.getPlanStartDate())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证结束时间不能早于开始时间
|
||||||
|
if (newStartDate != null && newEndDate != null) {
|
||||||
|
if (newEndDate.isBefore(newStartDate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新逾期状态
|
||||||
|
*/
|
||||||
|
private void updateOverdueStatus(ProjectTaskEntity task) {
|
||||||
|
if (task.getPlanEndDate() != null &&
|
||||||
|
task.getPlanEndDate().isBefore(LocalDate.now()) &&
|
||||||
|
task.getStatus() != 2) {
|
||||||
|
task.setOverdueStatus(1); // 标记为逾期
|
||||||
|
} else {
|
||||||
|
task.setOverdueStatus(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -94,5 +94,20 @@
|
||||||
</set>
|
</set>
|
||||||
where file_id = #{fileId}
|
where file_id = #{fileId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<!-- <!– 批量更新文件路径 –>-->
|
||||||
|
<!-- <update id="updateFilePathByFolderId">-->
|
||||||
|
<!-- update business_data_part_file-->
|
||||||
|
<!-- set file_path = concat(#{newFolderPath}, #{separator}, file_name)-->
|
||||||
|
<!-- where folder_id = #{folderId}-->
|
||||||
|
<!-- </update>-->
|
||||||
|
|
||||||
|
<!-- 批量更新子文件夹下文件的路径 -->
|
||||||
|
<update id="updateSubFilePaths">
|
||||||
|
update business_data_part_file
|
||||||
|
set file_path = replace(file_path, #{oldParentPath1}, #{newParentPath1})
|
||||||
|
where file_path like concat(#{oldParentPath2}, '%')
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
||||||
|
|
|
@ -51,5 +51,14 @@
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 批量更新子文件夹路径 -->
|
||||||
|
<update id="updateSubFolderPaths">
|
||||||
|
update business_data_part
|
||||||
|
set folder_path = replace(folder_path, #{oldParentPath1}, #{newParentPath1}),
|
||||||
|
update_time = now()
|
||||||
|
where folder_path like concat(#{processedOldParentPath}, '%')
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.dite.znpt.domain.vo.ReceiptRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Bear.G
|
* @author Bear.G
|
||||||
|
@ -139,4 +140,15 @@ public class EquipmentController {
|
||||||
public Result<?> getProcurementStats(){
|
public Result<?> getProcurementStats(){
|
||||||
return Result.ok(equipmentService.getProcurementStats());
|
return Result.ok(equipmentService.getProcurementStats());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "确认收货并自动入库", httpMethod = "POST")
|
||||||
|
@PostMapping("/procurement/receipt/{equipmentId}")
|
||||||
|
public Result<?> receiveGoods(@PathVariable String equipmentId, @Validated @RequestBody ReceiptRequest req) {
|
||||||
|
log.info("=== 设备收货接口被调用 ===");
|
||||||
|
log.info("设备ID: {}", equipmentId);
|
||||||
|
log.info("收货数据: {}", req);
|
||||||
|
|
||||||
|
equipmentService.receiveGoodsAndStockIn(equipmentId, req);
|
||||||
|
return Result.ok("收货成功,设备已自动入库");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.dite.znpt.web.controller;
|
||||||
|
|
||||||
|
import com.dite.znpt.domain.Result;
|
||||||
|
import com.dite.znpt.domain.vo.GanttChartReq;
|
||||||
|
import com.dite.znpt.domain.vo.GanttChartResp;
|
||||||
|
import com.dite.znpt.service.GanttChartService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 甘特图控制器
|
||||||
|
*/
|
||||||
|
@Api(tags = "甘特图管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/gantt-chart")
|
||||||
|
public class GanttChartController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GanttChartService ganttChartService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取项目甘特图数据", httpMethod = "GET")
|
||||||
|
@GetMapping("/data")
|
||||||
|
public Result<List<GanttChartResp>> getGanttChartData(GanttChartReq req) {
|
||||||
|
List<GanttChartResp> data = ganttChartService.getGanttChartData(req);
|
||||||
|
return Result.ok(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取项目甘特图统计信息", httpMethod = "GET")
|
||||||
|
@GetMapping("/statistics/{projectId}")
|
||||||
|
public Result<Object> getGanttChartStatistics(@PathVariable String projectId) {
|
||||||
|
Object statistics = ganttChartService.getGanttChartStatistics(projectId);
|
||||||
|
return Result.ok(statistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取项目甘特图时间轴信息", httpMethod = "GET")
|
||||||
|
@GetMapping("/timeline/{projectId}")
|
||||||
|
public Result<Object> getGanttChartTimeline(@PathVariable String projectId) {
|
||||||
|
Object timeline = ganttChartService.getGanttChartTimeline(projectId);
|
||||||
|
return Result.ok(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "更新任务进度", httpMethod = "PUT")
|
||||||
|
@PutMapping("/progress/{taskId}")
|
||||||
|
public Result<Boolean> updateTaskProgress(@PathVariable String taskId, @RequestParam Integer progress) {
|
||||||
|
boolean success = ganttChartService.updateTaskProgress(taskId, progress);
|
||||||
|
return Result.ok(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "拖拽更新任务时间", httpMethod = "PUT")
|
||||||
|
@PutMapping("/time/{taskId}")
|
||||||
|
public Result<Boolean> updateTaskTime(@PathVariable String taskId,
|
||||||
|
@RequestParam(required = false) String startDate,
|
||||||
|
@RequestParam(required = false) String endDate) {
|
||||||
|
boolean success = ganttChartService.updateTaskTime(taskId, startDate, endDate);
|
||||||
|
return Result.ok(success);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ spring:
|
||||||
datasource:
|
datasource:
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://39.99.201.243:3306/znpt_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
url: jdbc:mysql://39.99.201.243:3306/test01?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
username: root
|
username: root
|
||||||
password: BUw8YW6%@^8q
|
password: BUw8YW6%@^8q
|
||||||
druid:
|
druid:
|
||||||
|
|
Loading…
Reference in New Issue