Parcourir la source

feat: task's related cost crud

Blizzard il y a 1 an
Parent
commit
5693aaa0cc

+ 3 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/DeptToDept.java

@@ -9,6 +9,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.mp.base.BaseEntity;
 
+import javax.validation.constraints.NotNull;
+
 /**
  * @author Blizzard
  * @create at 2023-09-14 10:54
@@ -22,6 +24,7 @@ public class DeptToDept extends BaseEntity {
 	@JsonSerialize(using = ToStringSerializer.class)
 	@TableField("org_dept_id")
 	@ApiModelProperty(value = "服务机构顶级id")
+	@NotNull(message = "orgDeptId can't be null")
 	private Long orgDeptId;
 
 	@ApiModelProperty("租户ID")

+ 0 - 1
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/TaskContract.java

@@ -31,7 +31,6 @@ public class TaskContract extends BaseEntity {
 
 	@TableField("blade_file_id")
 	@ApiModelProperty(value = "文件上传完返回的主键id")
-	@NotNull(message = "bladeFileId can't be null")
 	private Long bladeFileId;
 
 	@TableField("amount")

+ 53 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/entity/TaskCost.java

@@ -0,0 +1,53 @@
+package com.wtkj.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-18 11:52
+ * @describe 任务成本核算
+ */
+@EqualsAndHashCode(callSuper = true)
+@TableName("blade_task_cost")
+@Data
+public class TaskCost extends BaseEntity {
+
+	@TableField("task_id")
+	@JsonSerialize(using = ToStringSerializer.class)
+	private Long taskId;
+
+	@ApiModelProperty(value = "成本类型 字典值")
+	@TableField("type")
+	private String type;
+
+	@ApiModelProperty(value = "金额")
+	@TableField("amount")
+	private BigDecimal amount;
+
+	@ApiModelProperty(value = "开始时间")
+	@TableField("start_time")
+	private Date startTime;
+
+	@ApiModelProperty(value = "结束时间")
+	@TableField("end_time")
+	private Date endTime;
+
+	@ApiModelProperty(value = "交通方式 字典值")
+	@TableField("transportation_mode")
+	private String transportationMode;
+
+	@ApiModelProperty(value = "报销凭证文件ids 上传完成以后返回的主键ID")
+	@TableField("blade_file_ids")
+	private String bladeFileIds;
+
+}

+ 3 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/TaskContractVO.java

@@ -1,6 +1,7 @@
 package com.wtkj.vo;
 
 import com.wtkj.entity.TaskContract;
+import com.wutong.file.vo.FileVO;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -15,4 +16,6 @@ public class TaskContractVO extends TaskContract {
 
 	private String partyB;
 
+	private FileVO fileVO;
+
 }

+ 22 - 0
blade-service-api/wt-okr-api/src/main/java/com/wtkj/vo/TaskCostVO.java

@@ -0,0 +1,22 @@
+package com.wtkj.vo;
+
+import com.wtkj.entity.TaskCost;
+import com.wutong.file.vo.FileVO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-18 14:26
+ * @describe
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class TaskCostVO extends TaskCost {
+
+	private String submitUser;
+
+	private List<FileVO> files;
+}

+ 64 - 17
blade-service/wt-okr/src/main/java/com/wtkj/controller/TaskController.java

@@ -1,23 +1,13 @@
 package com.wtkj.controller;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import com.wtkj.entity.Task;
-import com.wtkj.entity.TaskContract;
-import com.wtkj.entity.TaskFile;
-import com.wtkj.entity.TaskLog;
-import com.wtkj.service.ITaskContractService;
-import com.wtkj.service.ITaskFileService;
-import com.wtkj.service.ITaskLogService;
-import com.wtkj.service.ITaskService;
-import com.wtkj.vo.TaskFileVO;
-import com.wtkj.vo.TaskLogVO;
-import com.wtkj.vo.TaskVO;
-import com.wtkj.wrapper.TaskContractWrapper;
-import com.wtkj.wrapper.TaskFileWrapper;
-import com.wtkj.wrapper.TaskLogWrapper;
-import com.wtkj.wrapper.TaskWrapper;
+import com.wtkj.entity.*;
+import com.wtkj.service.*;
+import com.wtkj.vo.*;
+import com.wtkj.wrapper.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
@@ -49,6 +39,8 @@ public class TaskController {
 
 	private final ITaskContractService taskContractService;
 
+	private final ITaskCostService taskCostService;
+
 
 	@GetMapping("/my-task-page")
 	@ApiOperationSupport(order = 1)
@@ -157,7 +149,7 @@ public class TaskController {
 	@PostMapping("/submit-task-contract")
 	@ApiOperationSupport(order = 11)
 	@ApiOperation(value = "新增或者修改任务合同", notes = "")
-	public R<Boolean> savaContracts(@RequestBody @Valid TaskContract contract) {
+	public R<Boolean> submitContracts(@RequestBody @Valid TaskContract contract) {
 		return R.status(taskContractService.saveOrUpdate(contract));
 
 	}
@@ -178,11 +170,66 @@ public class TaskController {
 	@GetMapping("/task-contract-page")
 	@ApiOperationSupport(order = 13)
 	@ApiOperation(value = "任务合同分页", notes = "传入主键taskId,分页参数")
-	public R contractPage(@RequestParam Long taskId, Query query) {
+	public R<IPage<TaskContractVO>> contractPage(@RequestParam Long taskId, Query query) {
 		IPage<TaskContract> page = taskContractService.pageByTaskId(taskId, Condition.getPage(query));
 		return R.data(TaskContractWrapper.build().pageVO(page));
 	}
 
 
+	/**
+	 * 任务成本核算
+	 */
+	@PostMapping("/submit-task-cost")
+	@ApiOperationSupport(order = 14)
+	@ApiOperation(value = "新增或修改任务成本", notes = "")
+	public R<Boolean> submitCost(@RequestBody TaskCost cost) {
+		return R.data(taskCostService.saveOrUpdate(cost));
+	}
+
+	/**
+	 * 任务成本详情
+	 */
+	@GetMapping("/task-cost-detail")
+	@ApiOperationSupport(order = 15)
+	@ApiOperation(value = "成本详情", notes = "")
+	public R<TaskCostVO> costDetail(@RequestParam Long id) {
+		TaskCost detail = taskCostService.getById(id);
+		return R.data(TaskCostWrapper.build().entityVO(detail));
+	}
+
+	/**
+	 * 删除成本记录
+	 */
+	@GetMapping("/delete-task-cost")
+	@ApiOperationSupport(order = 16)
+	@ApiOperation(value = "删除成本记录", notes = "传入主键ids")
+	public R<Boolean> deleteCost(@RequestParam String ids) {
+		return R.status(taskCostService.removeByIds(Func.toLongList(ids)));
+	}
+
+	/**
+	 * 成本分页
+	 */
+	@GetMapping("/task-cost-page")
+	@ApiOperationSupport(order = 17)
+	@ApiOperation(value = "成本分页", notes = "传入taskId,分页参数")
+	public R<IPage<TaskCostVO>> costPage(@RequestParam Long taskId, Query query) {
+		IPage<TaskCost> page = taskCostService.pageByTaskId(taskId, Condition.getPage(query));
+		return R.data(TaskCostWrapper.build().pageVO(page));
+	}
+
+	/**
+	 * 成本统计
+	 */
+	@GetMapping("/task-cost-statistics")
+	@ApiOperationSupport(order = 18)
+	@ApiOperation(value = "任务成本统计", notes = "传入taskId数")
+	public R<JSONObject> costStatistics(@RequestParam Long taskId) {
+		return R.data(taskCostService.costStatistics(taskId));
+	}
+
+
+
 
 }
+

+ 18 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/TaskCostMapper.java

@@ -0,0 +1,18 @@
+package com.wtkj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.TaskCost;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-18 14:13
+ * @describe
+ */
+public interface TaskCostMapper extends BaseMapper<TaskCost> {
+	List<TaskCost> selectByTaskId(Long taskId, IPage<TaskCost> page);
+
+	List<TaskCost> listByTaskId(Long taskId);
+}

+ 12 - 0
blade-service/wt-okr/src/main/java/com/wtkj/mapper/TaskCostMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.wtkj.mapper.TaskCostMapper">
+
+    <select id="selectByTaskId" resultType="com.wtkj.entity.TaskCost">
+        select * from blade_task_cost where is_deleted = 0 and task_id = #{param1}
+    </select>
+
+    <select id="listByTaskId" resultType="com.wtkj.entity.TaskCost">
+        select * from blade_task_cost where is_deleted = 0 and task_id = #{param}
+    </select>
+</mapper>

+ 21 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/ITaskCostService.java

@@ -0,0 +1,21 @@
+package com.wtkj.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.TaskCost;
+import org.springblade.core.mp.base.BaseService;
+
+import java.util.List;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-18 14:15
+ * @describe
+ */
+public interface ITaskCostService extends BaseService<TaskCost> {
+	IPage<TaskCost> pageByTaskId(Long taskId, IPage<TaskCost> page);
+
+	List<TaskCost> listByTaskId(Long taskId);
+
+	JSONObject costStatistics(Long taskId);
+}

+ 79 - 0
blade-service/wt-okr/src/main/java/com/wtkj/service/impl/TaskCostServiceImpl.java

@@ -0,0 +1,79 @@
+package com.wtkj.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.wtkj.entity.Project;
+import com.wtkj.entity.Task;
+import com.wtkj.entity.TaskCost;
+import com.wtkj.mapper.TaskCostMapper;
+import com.wtkj.service.IProjectService;
+import com.wtkj.service.ITaskCostService;
+import com.wtkj.service.ITaskService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.math.BigDecimal;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-18 14:16
+ * @describe
+ */
+@Service
+@AllArgsConstructor
+public class TaskCostServiceImpl extends BaseServiceImpl<TaskCostMapper, TaskCost> implements ITaskCostService {
+
+	private final ITaskService taskService;
+	private final IProjectService projectService;
+
+	@Override
+	public IPage<TaskCost> pageByTaskId(Long taskId, IPage<TaskCost> page) {
+		return page.setRecords(baseMapper.selectByTaskId(taskId, page));
+	}
+
+	@Override
+	public List<TaskCost> listByTaskId(Long taskId) {
+		return baseMapper.listByTaskId(taskId);
+	}
+
+	@Override
+	public JSONObject costStatistics(Long taskId) {
+		JSONObject res = new JSONObject();
+		int days = 0;
+		BigDecimal amount = BigDecimal.valueOf(0);
+		Task task = taskService.getById(taskId);
+		if (task != null) {
+			Long projectId = task.getProjectId();
+			if (projectId != null) {
+				Project byId = projectService.getById(projectId);
+				if (byId != null) {
+					Date createTime = byId.getCreateTime();
+					if (createTime != null) {
+						Instant instant = createTime.toInstant();
+						ZoneId zoneId = ZoneId.systemDefault();
+						LocalDate createDate = instant.atZone(zoneId).toLocalDate();
+						LocalDate now = LocalDate.now(zoneId);
+						Period between = Period.between(createDate, now);
+						days = between.getDays();
+					}
+				}
+			}
+		}
+		List<TaskCost> costs = this.listByTaskId(taskId);
+		if (!CollectionUtils.isEmpty(costs)) {
+			amount = costs.stream().map(TaskCost::getAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
+		}
+		res.put("days", days);
+		res.put("amount", amount);
+		return res;
+	}
+}

+ 11 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/TaskContractWrapper.java

@@ -2,6 +2,8 @@ package com.wtkj.wrapper;
 
 import com.wtkj.entity.TaskContract;
 import com.wtkj.vo.TaskContractVO;
+import com.wutong.file.feign.IFileClient;
+import com.wutong.file.vo.FileVO;
 import org.springblade.core.mp.support.BaseEntityWrapper;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
@@ -19,9 +21,11 @@ import java.util.Objects;
 public class TaskContractWrapper extends BaseEntityWrapper<TaskContract, TaskContractVO> {
 
 	private static ISysClient sysClient;
+	private static IFileClient fileClient;
 
 	public static TaskContractWrapper build() {
 		sysClient = SpringUtil.getBean(ISysClient.class);
+		fileClient = SpringUtil.getBean(IFileClient.class);
 		return new TaskContractWrapper();
 	}
 
@@ -33,6 +37,13 @@ public class TaskContractWrapper extends BaseEntityWrapper<TaskContract, TaskCon
 		if (rpc.isSuccess()) {
 			vo.setPartyB(rpc.getData().getDeptName());
 		}
+		Long fileId = entity.getBladeFileId();
+		if (fileId != null) {
+			R<FileVO> byId = fileClient.findById(fileId);
+			if (byId.isSuccess()) {
+				vo.setFileVO(byId.getData());
+			}
+		}
 		return vo;
 	}
 }

+ 59 - 0
blade-service/wt-okr/src/main/java/com/wtkj/wrapper/TaskCostWrapper.java

@@ -0,0 +1,59 @@
+package com.wtkj.wrapper;
+
+import com.wtkj.entity.TaskCost;
+import com.wtkj.vo.TaskCostVO;
+import com.wutong.file.feign.IFileClient;
+import com.wutong.file.vo.FileVO;
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.SpringUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.system.user.entity.User;
+import org.springblade.system.user.feign.IUserClient;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Blizzard
+ * @create at 2023-09-18 14:29
+ * @describe
+ */
+public class TaskCostWrapper extends BaseEntityWrapper<TaskCost, TaskCostVO> {
+
+	private static IUserClient userClient;
+	private static IFileClient fileClient;
+
+	public static TaskCostWrapper build() {
+		userClient = SpringUtil.getBean(IUserClient.class);
+		fileClient = SpringUtil.getBean(IFileClient.class);
+		return new TaskCostWrapper();
+	}
+
+	@Override
+	public TaskCostVO entityVO(TaskCost entity) {
+		TaskCostVO vo = Objects.requireNonNull(BeanUtil.copy(entity, TaskCostVO.class));
+		Long createUser = entity.getCreateUser();
+		R<User> userR = userClient.userInfoById(createUser);
+		if (userR.isSuccess()) {
+			vo.setSubmitUser(userR.getData().getName());
+		}
+		//报销凭证
+		String bladeFileIds = entity.getBladeFileIds();
+		if (StringUtil.isNotBlank(bladeFileIds)) {
+			List<FileVO> files = new ArrayList<>();
+			List<Long> fileIds = Func.toLongList(bladeFileIds);
+			fileIds.forEach(fileId -> {
+				R<FileVO> byId = fileClient.findById(fileId);
+				if (byId.isSuccess()) {
+					files.add(byId.getData());
+				}
+			});
+			vo.setFiles(files);
+		}
+		return vo;
+	}
+}