Commit 5165b094 authored by tianhongyang's avatar tianhongyang

Merge branch 'V20231129-中建一局二公司' of http://192.168.60.201/root/dsk-operate-sys...

Merge branch 'V20231129-中建一局二公司' of http://192.168.60.201/root/dsk-operate-sys into V20231129-中建一局二公司
parents 0d5acdc9 db4d37a2
...@@ -8,10 +8,14 @@ import org.springframework.beans.factory.annotation.Qualifier; ...@@ -8,10 +8,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport; import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
/** /**
* 异步配置 * 异步配置
...@@ -22,16 +26,56 @@ import java.util.concurrent.ScheduledExecutorService; ...@@ -22,16 +26,56 @@ import java.util.concurrent.ScheduledExecutorService;
@Configuration @Configuration
public class AsyncConfig extends AsyncConfigurerSupport { public class AsyncConfig extends AsyncConfigurerSupport {
@Autowired // @Autowired
@Qualifier("scheduledExecutorService") // @Qualifier("scheduledExecutorService")
private ScheduledExecutorService scheduledExecutorService; // private ScheduledExecutorService scheduledExecutorService;
//
// /**
// * 自定义 @Async 注解使用系统线程池
// */
// @Override
// public Executor getAsyncExecutor() {
// return scheduledExecutorService;
// }
/**
* 自定义 @Async 注解使用系统线程池
*/
@Override @Override
public Executor getAsyncExecutor() { public Executor getAsyncExecutor() {
return scheduledExecutorService; ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 核心线程数:线程池创建时候初始化的线程数
taskExecutor.setCorePoolSize(10);
// 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
taskExecutor.setMaxPoolSize(20);
// 缓冲队列:用来缓冲执行任务的队列
taskExecutor.setQueueCapacity(50);
// 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
taskExecutor.setKeepAliveSeconds(60);
// 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
taskExecutor.setThreadNamePrefix("HiTask-");
// 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)
//taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
taskExecutor.initialize();
//解决使用@Async注解,获取不到上下文信息的问题
taskExecutor.setTaskDecorator(runnable -> {
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
return ()->{
try {
// 我们set 进去 ,其实是一个ThreadLocal维护的.
RequestContextHolder.setRequestAttributes(requestAttributes);
runnable.run();
} finally {
// 最后记得释放内存
RequestContextHolder.resetRequestAttributes();
}
};
});
return taskExecutor;
} }
/** /**
......
...@@ -50,11 +50,7 @@ public class DataAnalysisComponent { ...@@ -50,11 +50,7 @@ public class DataAnalysisComponent {
@Async @Async
public void quantitySummaryDataAnalysis(CbProjectBaseBo bo) throws Exception { public void quantitySummaryDataAnalysis(CbProjectBaseBo bo) throws Exception {
//查询工料汇总导入文件 //查询工料汇总导入文件
List<CbProjectFile> fileList = projectFileService.list(Wrappers.<CbProjectFile>lambdaQuery() List<CbProjectFile> fileList = projectFileService.selectAnalysisList(bo.getProjectId(), CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY, bo.getCbStage());
.eq(CbProjectFile::getProjectId, bo.getProjectId())
.eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY)
.eq(CbProjectFile::getCbStage, bo.getCbStage())
.in(CbProjectFile::getFileParseStatus, Arrays.asList(1, 3)));
if (ObjectUtils.isEmpty(fileList)) return; if (ObjectUtils.isEmpty(fileList)) return;
//文件处理 //文件处理
for (CbProjectFile file : fileList) { for (CbProjectFile file : fileList) {
......
...@@ -134,7 +134,7 @@ public class CbSummaryController extends BaseController { ...@@ -134,7 +134,7 @@ public class CbSummaryController extends BaseController {
*/ */
@PostMapping("/analysisData") @PostMapping("/analysisData")
public void analysisData(Long projectId){ public void analysisData(Long projectId){
cbSummaryService.importCbProject(projectId); cbSummaryService.importCbSummary(projectId);
} }
} }
...@@ -88,4 +88,9 @@ public class CbSummaryActualListVo extends BaseEntity { ...@@ -88,4 +88,9 @@ public class CbSummaryActualListVo extends BaseEntity {
private String expenseDate; private String expenseDate;
private List<CbSummaryActualListVo> children; private List<CbSummaryActualListVo> children;
/**
* 是否有子级(0否1是)
*/
private Integer hasChildren;
} }
...@@ -53,6 +53,12 @@ public class CbSummaryCostAccountImportListener extends AnalysisEventListener<Cb ...@@ -53,6 +53,12 @@ public class CbSummaryCostAccountImportListener extends AnalysisEventListener<Cb
failureMsg.append("<br/>").append("第" + sort + "条数据序号为空"); failureMsg.append("<br/>").append("第" + sort + "条数据序号为空");
return; return;
} }
//成本科目不能为空
if (StringUtil.isBlank(importVo.getCbName())) {
failureNum++;
failureMsg.append("<br/>").append("第" + sort + "条数据成本科目为空");
return;
}
//父级数据处理 //父级数据处理
if (sort == 1) { if (sort == 1) {
...@@ -74,7 +80,7 @@ public class CbSummaryCostAccountImportListener extends AnalysisEventListener<Cb ...@@ -74,7 +80,7 @@ public class CbSummaryCostAccountImportListener extends AnalysisEventListener<Cb
@Override @Override
public String getAnalysis() { public String getAnalysis() {
if (failureNum > 0) { if (failureNum > 0) {
failureMsg.insert(0, "失败原因:共 " + failureNum + " 条数据格式不正确,错误如下:"); failureMsg.insert(0, "共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString()); throw new ServiceException(failureMsg.toString());
} else { } else {
successMsg.insert(0, "成本科目汇总数据已全部解析成功!共 " + getList().size() + " 条"); successMsg.insert(0, "成本科目汇总数据已全部解析成功!共 " + getList().size() + " 条");
......
package com.dsk.cscec.listener; package com.dsk.cscec.listener;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventListener;
import com.dsk.common.excel.ExcelListener; import com.dsk.common.excel.ExcelListener;
...@@ -42,8 +43,12 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm ...@@ -42,8 +43,12 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
@Override @Override
public void invoke(CbSummaryProjectImportVo importVo, AnalysisContext context) { public void invoke(CbSummaryProjectImportVo importVo, AnalysisContext context) {
//第一个序号不能为空? todo //名称不能为空
if (StringUtil.isBlank(importVo.getCbName())) {
failureNum++;
failureMsg.append("<br/>").append("第" + sort + "条数据名称为空");
return;
}
//添加父级数据 //添加父级数据
if (sort == 0) { if (sort == 0) {
CbSummaryProjectImportVo firstVo = new CbSummaryProjectImportVo(); CbSummaryProjectImportVo firstVo = new CbSummaryProjectImportVo();
...@@ -63,8 +68,12 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm ...@@ -63,8 +68,12 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
//按sort倒序取number不为空的最大level //按sort倒序取number不为空的最大level
Object[] objects = resultList.stream().sorted(Comparator.comparingInt(CbSummaryProjectImportVo::getSort).reversed()) Object[] objects = resultList.stream().sorted(Comparator.comparingInt(CbSummaryProjectImportVo::getSort).reversed())
.filter(vo -> StringUtil.isNotBlank(vo.getNumber())).limit(1).map(CbSummaryProjectImportVo::getLevel).toArray(); .filter(vo -> StringUtil.isNotBlank(vo.getNumber())).limit(1).map(CbSummaryProjectImportVo::getLevel).toArray();
//数据序号错误 todo //数据序号错误
if (ObjectUtil.isEmpty(objects)) {
failureNum++;
failureMsg.append("<br/>").append("第" + sort + "条数据序号错误");
return;
}
Integer lastLevel = (Integer) objects[0]; Integer lastLevel = (Integer) objects[0];
importVo.setLevel(lastLevel + 1); importVo.setLevel(lastLevel + 1);
...@@ -75,8 +84,6 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm ...@@ -75,8 +84,6 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
} }
// failureNum++;
// failureMsg.append("<br/>").append(failureNum);
resultList.add(importVo); resultList.add(importVo);
} }
...@@ -93,7 +100,7 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm ...@@ -93,7 +100,7 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
@Override @Override
public String getAnalysis() { public String getAnalysis() {
if (failureNum > 0) { if (failureNum > 0) {
failureMsg.insert(0, "失败原因:共 " + failureNum + " 条数据格式不正确,错误如下:"); failureMsg.insert(0, "共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString()); throw new ServiceException(failureMsg.toString());
} else { } else {
successMsg.insert(0, "项目汇总数据已全部解析成功!共 " + getList().size() + " 条"); successMsg.insert(0, "项目汇总数据已全部解析成功!共 " + getList().size() + " 条");
......
...@@ -2,6 +2,9 @@ package com.dsk.cscec.mapper; ...@@ -2,6 +2,9 @@ package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbProjectFile; import com.dsk.cscec.domain.CbProjectFile;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 项目成本文件表(CbProjectFile)表数据库访问层 * 项目成本文件表(CbProjectFile)表数据库访问层
...@@ -11,5 +14,8 @@ import com.dsk.cscec.domain.CbProjectFile; ...@@ -11,5 +14,8 @@ import com.dsk.cscec.domain.CbProjectFile;
*/ */
public interface CbProjectFileMapper extends BaseMapper<CbProjectFile> { public interface CbProjectFileMapper extends BaseMapper<CbProjectFile> {
List<CbProjectFile> selectAnalysisList(@Param("projectId") Long projectId,@Param("cbType") Integer cbType,@Param("cbStage") Integer cbStage);
int removeById(@Param("id") Long id);
} }
...@@ -6,6 +6,8 @@ import com.dsk.cscec.domain.bo.AddProjectFileUploadBo; ...@@ -6,6 +6,8 @@ import com.dsk.cscec.domain.bo.AddProjectFileUploadBo;
import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo; import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo;
import com.dsk.system.domain.vo.SysOssVo; import com.dsk.system.domain.vo.SysOssVo;
import java.util.List;
/** /**
* 项目成本文件表(CbProjectFile)表服务接口 * 项目成本文件表(CbProjectFile)表服务接口
* *
...@@ -44,4 +46,14 @@ public interface CbProjectFileService extends IService<CbProjectFile> { ...@@ -44,4 +46,14 @@ public interface CbProjectFileService extends IService<CbProjectFile> {
* @return 文件列表 * @return 文件列表
*/ */
QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId); QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId);
/**
* 查询项目文件解析列表
* @param projectId 项目ID
* @param cbType 成本类型(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
* @param cbStage 成本阶段(0:标前成本、1:标后成本、2:转固成本)
* @return
*/
List<CbProjectFile> selectAnalysisList(Long projectId, Integer cbType, Integer cbStage);
} }
...@@ -2,7 +2,6 @@ package com.dsk.cscec.service; ...@@ -2,7 +2,6 @@ package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.common.core.domain.R; import com.dsk.common.core.domain.R;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbSummary; import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.domain.bo.CbSummaryActualBo; import com.dsk.cscec.domain.bo.CbSummaryActualBo;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo; import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
...@@ -23,10 +22,10 @@ import java.util.Map; ...@@ -23,10 +22,10 @@ import java.util.Map;
public interface CbSummaryService extends IService<CbSummary> { public interface CbSummaryService extends IService<CbSummary> {
/** /**
* 项目汇总导入 * 成本汇总导入
* @param projectId * @param projectId
*/ */
void importCbProject(Long projectId); void importCbSummary(Long projectId);
/** /**
* 获取一级名称/成本科目列表 * 获取一级名称/成本科目列表
......
...@@ -162,6 +162,11 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C ...@@ -162,6 +162,11 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C
return draftDetailVo; return draftDetailVo;
} }
@Override
public List<CbProjectFile> selectAnalysisList(Long projectId, Integer cbType, Integer cbStage) {
return baseMapper.selectAnalysisList(projectId, cbType, cbStage);
}
/** /**
* 校验项目是否存在 * 校验项目是否存在
* *
......
...@@ -27,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -27,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 项目台账表(CbProjectRecord)表服务实现类 * 项目台账表(CbProjectRecord)表服务实现类
...@@ -85,22 +86,27 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe ...@@ -85,22 +86,27 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
//校验项目是否存在 //校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(projectId); CbProjectRecord projectRecord = this.checkProjectExist(projectId);
List<CbProjectFile> projectFileList = new ArrayList<>();
//校验各个成本类型是否至少有1个文件 //校验各个成本类型是否至少有1个文件
//直接费成本 //直接费成本
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_DIRECT_EXPENSE, CbProjectConstants.CB_TYPE_DIRECT_EXPENSE_NAME); projectFileList.addAll(this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_DIRECT_EXPENSE, CbProjectConstants.CB_TYPE_DIRECT_EXPENSE_NAME));
//工料汇总 //工料汇总
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY_NAME); projectFileList.addAll(this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY_NAME));
//措施项目 //措施项目
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_MEASURE_PROJECT, CbProjectConstants.CB_TYPE_MEASURE_PROJECT_NAME); projectFileList.addAll(this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_MEASURE_PROJECT, CbProjectConstants.CB_TYPE_MEASURE_PROJECT_NAME));
//其他项目 //其他项目
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_OTHER_PROJECT, CbProjectConstants.CB_TYPE_OTHER_PROJECT_NAME); projectFileList.addAll(this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_OTHER_PROJECT, CbProjectConstants.CB_TYPE_OTHER_PROJECT_NAME));
//现场经费 //现场经费
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_SCENE_EXPENSE, CbProjectConstants.CB_TYPE_SCENE_EXPENSE_NAME); projectFileList.addAll(this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_SCENE_EXPENSE, CbProjectConstants.CB_TYPE_SCENE_EXPENSE_NAME));
//成本汇总 //成本汇总
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_SUMMARY, CbProjectConstants.CB_TYPE_SUMMARY_NAME); projectFileList.addAll(this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_SUMMARY, CbProjectConstants.CB_TYPE_SUMMARY_NAME));
//修改项目文件状态:解析中 //修改项目状态:解析中
projectRecord.setProjectFileStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING); projectRecord.setProjectFileStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING);
baseMapper.updateById(projectRecord);
//修改所有该项目的项目文件状态:解析中
CbProjectFileServiceImpl projectFileService = new CbProjectFileServiceImpl();
projectFileService.updateBatchById(projectFileList.stream().peek(projectFile -> projectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING)).collect(Collectors.toList()));
//TODO:调各个成本类型的解析文件方法 //TODO:调各个成本类型的解析文件方法
//直接费成本 //直接费成本
...@@ -123,13 +129,14 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe ...@@ -123,13 +129,14 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
* @param cbType 成本类型字典(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总) * @param cbType 成本类型字典(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
* @param cbTypeName 成本类型名称 * @param cbTypeName 成本类型名称
*/ */
private void checkCbTypeExistFile(Long projectId, Integer cbType, String cbTypeName) { private List<CbProjectFile> checkCbTypeExistFile(Long projectId, Integer cbType, String cbTypeName) {
boolean isExist = projectFileMapper.exists(new LambdaQueryWrapper<CbProjectFile>() List<CbProjectFile> projectFileList = projectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId) .eq(CbProjectFile::getProjectId, projectId)
.eq(CbProjectFile::getCbType, cbType) .eq(CbProjectFile::getCbType, cbType)
//项目文件状态:解析 //项目文件状态:准备
.eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)); .eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING));
Assert.isTrue(isExist, cbTypeName + "至少需要上传1个文件"); Assert.isFalse(projectFileList.isEmpty(), cbTypeName + "至少需要上传1个文件");
return projectFileList;
} }
/** /**
......
<?xml version="1.0" encoding="UTF-8"?> <?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"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dsk.cscec.mapper.CbProjectFileMapper"> <mapper namespace="com.dsk.cscec.mapper.CbProjectFileMapper">
<select id="selectAnalysisList" resultType="com.dsk.cscec.domain.CbProjectFile">
SELECT
id, project_id, cb_stage, cb_type, file_name, file_oss_id, file_oss_url, file_parse_status, fail_remark,
del_flag, create_by, create_time, update_by, update_time
FROM cb_project_file
WHERE ((del_flag = 0 and file_parse_status in (1,3)) or del_flag = 1)
and project_id=#{projectId}
<if test="cbStage != null">
and cb_stage =#{cbStage}
</if>
and cb_type = #{cbType}
</select>
<update id="removeById">
UPDATE cb_project_file SET del_flag=2 WHERE id=#{id}
</update>
</mapper> </mapper>
\ No newline at end of file
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