Commit 8ed6283b authored by wangqiang's avatar wangqiang

季报功能开发:下发行动项、批量下载季报报表、自动判断季报下所有行动项的状态时候是已完成。

parent cb7fba85
......@@ -402,6 +402,11 @@ public class Constants {
* 已答复
*/
public static final String ANSWERED = "answered";
/**
* 状态:信息收集中
*/
public static final String INFORMATION_COLLECTION = "InformationCollection";
/**
* 技术联系单的内容附件
*/
......
......@@ -271,6 +271,48 @@ public class FileUtils {
}
}
/**
* base64转换为文件,放入指定文件目录中
* @param base64
* @param fileName
* @param tempDir 临时文件目录
*/
public static String base64ToFile(String base64, String fileName,String tempDir) {
File file = null;
File dir = new File(tempDir);
if (!dir.exists() && !dir.isDirectory()) {
dir.mkdirs();
}
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
byte[] bytes = Base64.getDecoder().decode(base64);
file = new File(tempDir + "\\" + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bytes);
} catch (Exception e) {
log.error(e.getMessage());
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
}
return tempDir;
}
/**
* 按时间戳生成word名称
*
......@@ -402,7 +444,7 @@ public class FileUtils {
* @param inputData
* @throws IOException
*/
public static void downloadFile(HttpServletResponse response, InputStream inputData, DxDocumentVO doc) throws IOException {
public static void downloadFile(HttpServletResponse response, InputStream inputData, String fileName) throws IOException {
//放到缓冲流里面
BufferedInputStream bins = new BufferedInputStream(inputData);
//获取文件输出IO流
......@@ -410,7 +452,7 @@ public class FileUtils {
BufferedOutputStream bouts = new BufferedOutputStream(outs);
response.setContentType(Constants.DOWNLOAD_ZIP_TYPE);
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(doc.getNumber() + "-" + doc.getName(), "UTF-8") + ".zip");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".zip");
int bytesRead = 0;
byte[] buffer = new byte[8192];
//开始向网络传输文件流
......
package com.yonde.dcs.plan.common.utils;
import cn.hutool.core.io.FileUtil;
import com.yonde.dcs.plan.common.constants.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.system.ApplicationHome;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.UUID;
/**
* @program: service
......@@ -16,6 +22,9 @@ import java.util.Properties;
@Slf4j
public class ResourceHelper {
public static String baseHomeDir;
/**
* 获取外部资源配置
* @return
......@@ -31,4 +40,26 @@ public class ResourceHelper {
}
return prop;
}
/**
* 获取jar包所在目录
*
* @return
*/
public static String getBaseHomeDir() {
if (StringUtils.isEmpty(baseHomeDir)) {
ApplicationHome home = new ApplicationHome(Constants.class);
baseHomeDir = home.getSource().getParentFile().getPath();
}
return baseHomeDir;
}
public static File createTempDir() {
String uuid = UUID.randomUUID().toString().replace("-", "");
String temDir = getBaseHomeDir() + File.separator +
"temp" + File.separator +
uuid;
return FileUtil.mkdir(temDir);
}
}
......@@ -4,10 +4,15 @@ import com.yonde.dcs.plan.common.vo.ExtQuarterlyReportVO;
import com.yonde.dcs.plan.core.controller.shadow.ExtQuarterlyReportControllerShadow;
import com.yonde.dcs.plan.core.service.ExtQuarterlyReportService;
import com.yonde.dex.basedata.auth.annos.BasePermission;
import com.yonde.dex.basedata.entity.api.ApiResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @description: ExtQuarterlyReport-Controller
......@@ -23,6 +28,27 @@ import org.springframework.web.bind.annotation.ResponseBody;
public class ExtQuarterlyReportController<V extends ExtQuarterlyReportVO, S extends ExtQuarterlyReportService<V>> extends ExtQuarterlyReportControllerShadow<V, S> {
@Autowired
private ExtQuarterlyReportService extQuarterlyReportService;
/**
* 批量下载季报报表
*
* @param response
* @param id
* @throws IOException
*/
@ApiOperation(value = "批量下载季报报表", notes = "批量下载", httpMethod = "GET")
@GetMapping(value = "/batchDownloadDoc")
public void batchDownloadDoc(HttpServletResponse response, @RequestParam("id") Long id) throws IOException {
extQuarterlyReportService.batchDownloadDoc(response, id);
}
@ApiOperation(value = "下发行动项", notes = "下发行动项", httpMethod = "POST")
@PostMapping(value = "/sendActionItems")
public ApiResult startWorkflow(@RequestParam("id") Long id) {
return ApiResult.ok(extQuarterlyReportService.startWorkflow(id),"下发成功!");
}
}
......@@ -2,6 +2,9 @@ package com.yonde.dcs.plan.core.service;
import com.yonde.dcs.plan.common.vo.ExtActionItemVO;
import com.yonde.dcs.plan.core.service.shadow.ExtActionItemServiceShadow;
import java.util.List;
/**
* @description: ExtActionItem-service
* @author: dexadmin
......@@ -10,4 +13,14 @@ import com.yonde.dcs.plan.core.service.shadow.ExtActionItemServiceShadow;
**/
public interface ExtActionItemService<V extends ExtActionItemVO> extends ExtActionItemServiceShadow<V> {
/**
* 季报下的所有行动项如果已完成,将季报状态置为待审阅
* @param id 行动项的id
* @return
*/
String changeQRStateWhenAllActionItemIsDone(Long id);
}
......@@ -2,6 +2,11 @@ package com.yonde.dcs.plan.core.service;
import com.yonde.dcs.plan.common.vo.ExtQuarterlyReportVO;
import com.yonde.dcs.plan.core.service.shadow.ExtQuarterlyReportServiceShadow;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* @description: ExtQuarterlyReport-service
* @author: dexadmin
......@@ -10,4 +15,20 @@ import com.yonde.dcs.plan.core.service.shadow.ExtQuarterlyReportServiceShadow;
**/
public interface ExtQuarterlyReportService<V extends ExtQuarterlyReportVO> extends ExtQuarterlyReportServiceShadow<V> {
/**
* 批量下载季报下所有行动项的附件
*
* @param response
* @param id
* @throws IOException
*/
void batchDownloadDoc(HttpServletResponse response, Long id) throws IOException;
/**
* 启动行动项
* @param id
* @return
*/
String startWorkflow(Long id);
}
package com.yonde.dcs.plan.core.service.impl;
import com.yonde.dcs.plan.common.constants.Constants;
import com.yonde.dcs.plan.common.utils.SearchUtil;
import com.yonde.dcs.plan.common.vo.ExtActionItemVO;
import com.yonde.dcs.plan.common.vo.ExtQuarterlyReportVO;
import com.yonde.dcs.plan.core.repository.ExtActionItemRepository;
import com.yonde.dcs.plan.core.service.ExtActionItemService;
import com.yonde.dcs.plan.core.service.ExtQuarterlyReportService;
import com.yonde.dcs.plan.entity.po.ExtActionItem;
import com.yonde.dex.basedata.data.search.SearchItem;
import com.yonde.dex.basedata.data.search.SearchQueryCondition;
import com.yonde.dex.basedata.entity.api.ApiResult;
import com.yonde.dex.basedata.entity.data.DxPageImpl;
import com.yonde.dex.basedata.entity.vo.IdVO;
import com.yonde.dex.basedata.exception.DxBusinessException;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.List;
/**
* @description: ExtActionItem-ServiceImpl
* @author: dexadmin
* @version: V
* @date: 2024-11-5 10:16:12
**/
* @description: ExtActionItem-ServiceImpl
* @author: dexadmin
* @version: V
* @date: 2024-11-5 10:16:12
**/
@Slf4j
@Service(ExtActionItemServiceImpl.BEAN_NAME)
public class ExtActionItemServiceImpl<V extends ExtActionItemVO> implements ExtActionItemService<V>{
public class ExtActionItemServiceImpl<V extends ExtActionItemVO> implements ExtActionItemService<V> {
public static final String BEAN_NAME = "extActionItemServiceImpl";
@Autowired
ExtActionItemRepository<ExtActionItem> extActionItemRepository;
@Autowired
private ExtQuarterlyReportService extQuarterlyReportService;
@Transactional(rollbackFor = Exception.class)
@Override
public String changeQRStateWhenAllActionItemIsDone(Long id) {
Boolean allActionItemIsCompleteFlag = false;
ExtActionItemVO extActionItemVO = this.findLatest(id);
if (ObjectUtils.isEmpty(extActionItemVO)) {
throw new DxBusinessException("-1", "根据行动项id:" + id + "未查到数据");
}
SearchQueryCondition searchQRById = SearchUtil.buildQueryWithOpenAttr("id",
SearchItem.Operator.EQ,
extActionItemVO.getExtQuarterlyReport().getId(),
"extActionItems"
);
ExtQuarterlyReportVO extQuarterlyReportVO = (ExtQuarterlyReportVO) extQuarterlyReportService.findOne(searchQRById);
for (ExtActionItemVO actionItem : extQuarterlyReportVO.getExtActionItems()){
if(!actionItem.getState().equals(Constants.COMPLETE)){
break;
}
allActionItemIsCompleteFlag = true;
}
if(allActionItemIsCompleteFlag){
extQuarterlyReportService.changeStatus(extQuarterlyReportVO.getId(),Constants.PENDING_REVIEW,true);
}
return ApiResult.SUCCESS;
}
}
......
package com.yonde.dcs.plan.core.service.impl;
import cn.hutool.core.util.ZipUtil;
import com.yonde.dcs.document.common.entity.vo.DxDocumentVO;
import com.yonde.dcs.plan.common.constants.Constants;
import com.yonde.dcs.plan.common.utils.FileUtils;
import com.yonde.dcs.plan.common.utils.ResourceHelper;
import com.yonde.dcs.plan.common.utils.SearchUtil;
import com.yonde.dcs.plan.common.vo.ExtActionItemVO;
import com.yonde.dcs.plan.common.vo.ExtQuarterlyReportVO;
import com.yonde.dcs.plan.core.repository.ExtQuarterlyReportRepository;
import com.yonde.dcs.plan.core.service.ExtQuarterlyReportService;
import com.yonde.dcs.plan.entity.po.ExtQuarterlyReport;
import com.yonde.dex.basedata.data.search.SearchItem;
import com.yonde.dex.basedata.data.search.SearchItems;
import com.yonde.dex.basedata.data.search.SearchQueryCondition;
import com.yonde.dex.basedata.entity.api.ApiResult;
import com.yonde.dex.basedata.entity.data.DxPageImpl;
import com.yonde.dex.basedata.exception.DxBusinessException;
import com.yonde.dex.dfs.feign.FileManagerFeignService;
import com.yonde.dex.dfs.vo.ObjFileLinkVO;
import com.yonde.dex.dfs.vo.view.FileDownLoadInfoVO;
import com.yonde.dex.wfc.feign.api.WfcProcessFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @description: ExtQuarterlyReport-ServiceImpl
* @author: dexadmin
* @version: V
* @date: 2024-11-5 10:16:11
**/
* @description: ExtQuarterlyReport-ServiceImpl
* @author: dexadmin
* @version: V
* @date: 2024-11-5 10:16:11
**/
@Slf4j
@Service(ExtQuarterlyReportServiceImpl.BEAN_NAME)
public class ExtQuarterlyReportServiceImpl<V extends ExtQuarterlyReportVO> implements ExtQuarterlyReportService<V>{
public class ExtQuarterlyReportServiceImpl<V extends ExtQuarterlyReportVO> implements ExtQuarterlyReportService<V> {
public static final String BEAN_NAME = "extQuarterlyReportServiceImpl";
......@@ -24,6 +52,103 @@ public class ExtQuarterlyReportServiceImpl<V extends ExtQuarterlyReportVO> imple
@Autowired
ExtQuarterlyReportRepository<ExtQuarterlyReport> extQuarterlyReportRepository;
@Autowired
private FileManagerFeignService fileManagerService;
@Autowired
private WfcProcessFeign wfcProcessFeign;
@Override
public void batchDownloadDoc(HttpServletResponse response, Long id) throws IOException {
//文件id集合
List<Long> fileIds = new ArrayList<>();
//临时文件目录
String tempDir = ResourceHelper.createTempDir().getPath();
SearchQueryCondition query = SearchQueryCondition.builder()
.openProp(SearchQueryCondition.builder().name("extActionItems")
.openProp(SearchQueryCondition.builder().name("objFileLinks").build())
.openProp(SearchQueryCondition.builder().name("target").build()).build())
.searchItems(SearchItems.builder()
.item(new SearchItem("id", SearchItem.Operator.EQ, id, null))
.item(new SearchItem("latest", SearchItem.Operator.EQ, true, null))
.operator(SearchItems.BooleanOperator.AND).build()).build();
List<V> quarterlyReportVOList = this.findRecursion(query).getContent();
if (!ObjectUtils.isEmpty(quarterlyReportVOList)) {
ExtQuarterlyReportVO extQuarterlyReportVO = quarterlyReportVOList.get(0);
this.extFindFileIds(fileIds, extQuarterlyReportVO.getObjFileLinks(), Constants.MASTER_FILE);
if (!CollectionUtils.isEmpty(fileIds)) {
fileIds.stream().forEach(fileId -> {
try {
//通过fileId下载文件
FileDownLoadInfoVO fileDownLoadInfoVO = fileManagerService.download(fileId);
FileUtils.base64ToFile(fileDownLoadInfoVO.getFileBase64(), fileDownLoadInfoVO.getFileName(), tempDir);
} catch (Exception e) {
throw new DxBusinessException("-1", "批量下载文件失败" + e.getMessage());
}
});
//压缩文件
downloadDataZip(response, tempDir);
} else {
throw new DxBusinessException("-1", "根据季报id:" + id + "未查到数据");
}
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public String startWorkflow(Long id) {
SearchQueryCondition searchQueryCondition = SearchUtil.buildQueryWithOpenAttr("id", SearchItem.Operator.EQ, id, "extActionItems");
List<V> content = this.findRecursion(searchQueryCondition).getContent();
if (!ObjectUtils.isEmpty(content)) {
ExtQuarterlyReportVO extQuarterlyReportVO = content.get(0);
if (ObjectUtils.isEmpty(extQuarterlyReportVO.getExtActionItems())) {
throw new DxBusinessException("-1", "该季报下的行动项不能为空,启动失败!");
}
//批量启动行动项工作流
for (ExtActionItemVO extActionItemVO : extQuarterlyReportVO.getExtActionItems()) {
wfcProcessFeign.startProcessByKey("ExtActionItemWF", extActionItemVO);
}
//修改季报的状态未信息收集中
this.changeStatus(extQuarterlyReportVO.getId(), Constants.INFORMATION_COLLECTION, true);
} else {
throw new DxBusinessException("-1", "为查到id:" + id + "的季报对象");
}
return ApiResult.SUCCESS;
}
/**
* 批量下载季报报表文件
*
* @param response
* @param dir
* @throws IOException
*/
private void downloadDataZip(HttpServletResponse response, String dir) throws IOException {
File zip = ZipUtil.zip(dir);
InputStream inputStream = FileUtils.fileToInputStream(zip);
FileUtils.downloadFile(response, inputStream, "季报报表");
}
/**
* 通过objFileLink读取id
*
* @param fileIds
* @param objFileLinks
*/
private void extFindFileIds(List<Long> fileIds, List<ObjFileLinkVO> objFileLinks, String fileType) {
if (!CollectionUtils.isEmpty(objFileLinks)) {
//遍历取主内容的文件id
List<ObjFileLinkVO> objFileLinkVOs = objFileLinks.stream().filter(n -> n.getContentType().equals(fileType)).collect(Collectors.toList());
objFileLinkVOs.stream().forEach(o -> {
fileIds.add(o.getTargetId());
});
}
}
}
package com.yonde.dcs.plan.entity.po;
import org.springframework.data.annotation.CreatedBy;
import javax.persistence.UniqueConstraint;
import java.util.Date;
import java.time.LocalDateTime;
import lombok.EqualsAndHashCode;
import org.springframework.data.annotation.LastModifiedDate;
import com.yonde.dex.dao.entity.base.IdEntity;
import org.springframework.data.annotation.LastModifiedBy;
import javax.persistence.Column;
import org.springframework.data.annotation.CreatedDate;
import com.yonde.dex.basedata.entity.annotation.DexEmbedded;
import com.yonde.dex.dao.entity.base.DxIdEntityEmbeddable;
import com.yonde.dex.dao.entity.base.IdEntity;
import com.yonde.dex.dao.entity.base.IdOnlyEntity;
import com.yonde.dex.dfs.objfilelink.plugin.entities.DxObjFileLinkEmbeddable;
import com.yonde.dex.dfs.objfilelink.plugin.entities.DxObjFileLinkHolder;
import com.yonde.dex.lcycle.plugin.entities.DxLifecycleManageBaseEmbeddable;
import com.yonde.dex.lcycle.plugin.entities.DxLifecycleManageBaseHolder;
import com.yonde.dex.secretcode.plugin.entities.DxSecretEmbeddable;
import com.yonde.dex.secretcode.plugin.entities.DxSecretHolder;
import lombok.Data;
import com.yonde.dex.basedata.entity.annotation.*;
import java.math.BigInteger;
import javax.persistence.*;
import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Table;
import com.yonde.dex.lcycle.plugin.entities.DxLifecycleManageBaseEmbeddable;
import com.yonde.dex.dao.entity.base.IdEntity;
import javax.persistence.Column;
import com.yonde.dex.dfs.objfilelink.plugin.entities.DxObjFileLinkHolder;
import com.yonde.dex.dfs.objfilelink.plugin.entities.DxObjFileLinkEmbeddable;
import com.yonde.dex.secretcode.plugin.entities.DxSecretHolder;
import com.yonde.dex.lcycle.plugin.entities.DxLifecycleManageBaseHolder;
import com.yonde.dex.dao.entity.base.DxIdEntityEmbeddable;
import com.yonde.dex.secretcode.plugin.entities.DxSecretEmbeddable;
import com.yonde.dex.dao.entity.base.IdOnlyEntity;
import java.time.LocalDateTime;
/**
* @description: ExtActionItem-PO实体
* @author: dexadmin
* @version: V
* @date: 2024-11-5 11:10:05
* @date: 2024-11-5 10:16:11
**/
@Entity
@EqualsAndHashCode(callSuper = true)
......@@ -118,18 +104,6 @@ public class ExtActionItem extends IdOnlyEntity implements DxObjFileLinkHolder ,
* 序号,只有项目进展类型有
*/
private String serialNumber;
/**
* 任务启动时间
*/
private LocalDateTime taskReleaseDate;
/**
* 任务发布人的id
*/
private Long taskReleasePersonId;
/**
* 任务发布人的类型
*/
private String taskReleasePersonIdType;
}
......@@ -3,7 +3,10 @@ package com.yonde.dcs.plan.feign;
import com.yonde.dcs.plan.common.vo.ExtActionItemVO;
import com.yonde.dcs.plan.feign.shadow.ExtActionItemServiceFeignShadow;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @description: ExtActionItem-Feign
......@@ -15,4 +18,8 @@ import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(value = "${dcs.feign.INET-PLAN}", path = "/ExtActionItem")
public interface ExtActionItemServiceFeign<V extends ExtActionItemVO> extends ExtActionItemServiceFeignShadow<V> {
@ApiOperation(value = "根据行动项id修改季报的状态", notes = "根据行动项id修改季报的状态")
@GetMapping(value = "/updateQRStateByAItemId")
String changeQRStateWhenAllActionItemIsDone(@RequestParam("id") Long id);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment