add:项目搭建

This commit is contained in:
2025-01-14 15:43:20 +08:00
parent d9659a87b2
commit bf0248478c
63 changed files with 4439 additions and 252 deletions

View File

@@ -293,6 +293,13 @@
<version>5.23</version>
</dependency>
<!-- 图片处理 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>

View File

@@ -15,12 +15,14 @@ import org.nl.system.service.tools.IToolLocalStorageService;
import org.nl.system.service.tools.dao.ToolLocalStorage;
import org.nl.system.service.tools.dto.ToolLocalStorageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Map;
import java.util.Set;
/**
@@ -44,6 +46,12 @@ public class ToolLocalStorageController {
}
@GetMapping("/queryId")
public ResponseEntity<Object> queryId(@RequestParam Map whereJson, Pageable page) {
return new ResponseEntity<>(localStorageService.queryId(whereJson, page), HttpStatus.OK);
}
@PostMapping
@SaIgnore
public ResponseEntity<Object> create(@RequestParam String name, @RequestParam("file") MultipartFile file) {

View File

@@ -126,4 +126,10 @@ public class UserController {
return new ResponseEntity<>(HttpStatus.OK);
}
@Log("获取用户集合")
@PostMapping("/getUserList")
public ResponseEntity<Object> getUserList(@RequestBody JSONObject whereJson){
return new ResponseEntity<>(userService.getUserList(whereJson), HttpStatus.OK);
}
}

View File

@@ -8,6 +8,7 @@ import org.nl.system.service.tools.dto.ToolLocalStorageQuery;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import java.util.Map;
import java.util.Set;
/**
@@ -34,7 +35,7 @@ public interface IToolLocalStorageService extends IService<ToolLocalStorage> {
* @param file
* @return
*/
Object create(String name, MultipartFile file);
ToolLocalStorage create(String name, MultipartFile file);
/**
* 修改文件
@@ -47,4 +48,6 @@ public interface IToolLocalStorageService extends IService<ToolLocalStorage> {
* @param ids
*/
void deleteAll(Set<String> ids);
Map<String, Object> queryId(Map whereJson, Pageable page);
}

View File

@@ -87,5 +87,10 @@ public class ToolLocalStorage implements Serializable {
*/
private String update_time;
/**
* 源单标识
*/
private String source_bill_id;
}

View File

@@ -4,7 +4,9 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.nl.common.domain.query.PageQuery;
import org.nl.config.FileProperties;
import org.nl.common.exception.BadRequestException;
@@ -16,12 +18,16 @@ import org.nl.system.service.tools.dao.mapper.ToolLocalStorageMapper;
import org.nl.system.service.tools.IToolLocalStorageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.system.service.tools.dto.ToolLocalStorageQuery;
import org.nl.work.service.demandmanage.dao.DemanDmanage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
@@ -47,7 +53,7 @@ public class ToolLocalStorageServiceImpl extends ServiceImpl<ToolLocalStorageMap
@Override
@Transactional(rollbackFor = Exception.class)
public Object create(String name, MultipartFile multipartFile) {
public ToolLocalStorage create(String name, MultipartFile multipartFile) {
FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize());
String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
String type = FileUtil.getFileType(suffix);
@@ -104,4 +110,22 @@ public class ToolLocalStorageServiceImpl extends ServiceImpl<ToolLocalStorageMap
}
});
}
@Override
public Map<String, Object> queryId(Map whereJson, Pageable page) {
Map<String, Object> mapResult = new HashMap<>();
// 组织查询条件
LambdaQueryWrapper<ToolLocalStorage> queryWrapper = new LambdaQueryWrapper<>();
if (whereJson.containsKey("search")) {
queryWrapper.like(ToolLocalStorage::getName, whereJson.get("search"));
}
if (whereJson.containsKey("id")) {
queryWrapper.eq(ToolLocalStorage::getSource_bill_id, whereJson.get("id"));
}
IPage<ToolLocalStorage> resultPage = localStorageMapper.selectPage(new Page<>(page.getPageNumber() + 1, page.getPageSize()), queryWrapper);
mapResult.put("content", resultPage.getRecords());
mapResult.put("totalElements", resultPage.getTotal());
return mapResult;
}
}

View File

@@ -1,5 +1,6 @@
package org.nl.system.service.user;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.common.domain.query.PageQuery;
import org.nl.system.service.user.dao.SysUser;
@@ -80,4 +81,11 @@ public interface ISysUserService extends IService<SysUser> {
* @return List<String>
*/
List<String> getUserIdByDeptId(String deptId);
/**
* 获取用户集合
* @param whereJson {查询参数}
* @return List<SysUser> 用户集合
*/
List<SysUser> getUserList(JSONObject whereJson);
}

View File

@@ -3,6 +3,8 @@ package org.nl.system.service.user.impl;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
@@ -156,4 +158,11 @@ public class ISysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> imp
public List<String> getUserIdByDeptId(String deptId) {
return sysUserMapper.getUserIdByDeptId(deptId);
}
@Override
public List<SysUser> getUserList(JSONObject whereJson) {
LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
sysUserLambdaQueryWrapper.eq(SysUser::getIs_used, true);
return sysUserMapper.selectList(sysUserLambdaQueryWrapper);
}
}

View File

@@ -0,0 +1,58 @@
package org.nl.system.util;
import net.coobird.thumbnailator.Thumbnails;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.FileUtil;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.math.BigDecimal;
/*
* @author Liuxy
* @Date 2024/12/24 4:17 下午
*/
public class ImageCompress {
public static Long imgCompress(File file,Long desFileSize,Double accuracy,int threshold){
if (threshold>5){
return file.length();
}
long length = file.length();
//小于目标压缩文件大小的2倍就不压缩了
if (length>desFileSize*1024*2){
try {
BufferedImage bim = ImageIO.read(file);
int imgWidth = bim.getWidth();
int imgHeight = bim.getHeight();
int desWidth = new BigDecimal(imgWidth).multiply(
new BigDecimal(accuracy)).intValue();
int desHeight = new BigDecimal(imgHeight).multiply(
new BigDecimal(accuracy)).intValue();
Thumbnails.of(file.getPath()).size(desWidth, desHeight).outputQuality(accuracy).toFile(file.getPath());
//如果不满足要求,递归直至满足要求
imgCompress(file, desFileSize, accuracy,threshold);
}catch (Exception ex){
ex.printStackTrace();
}
}
return file.length();
};
public static Long imgCompress(String path,Long desFileSize,Double accuracy){
File file;
try {
file = new File(path);
String suffix = FileUtil.getExtensionName(file.getName());
if (!"图片".equals(FileUtil.getFileType(suffix))) {
return file.length();
}
}catch (Exception ex){
throw new BadRequestException("文件不存在");
}
int i = 0;
//小于目标压缩文件大小的2倍就不压缩了
return imgCompress(file, desFileSize==null?100L:desFileSize, accuracy==null?0.8:accuracy,i);
};
}

View File

@@ -0,0 +1,81 @@
package org.nl.work.controller;
import com.alibaba.fastjson.JSONObject;
import org.nl.common.logging.annotation.Log;
import org.nl.work.service.demandmanage.DemanDmanageService;
import org.nl.work.service.demandmanage.dao.DemanDmanage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Map;
import java.util.Set;
/**
* <p>
* 前端控制器
* </p>
*
* @author author
* @since 2024-12-23
*/
@RestController
@RequestMapping("/api/demandManage")
public class DemanDmanageController {
@Autowired
private DemanDmanageService demanDmanageService;
@GetMapping
@Log("查询需求")
public ResponseEntity<Object> query(@RequestParam Map whereJson, Pageable page) {
return new ResponseEntity<>(demanDmanageService.queryAll(whereJson, page), HttpStatus.OK);
}
@PostMapping({"/queryData"})
@Log("查询ui数据")
public ResponseEntity<Object> queryData(@RequestBody JSONObject dao) {
return new ResponseEntity<>(demanDmanageService.queryData(dao),HttpStatus.OK);
}
@PostMapping
@Log("新增需求")
public ResponseEntity<Object> create(@Validated @RequestBody DemanDmanage dao) {
demanDmanageService.create(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
@PutMapping
@Log("修改需求")
public ResponseEntity<Object> update(@Validated @RequestBody DemanDmanage dao) {
demanDmanageService.update(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping
@Log("删除需求")
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
demanDmanageService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping({"/uploadFile/{id}"})
@Log("文件上传")
public ResponseEntity<Object> uploadFile(@RequestParam MultipartFile file, @PathVariable String id) {
demanDmanageService.uploadFile(file,id);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping({"/confirm"})
@Log("确认完成")
public ResponseEntity<Object> confirm(@RequestBody DemanDmanage dao) {
demanDmanageService.confirm(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,93 @@
package org.nl.work.controller;
import com.alibaba.fastjson.JSONObject;
import org.nl.common.logging.annotation.Log;
import org.nl.work.service.demandtask.DemandTaskService;
import org.nl.work.service.demandtask.dao.DemandTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Set;
/**
* <p>
* 前端控制器
* </p>
*
* @author author
* @since 2024-12-25
*/
@RestController
@RequestMapping("/api/demandTask")
public class DemandTaskController {
@Autowired
private DemandTaskService demandTaskService;
@GetMapping
@Log("查询任务")
public ResponseEntity<Object> query(@RequestParam Map whereJson, Pageable page) {
return new ResponseEntity<>(demandTaskService.queryAll(whereJson, page), HttpStatus.OK);
}
@PostMapping
@Log("新增任务")
public ResponseEntity<Object> create(@Validated @RequestBody DemandTask dao) {
demandTaskService.create(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
@PutMapping
@Log("修改任务")
public ResponseEntity<Object> update(@Validated @RequestBody DemandTask dao) {
demandTaskService.update(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
@DeleteMapping
@Log("删除任务")
public ResponseEntity<Object> delete(@RequestBody Set<String> ids) {
demandTaskService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/queryUser")
@Log("获取参与人员名称")
public ResponseEntity<Object> queryUser(@RequestBody JSONObject whereJson) {
return new ResponseEntity<>(demandTaskService.queryUser(whereJson),HttpStatus.OK);
}
@PostMapping("/relevancyDemand")
@Log("关联需求")
public ResponseEntity<Object> relevancyDemand(@RequestBody DemandTask dao) {
demandTaskService.relevancyDemand(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/getUser")
@Log("获取开发人员角色")
public ResponseEntity<Object> getUser(@RequestBody JSONObject whereJson) {
return new ResponseEntity<>(demandTaskService.getUser(whereJson),HttpStatus.OK);
}
@PostMapping("/confirmUser")
@Log("指派人员")
public ResponseEntity<Object> confirmUser(@RequestBody DemandTask dao) {
demandTaskService.confirmUser(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/startTask")
@Log("开始任务")
public ResponseEntity<Object> startTask(@RequestBody DemandTask dao) {
demandTaskService.startTask(dao);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -0,0 +1,27 @@
package org.nl.work.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 需求状态
*/
@Getter
@AllArgsConstructor
public enum NeedStatusEnum {
/**
* 生成
*/
CREATE("1", "生成"),
/**
* 开发中
*/
DEVELOPING("2", "开发中"),
/**
* 完成
*/
CONFIRM("3", "完成");
private final String value;
private final String name;
}

View File

@@ -0,0 +1,39 @@
package org.nl.work.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 需求类型
*/
@Getter
@AllArgsConstructor
public enum NeedTypeEnum {
/**
* 生成
*/
ITEM("1", "项目"),
/**
* 开发中
*/
DEVELOP("2", "研发"),
/**
* 完成
*/
OTHER("3", "其他"),
/**
* P1
*/
P1("P1", "P1"),
/**
* P2
*/
P2("P2", "P2"),
/**
* P3
*/
P3("P3", "P3");
private final String value;
private final String name;
}

View File

@@ -0,0 +1,48 @@
package org.nl.work.sch;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.work.enums.NeedStatusEnum;
import org.nl.work.service.demandtask.DemandTaskService;
import org.nl.work.service.demandtask.dao.DemandTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class AutoUpdateTaskDate {
@Autowired
private DemandTaskService demandTaskService;
public void run() {
// 查询未完成任务
List<DemandTask> demandTaskList = demandTaskService.list(
new QueryWrapper<DemandTask>().lambda()
.ne(DemandTask::getTaskStatus, NeedStatusEnum.DEVELOPING.getValue())
);
for(DemandTask dao : demandTaskList) {
// 计算消耗时间:当前时间 - 开始时间
DateTime nowDate = DateUtil.parse(DateUtil.now());
DateTime startDate = DateUtil.parse(dao.getStartDate());
long useDate = DateUtil.between(nowDate, startDate, DateUnit.HOUR);
// 计算剩余时间:预计完成时间 -消耗时间
String surplusDate = NumberUtil.sub(dao.getPlanDate(), String.valueOf(useDate)).toString();
dao.setUseDate(String.valueOf(useDate));
dao.setSurplusDate(surplusDate);
}
// 更新
demandTaskService.updateBatchById(demandTaskList);
}
}

View File

@@ -0,0 +1,87 @@
package org.nl.work.service.demandmanage;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.work.service.demandmanage.dao.DemanDmanage;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* <p>
* 服务类
* </p>
*
* @author author
* @since 2024-12-23
*/
public interface DemanDmanageService extends IService<DemanDmanage> {
/**
* 分页查询
* @param whereJson{
* search模糊搜索需求描述、需求版本、项目名称、项目编码
* demandType需求类型
* priority优先级别
* }
* @param page : 分页参数
* @return Map<String, Object> {
* content分页数据
* totalElements条数
* }
*/
Map<String, Object> queryAll(Map whereJson, Pageable page);
/**
* UI数据
* @return JSONObject ui数据
*/
JSONObject queryData(JSONObject dao);
/**
* 新增需求
* @param dao需求实体对象
*/
void create(DemanDmanage dao);
/**
* 修改需求
* @param dao需求实体对象
*/
void update(DemanDmanage dao);
/**
* 删除需求
* @param ids {集合}
*/
void delete(Set<String> ids);
/**
* 根据项目编码找对应项目
* @param code: 编码
* @return List<DemanDmanage> : 需求集合
*/
List<DemanDmanage> queryItemCode(String code);
/**
* 上传文件
* @param file文件
* @param id需求id
*/
void uploadFile(MultipartFile file, String id);
/**
* 确认完成
* @param dao需求实体类
*/
void confirm(DemanDmanage dao);
/**
* 更新需求状态
* @param id 需求id
*/
void updateStatus(String id);
}

View File

@@ -0,0 +1,123 @@
package org.nl.work.service.demandmanage.dao;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author author
* @since 2024-12-23
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("nl_demandmanage")
public class DemanDmanage implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 需求标识
*/
@TableId(value = "id")
private String id;
/**
* 需求类型
*/
private String demandType;
/**
* 需求描述
*/
private String demandRemark;
/**
* 需求版本
*/
private String demandVersion;
/**
* 项目名称
*/
private String projectName;
/**
* 项目编码
*/
private String projectCode;
/**
* 项目负责人
*/
private String projectPerson;
/**
* 上线日期
*/
private String onlineDate;
/**
* 提出日期
*/
private String createDate;
/**
* 提出人
*/
private String createId;
/**
* 提出人名称
*/
private String createName;
/**
* 计划完成日期
*/
private String planDate;
/**
* 优先级
*/
private String priority;
/**
* 开发人日
*/
private String developDate;
/**
* 开发状态
*/
private String developStatus;
/**
* 备注
*/
private String remark;
/**
* 完成人
*/
private String confirmId;
/**
* 完成人名称
*/
private String confirmName;
/**
* 完成时间
*/
private String confirmDate;
}

View File

@@ -0,0 +1,16 @@
package org.nl.work.service.demandmanage.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.nl.work.service.demandmanage.dao.DemanDmanage;
/**
* <p>
* Mapper 接口
* </p>
*
* @author author
* @since 2024-12-23
*/
public interface DemanDmanageMapper extends BaseMapper<DemanDmanage> {
}

View File

@@ -0,0 +1,5 @@
<?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="org.nl.work.service.demandmanage.dao.mapper.DemanDmanageMapper">
</mapper>

View File

@@ -0,0 +1,246 @@
package org.nl.work.service.demandmanage.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.FileUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.IdUtil;
import org.nl.system.service.tools.IToolLocalStorageService;
import org.nl.system.service.tools.dao.ToolLocalStorage;
import org.nl.system.util.ImageCompress;
import org.nl.work.enums.NeedStatusEnum;
import org.nl.work.enums.NeedTypeEnum;
import org.nl.work.service.demandmanage.DemanDmanageService;
import org.nl.work.service.demandmanage.dao.DemanDmanage;
import org.nl.work.service.demandmanage.dao.mapper.DemanDmanageMapper;
import org.nl.work.service.demandtask.DemandTaskService;
import org.nl.work.service.demandtask.dao.DemandTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author author
* @since 2024-12-23
*/
@Service
public class DemanDmanageServiceImpl extends ServiceImpl<DemanDmanageMapper, DemanDmanage> implements DemanDmanageService {
@Autowired
private DemanDmanageMapper demanDmanageMapper;
@Autowired
private DemandTaskService demandTaskService;
@Autowired
private IToolLocalStorageService iToolLocalStorageService;
@Override
public Map<String, Object> queryAll(Map whereJson, Pageable page) {
Map<String, Object> mapResult = new HashMap<>();
// 组织查询条件
LambdaQueryWrapper<DemanDmanage> queryWrapper = new LambdaQueryWrapper<>();
if (whereJson.containsKey("search")) {
queryWrapper.like(DemanDmanage::getDemandRemark, whereJson.get("search"))
.or().like(DemanDmanage::getDemandVersion, whereJson.get("search"))
.or().like(DemanDmanage::getProjectName, whereJson.get("search"))
.or().like(DemanDmanage::getProjectCode, whereJson.get("search"));
}
if (whereJson.containsKey("demandType")) {
queryWrapper.eq(DemanDmanage::getDemandType, whereJson.get("demandType"));
}
if (whereJson.containsKey("priority")) {
queryWrapper.eq(DemanDmanage::getPriority, whereJson.get("priority"));
}
IPage<DemanDmanage> resultPage = demanDmanageMapper.selectPage(new Page<>(page.getPageNumber() + 1, page.getPageSize()), queryWrapper);
mapResult.put("content", resultPage.getRecords());
mapResult.put("totalElements", resultPage.getTotal());
return mapResult;
}
/**
* 1.查询项目数量:完成需求、未完成需求
* 2.项目类型:项目、研发、其他
* 3.项目等级P1.P2.P3
* 4.七天内上线项目
* @return JSONObject: 查询数据
*/
@Override
public JSONObject queryData(JSONObject json) {
JSONObject result = new JSONObject();
List<DemanDmanage> demanDmanageList = this.baseMapper.selectList(
new QueryWrapper<DemanDmanage>().lambda()
);
// 1.查询项目数量:完成需求、未完成需求
// 完成需求量
long accomplish = demanDmanageList.stream()
.filter(row -> row.getDevelopStatus().equals(NeedStatusEnum.CONFIRM.getValue())).count();
// 未完成
long unfinished = demanDmanageList.stream()
.filter(row -> !row.getDevelopStatus().equals(NeedStatusEnum.CONFIRM.getValue())).count();
// 2.项目类型:项目、研发、其他
List<DemanDmanage> itemTypeList = demanDmanageList.stream()
.filter(row -> !row.getDevelopStatus().equals(NeedStatusEnum.CONFIRM.getValue()))
.collect(Collectors.toList());
result.put("accomplish",accomplish);
result.put("unfinished",unfinished);
// 项目
long item = itemTypeList.stream()
.filter(row -> row.getDemandType().equals(NeedTypeEnum.ITEM.getValue())).count();
// 研发
long develop = itemTypeList.stream()
.filter(row -> row.getDemandType().equals(NeedTypeEnum.DEVELOP.getValue())).count();
// 其他
long other = itemTypeList.stream()
.filter(row -> row.getDemandType().equals(NeedTypeEnum.OTHER.getValue())).count();
Long[] typeList = {item, develop, other};
result.put("typeList",typeList);
// 3.项目等级P1.P2.P3
// P1
long p1 = itemTypeList.stream()
.filter(row -> row.getPriority().equals(NeedTypeEnum.P1.getValue())).count();
// P2
long p2 = itemTypeList.stream()
.filter(row -> row.getPriority().equals(NeedTypeEnum.P2.getValue())).count();
// P3
long p3 = itemTypeList.stream()
.filter(row -> row.getPriority().equals(NeedTypeEnum.P3.getValue())).count();
Long[] rankList = {p1, p2, p3};
result.put("rankList",rankList);
// 4.七天内上线项目
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(DemanDmanage dao) {
// 判断当前项目编码和版本必须唯一
checkItem(dao);
// 组织数据
dao.setId(IdUtil.getStringId());
dao.setCreateDate(DateUtil.today());
dao.setCreateId(SecurityUtils.getCurrentUserId());
dao.setCreateName(SecurityUtils.getCurrentNickName());
dao.setCreateDate(DateUtil.now());
dao.setDevelopStatus(NeedStatusEnum.CREATE.getValue());
demanDmanageMapper.insert(dao);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(DemanDmanage dao) {
demanDmanageMapper.updateById(dao);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<String> ids) {
demanDmanageMapper.deleteBatchIds(ids);
}
@Override
public List<DemanDmanage> queryItemCode(String code) {
return demanDmanageMapper.selectList(
new QueryWrapper<DemanDmanage>().lambda()
.eq(DemanDmanage::getProjectCode, code)
);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void uploadFile(MultipartFile file, String id) {
// 插数据
ToolLocalStorage toolLocalStorage = iToolLocalStorageService.create(null, file);
Long compressSize = ImageCompress.imgCompress(toolLocalStorage.getPath(), 100L, 0.8);
toolLocalStorage.setSize(FileUtil.getSize(compressSize));
toolLocalStorage.setSource_bill_id(id);
iToolLocalStorageService.update(toolLocalStorage);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void confirm(DemanDmanage dao) {
// 完成需求逻辑:需求下的任务必须全部都为完成
List<DemandTask> taskList = demandTaskService.queryIDList(dao.getId());
// 校验任务是否都为完成
boolean isStatus = taskList.stream()
.allMatch(row -> row.getTaskStatus().equals(NeedStatusEnum.CONFIRM.getValue()));
if (!isStatus) {
throw new BadRequestException("此需求下的任务还未全部完成,不能完成需求!");
}
// 更新状态
dao.setDevelopStatus(NeedStatusEnum.CONFIRM.getValue());
dao.setConfirmId(SecurityUtils.getCurrentUserId());
dao.setConfirmName(SecurityUtils.getCurrentNickName());
dao.setConfirmDate(DateUtil.today());
this.demanDmanageMapper.updateById(dao);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateStatus(String id) {
DemanDmanage demanDmanageDao = this.baseMapper.selectById(id);
// 判断此需求下的任务
List<DemandTask> demandTaskList = this.demandTaskService.queryIDList(id);
boolean isConfirm = demandTaskList.stream()
.allMatch(row -> row.getTaskStatus().equals(NeedStatusEnum.CONFIRM.getValue()));
boolean isDeveloping = demandTaskList.stream()
.anyMatch(row -> row.getTaskStatus().equals(NeedStatusEnum.CREATE.getValue()) ||
row.getTaskStatus().equals(NeedStatusEnum.DEVELOPING.getValue())
);
// 完成
if (isConfirm) {
demanDmanageDao.setDevelopStatus(NeedStatusEnum.CONFIRM.getValue());
}
// 开发中
if (isDeveloping) {
demanDmanageDao.setDevelopStatus(NeedStatusEnum.DEVELOPING.getValue());
}
this.baseMapper.updateById(demanDmanageDao);
}
/**
* 新增修改时校验需求是否重复
* @param dao 需求实体类
*/
private void checkItem(DemanDmanage dao) {
List<DemanDmanage> demandList = queryItemCode(dao.getProjectCode());
List<DemanDmanage> collect = demandList.stream()
.filter(row -> row.getDemandVersion().equals(dao.getDemandVersion())
&& !row.getDevelopStatus().equals(NeedStatusEnum.CONFIRM.getValue()))
.collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(collect)) {
throw new BadRequestException("当前项目编码【"+dao.getProjectCode()+"】存在相同版本的需求!");
}
}
}

View File

@@ -0,0 +1,95 @@
package org.nl.work.service.demandtask;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.work.service.demandtask.dao.DemandTask;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* <p>
* 服务类
* </p>
*
* @author author
* @since 2024-12-25
*/
public interface DemandTaskService extends IService<DemandTask> {
/**
* 查询任务
* @param whereJson{
* search模糊搜索需求版本、任务编码/描述、项目名称/编码)
* developId开发人员
* taskStatus任务状态
* }
* @param page : 分页参数
* @return Map<String, Object> {
* content分页数据
* totalElements条数
* }
*/
Map<String, Object> queryAll(Map whereJson, Pageable page);
/**
* 新增任务
* @param dao任务实体类
*/
void create(DemandTask dao);
/**
* 修改任务
* @param dao需求实体对象
*/
void update(DemandTask dao);
/**
* 获取参与人员名称
* @param whereJson {
* demandId: 需求ID
* }
* @return List<String>
*/
List<String> queryUser(JSONObject whereJson);
/**
* 根据需求id查询任务
* @param demandId 需求id
* @return List<DemandTask>:任务集合
*/
List<DemandTask> queryIDList(String demandId);
/**
* 删除任务
* @param ids标识集合
*/
void delete(Set<String> ids);
/**
* 关联需求
* @param dao任务实体类
*/
void relevancyDemand(DemandTask dao);
/**
* 获取开发人员角色
* @param whereJson {}
* @return List<String>
*/
List<JSONObject> getUser(JSONObject whereJson);
/**
* 指派人员
* @param dao 任务实体类
*/
void confirmUser(DemandTask dao);
/**
* 开始任务
* @param dao 任务实体类
*/
void startTask(DemandTask dao);
}

View File

@@ -0,0 +1,129 @@
package org.nl.work.service.demandtask.dao;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author author
* @since 2024-12-25
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("nl_demandtask")
public class DemandTask implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id标识
*/
@TableId(value = "id")
private String id;
/**
* 任务编码
*/
private String taskCode;
/**
* 任务描述
*/
private String taskName;
/**
* 任务状态
*/
private String taskStatus;
/**
* 开发人员
*/
private String developId;
/**
* 开发人员名称
*/
private String developName;
/**
* 需求标识
*/
private String demandId;
/**
* 创建人
*/
private String createId;
/**
* 创建人名称
*/
private String createName;
/**
* 创建时间
*/
private String createDate;
/**
* 完成人
*/
private String confirmId;
/**
* 完成人名称
*/
private String confirmName;
/**
* 完成时间
*/
private String confirmDate;
/**
* 预计完成时间
*/
private String planDate;
/**
* 开始时间
*/
private String startDate;
/**
* 消耗时间
*/
private String useDate;
/**
* 剩余时间
*/
private String surplusDate;
/**
* 截止日期
*/
private String overDate;
/**
* 开发状态
*/
private String developStatus;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,36 @@
package org.nl.work.service.demandtask.dao.mapper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.nl.work.service.demandtask.dao.DemandTask;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.Map;
/**
* <p>
* Mapper 接口
* </p>
*
* @author author
* @since 2024-12-25
*/
public interface DemandTaskMapper extends BaseMapper<DemandTask> {
/**
* 分页查询
* @param query{查询参数}
* @param pageQuery {分页参数}
* @return List<JSONObject> 返回集合
*/
List<JSONObject> getPageQuery(@Param("query") Map query, @Param("pageQuery") Pageable pageQuery);
/**
* 获取开发人员
* @return List<JSONObject>
*/
List<JSONObject> getUser();
}

View File

@@ -0,0 +1,53 @@
<?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="org.nl.work.service.demandtask.dao.mapper.DemandTaskMapper">
<select id="getPageQuery" resultType="java.util.Map">
SELECT
task.*,
demand.demandVersion,
demand.projectName,
demand.projectCode
FROM
nl_demandtask task
LEFT JOIN nl_demandmanage demand ON task.demandId = demand.id
<where>
1 = 1
<if test="query.taskStatus != null and query.taskStatus != ''">
and task.taskStatus = #{query.taskStatus}
</if>
<if test="query.developId != null and query.developId != ''">
and task.developId = #{query.developId}
</if>
<if test="query.demandId != null and query.demandId != ''">
and task.demandId = #{query.demandId}
</if>
<if test="query.search != null and query.search != ''">
and ( demand.demandVersion LIKE '%${query.search}%' or
task.taskCode LIKE '%${query.search}%' or
task.taskName LIKE '%${query.search}%' or
demand.projectName LIKE '%${query.search}%' or
demand.projectCode LIKE '%${query.search}%'
)
</if>
</where>
</select>
<select id="getUser" resultType="java.util.Map">
SELECT
a.user_id,
a.person_name
FROM
sys_users_roles roles
LEFT JOIN sys_user a ON roles.user_id = a.user_id
<where>
1 = 1
and roles.role_id = '1873638956067852288'
</where>
</select>
</mapper>

View File

@@ -0,0 +1,165 @@
package org.nl.work.service.demandtask.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.CodeUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.IdUtil;
import org.nl.system.service.user.ISysUserService;
import org.nl.system.service.user.dao.SysUser;
import org.nl.work.enums.NeedStatusEnum;
import org.nl.work.service.demandmanage.DemanDmanageService;
import org.nl.work.service.demandmanage.dao.DemanDmanage;
import org.nl.work.service.demandtask.DemandTaskService;
import org.nl.work.service.demandtask.dao.DemandTask;
import org.nl.work.service.demandtask.dao.mapper.DemandTaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author author
* @since 2024-12-25
*/
@Service
public class DemandTaskServiceImpl extends ServiceImpl<DemandTaskMapper, DemandTask> implements DemandTaskService {
@Autowired
private ISysUserService iSysUserService;
@Autowired
private DemanDmanageService demanDmanageService;
@Override
public Map<String, Object> queryAll(Map whereJson, Pageable pageaBle) {
Map<String, Object> mapResult = new HashMap<>();
Page<Object> page = PageHelper.startPage(pageaBle.getPageNumber() + 1, pageaBle.getPageSize());
page.setOrderBy("createDate DESC");
List<JSONObject> content = this.baseMapper.getPageQuery(whereJson, pageaBle);
mapResult.put("content", content);
mapResult.put("totalElements", page.getTotal());
return mapResult;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(DemandTask dao) {
// 组织数据
dao.setId(IdUtil.getStringId());
dao.setTaskCode(CodeUtil.getNewCode("TASK_CODE"));
dao.setTaskStatus(NeedStatusEnum.CREATE.getValue());
// 查找用户名称
if (ObjectUtil.isNotEmpty(dao.getDevelopId())) {
SysUser userDao = iSysUserService.getById(dao.getDevelopId());
dao.setDevelopName(userDao.getPerson_name());
}
dao.setCreateId(SecurityUtils.getCurrentUserId());
dao.setCreateName(SecurityUtils.getCurrentNickName());
dao.setCreateDate(DateUtil.now());
dao.setDevelopStatus(NeedStatusEnum.CREATE.getValue());
this.baseMapper.insert(dao);
// 如果需求id不为空则调用
if (ObjectUtil.isNotEmpty(dao.getDemandId())) {
this.demanDmanageService.updateStatus(dao.getDemandId());
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(DemandTask dao) {
// 查找用户名称
if (ObjectUtil.isNotEmpty(dao.getDevelopId())) {
SysUser userDao = iSysUserService.getById(dao.getDevelopId());
dao.setDevelopName(userDao.getPerson_name());
}
this.baseMapper.updateById(dao);
}
@Override
public List<String> queryUser(JSONObject whereJson) {
return this.baseMapper.selectList(
new QueryWrapper<DemandTask>().lambda()
.eq(DemandTask::getDemandId, whereJson.getString("demandId"))
).stream()
.map(DemandTask::getDevelopName)
.collect(Collectors.toList());
}
@Override
public List<DemandTask> queryIDList(String demandId) {
return this.baseMapper.selectList(
new QueryWrapper<DemandTask>().lambda()
.eq(DemandTask::getDemandId, demandId)
);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Set<String> ids) {
this.baseMapper.deleteBatchIds(ids);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void relevancyDemand(DemandTask dao) {
// 判断需求是否完成
DemanDmanage demandDao = demanDmanageService.getById(dao.getDemandId());
if (demandDao.getDevelopStatus().equals(NeedStatusEnum.CONFIRM.getValue())) {
throw new BadRequestException("不能绑定已完成需求!");
}
// 判断是否已经绑定需求
DemandTask demandTask = this.baseMapper.selectById(dao.getId());
if (ObjectUtil.isNotEmpty(demandTask.getDemandId())) {
throw new BadRequestException("该任务已经绑定需求!");
}
// 更新需求任务
this.baseMapper.updateById(dao);
// 更新需求状态
demandDao.setDevelopStatus(NeedStatusEnum.DEVELOPING.getValue());
demanDmanageService.updateById(demandDao);
}
@Override
public List<JSONObject> getUser(JSONObject whereJson) {
return this.baseMapper.getUser();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void confirmUser(DemandTask dao) {
this.baseMapper.updateById(dao);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void startTask(DemandTask dao) {
dao.setStartDate(DateUtil.now());
dao.setTaskStatus(NeedStatusEnum.DEVELOPING.getValue());
this.baseMapper.updateById(dao);
}
}