Commit a8485a2a authored by danfuman's avatar danfuman

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 61ec6262 0a8d6205
......@@ -8,10 +8,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
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.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 异步配置
......@@ -22,16 +26,56 @@ import java.util.concurrent.ScheduledExecutorService;
@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {
@Autowired
@Qualifier("scheduledExecutorService")
private ScheduledExecutorService scheduledExecutorService;
// @Autowired
// @Qualifier("scheduledExecutorService")
// private ScheduledExecutorService scheduledExecutorService;
//
// /**
// * 自定义 @Async 注解使用系统线程池
// */
// @Override
// public Executor getAsyncExecutor() {
// return scheduledExecutorService;
// }
/**
* 自定义 @Async 注解使用系统线程池
*/
@Override
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;
}
/**
......
package com.dsk.component;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dsk.common.excel.ExcelUtils;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbProjectOther;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.service.CbProjectFileService;
import com.dsk.cscec.service.CbProjectOtherService;
import com.dsk.system.service.ISysOssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 其他费用数据解析组件
*
* @Author lcl
* @Data 2024/2/7 17:43
*/
@Slf4j
@Component
public class CbProjectOtherAnalysisComponent {
@Resource
private CbProjectOtherService projectOtherService;
@Resource
private CbProjectFileService projectFileService;
@Resource
private ISysOssService ossService;
@Resource
private TransactionTemplate transactionTemplate;
/**
* 其他费用数据解析
*/
@Async
public void projectOtherDataAnalysis(CbProjectBaseBo bo) throws Exception {
//查询其他费用导入文件
List<CbProjectFile> fileList = projectFileService.list(Wrappers.<CbProjectFile>lambdaQuery()
.eq(CbProjectFile::getProjectId, bo.getProjectId())
.eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_OTHER_PROJECT)
.eq(CbProjectFile::getCbStage, bo.getCbStage())
.in(CbProjectFile::getFileParseStatus, Arrays.asList(1, 3)));
if (ObjectUtils.isEmpty(fileList)) {
return;
}
//文件处理
for (CbProjectFile file : fileList) {
if (file.getDelFlag() == 0) {
//文件下载
InputStream inputStream = ossService.downFileIO(file.getFileOssId());
if (ObjectUtil.isNull(inputStream)) {
file.setFileParseStatus(3);
file.setFailRemark("文件数据不存在");
projectFileService.updateById(file);
break;
}
//解析数据
List<CbProjectOther> importList = new ExcelUtils<>(CbProjectOther.class).importExcelAllSheet(inputStream, 1);
if (importList.isEmpty()) {
file.setFileParseStatus(3);
file.setFailRemark("表格中不存在待导入数据!");
projectFileService.updateById(file);
break;
}
List<CbProjectOther> projectOtherList = importList.stream().parallel()
.peek(item -> {
item.setProjectId(bo.getProjectId());
item.setCbStage(bo.getCbStage());
item.setCbProjectFileId(file.getId());
}).collect(Collectors.toList());
if (projectOtherList.isEmpty()) {
throw new ServiceException("表格中不存在有效数据数据!");
}
transactionTemplate.execute(status -> {
try {
//分批次插入
if (projectOtherList.size() > 1000) {
int index = 0;
int sum = projectOtherList.size();
while (index < sum) {
List<CbProjectOther> divideList = projectOtherList.subList(index, Math.max((index + 1) * 1000, sum));
boolean b = projectOtherService.saveBatch(divideList);
if (!b) {
throw new ServiceException("数据插入失败!");
}
index += 1000;
}
} else {
boolean b = projectOtherService.saveBatch(projectOtherList);
if (!b) {
throw new ServiceException("数据插入失败!");
}
}
file.setFileParseStatus(2);
boolean b = projectFileService.updateById(file);
if (!b) {
throw new ServiceException("文件状态更新失败!");
}
} catch (Exception e) {
status.setRollbackOnly();
file.setFileParseStatus(3);
file.setFailRemark(e.getMessage());
projectFileService.updateById(file);
}
return Boolean.TRUE;
});
} else {
projectOtherService.remove(Wrappers.<CbProjectOther>lambdaQuery().eq(CbProjectOther::getCbProjectFileId, file.getId()));
projectFileService.removeById(file);
}
}
}
}
......@@ -50,11 +50,7 @@ public class DataAnalysisComponent {
@Async
public void quantitySummaryDataAnalysis(CbProjectBaseBo bo) throws Exception {
//查询工料汇总导入文件
List<CbProjectFile> fileList = projectFileService.list(Wrappers.<CbProjectFile>lambdaQuery()
.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)));
List<CbProjectFile> fileList = projectFileService.selectAnalysisList(bo.getProjectId(), CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY, bo.getCbStage());
if (ObjectUtils.isEmpty(fileList)) return;
//文件处理
for (CbProjectFile file : fileList) {
......
package com.dsk.cscec.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dsk.common.annotation.Log;
import com.dsk.common.core.domain.R;
import com.dsk.common.enums.BusinessType;
import com.dsk.component.CbProjectOtherAnalysisComponent;
import com.dsk.cscec.domain.CbProjectExpenseSummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbProjectOtherBo;
import com.dsk.cscec.domain.vo.CbProjectOtherVo;
import com.dsk.cscec.service.CbProjectExpenseSummaryService;
import com.dsk.cscec.service.CbProjectOtherService;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName CbProjectOtherController
* @Description 其他费用相关控制器
* @Author Dgm
* @Date 2024/2/8 10:55
* @Version 1.0.0
*/
@RestController
@RequestMapping("cb/projectOther")
public class CbProjectOtherController {
@Resource
private CbProjectOtherService projectOtherService;
@Resource
private CbProjectExpenseSummaryService cbProjectExpenseSummaryService;
@Resource
private CbProjectOtherAnalysisComponent otherAnalysisComponent;
@GetMapping(value = "/projectOther/dataAnalysis")
public R<List<CbProjectExpenseSummary>> projectOtherDataAnalysis(CbProjectBaseBo baseBo) throws Exception{
otherAnalysisComponent.projectOtherDataAnalysis(baseBo);
return R.ok();
}
/***
* @Description: 其他费用-汇总
* @Param:
* @return: com.dsk.common.core.domain.R<java.util.List<com.dsk.cscec.domain.vo.CbProjectOtherVo>>
* @Author: Dgm
* @date: 2024/2/8 14:08
*/
@SaIgnore
@GetMapping(value = "/statistics/{projectId}")
public R<List<CbProjectExpenseSummary>> statistics(@PathVariable Long projectId) {
CbProjectExpenseSummary expenseSummary = new CbProjectExpenseSummary();
expenseSummary.setProjectId(projectId);
expenseSummary.setDataType(2);
QueryWrapper<CbProjectExpenseSummary> queryWrapper = Wrappers.query(expenseSummary);
queryWrapper.select("id","expense_name as expenseName","expense_value as expenseValue");
queryWrapper.orderByAsc("id");
List<CbProjectExpenseSummary> expenseSummaryList = this.cbProjectExpenseSummaryService.list(queryWrapper);
if (ObjectUtil.isEmpty(expenseSummaryList)) {
expenseSummaryList = new ArrayList<>();
}
return R.ok(expenseSummaryList);
}
/***
* @Description: 其他费用一级大类
* @Param:
* @return: com.dsk.common.core.domain.R<java.util.List<com.dsk.cscec.domain.vo.CbProjectOtherVo>>
* @Author: Dgm
* @date: 2024/2/8 14:08
*/
@SaIgnore
@GetMapping(value = "/type/{projectId}")
public R<List<Map<String, Object>>> dictType(@PathVariable Long projectId) {
List<Map<String, Object>> data = projectOtherService.listByLevel(projectId,0);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}
return R.ok(data);
}
/***
* @Description: 其他费用列表
* @Param:
* @return: com.dsk.common.core.domain.R<java.util.List<com.dsk.cscec.domain.vo.CbProjectOtherVo>>
* @Author: Dgm
* @date: 2024/2/8 14:08
*/
@SaIgnore
@GetMapping("/list")
public R<List<CbProjectOtherVo>> list(CbProjectOtherBo projectOtherBo) {
List<CbProjectOtherVo> data= projectOtherService.selectDataList(projectOtherBo);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}
return R.ok(data);
}
/***
* @Description: 其他费用-导入数据
* @param file 导入文件
* @param projectId 项目id
* @return: com.dsk.common.core.domain.R<java.util.List<com.dsk.cscec.domain.vo.CbProjectOtherVo>>
* @Author: Dgm
* @date: 2024/2/8 14:08
*/
@Log(title = "其他费用相关项导入", businessType = BusinessType.IMPORT)
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, Long projectId) throws Exception {
projectOtherService.importExcelData(file,projectId);
return R.ok();
}
}
......@@ -67,7 +67,7 @@ public class CbProjectRecordController extends BaseController {
* 获取项目台账列表
*/
@GetMapping("/getProjectList")
public TableDataInfo<CbProjectRecordSearchVo> getProjectList(@RequestBody CbProjectSearchBo searchBo, PageQuery pageQuery) {
public TableDataInfo<CbProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery) {
return baseService.getProjectList(searchBo, pageQuery);
}
......
......@@ -134,7 +134,7 @@ public class CbSummaryController extends BaseController {
*/
@PostMapping("/analysisData")
public void analysisData(Long projectId){
cbSummaryService.importCbProject(projectId);
cbSummaryService.importCbSummary(projectId);
}
}
package com.dsk.cscec.domain;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName CbProjectOtherVo
* @Description 项目其他项目费用
* @Author Dgm
* @Date 2024/2/8 10:39
* @Version 1.0.0
*/
@Data
public class CbProjectOther implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long id;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目ID
*/
private Long projectId;
/**
* 父项id
*/
private Long parentId;
/**
* 序号
*/
private String number;
/**
* 处理后序号
*/
private String dealWithNumber;
/**
* 清单内容
*/
private String itemContent;
/**
* 工作内容、做法/规格型号/施工现场配置说明
*/
private String workContent;
/**
* 单位
*/
private String unit;
/**
* 工程量
*/
private BigDecimal engineeringQuantity;
/**
* 不含税单价
*/
private String unitPriceExcludingTax;
/**
* 不含税合价
*/
private String totalPriceExcludeTax;
/**
* 税率(%)
*/
private String taxRate;
/**
* 含税合价
*/
private String totalPriceIncludingTax;
/**
* 税金(元)
*/
private String taxAmount;
/**
* 成本科目
*/
private String costSubject;
/**
* 税金类型
*/
private String taxType;
/**
* 数据类型(1:履约担保、保函手续费、市场营销奖励费、2:创优费:3:其他:4:保险保函:5:水电费:6:现场其他直接费:7:技术质量管理:8:工程保险类:10:报批报建、竣工验收类
*/
private String dataType;
/**
* 备注
*/
private String remarks;
/**
* 修改人
*/
private String updateBy;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 项目成本文件id
*/
private Long cbProjectFileId;
}
......@@ -44,9 +44,9 @@ public class CbProjectRecord extends BaseEntity implements Serializable {
*/
private String ipmProjectNo;
/**
* 是否获取项目详情(0:是、1:否)
* 是否获取项目详情
*/
private Integer isGetProjectDetail;
private Boolean isGetProjectDetail;
/**
* 文件名称
*/
......
......@@ -48,10 +48,7 @@ public class CbQuantitySummaryActual implements Serializable {
* 采购单价
*/
private Double purchaseUnitPrice;
/**
* 创建时间
*/
private Date createTime;
/**
* 推送时间
*/
......@@ -76,6 +73,18 @@ public class CbQuantitySummaryActual implements Serializable {
* IPM作业编码
*/
private String ipmBizCode;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
}
......@@ -20,10 +20,10 @@ public class AddCbProjectBo {
*/
private String ipmProjectNo;
/**
* 是否获取项目详情(0:否、1:是)
* 是否获取项目详情
*/
@NotNull(message = "是否获取项目详情不能为空")
private Integer isGetProjectDetail;
private Boolean isGetProjectDetail;
/**
* 文件名称
*/
......
package com.dsk.cscec.domain.bo;
import lombok.Data;
@Data
public class CbProjectOtherBo {
/**
* 费用项Id
*/
private Long parentId;
/**
* 年月
*/
private String month;
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
}
\ No newline at end of file
......@@ -25,10 +25,10 @@ public class EditProjectInfoBo {
*/
private String ipmProjectNo;
/**
* 是否获取项目详情(0:否、1:是)
* 是否获取项目详情
*/
@NotNull(message = "是否获取项目详情不能为空")
private Integer isGetProjectDetail;
private Boolean isGetProjectDetail;
/**
* 文件名称
*/
......
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* @ClassName CbProjectOtherVo
* @Description 项目其他项目费用
* @Author Dgm
* @Date 2024/2/8 10:39
* @Version 1.0.0
*/
@Data
public class CbProjectOtherImportVo {
/**
* 序号
*/
@ExcelProperty(value = "序号")
private String number;
/**
* 清单内容
*/
@ExcelProperty(value = "清单内容")
private String itemContent;
/**
* 工作内容、做法/规格型号/施工现场配置说明
*/
@ExcelProperty(value = "工作内容")
private String workContent;
/**
* 单位
*/
@ExcelProperty(value = "单位")
private String unit;
/**
* 工程量
*/
@ExcelProperty(value = "工程量")
private BigDecimal engineeringQuantity;
/**
* 不含税单价
*/
@ExcelProperty(value = "不含税单价")
private String unitPriceExcludingTax;
/**
* 不含税合价
*/
@ExcelProperty(value = "不含税合价")
private String totalPriceExcludeTax;
/**
* 税率(%)
*/
@ExcelProperty(value = "税率(%)")
private String taxRate;
/**
* 含税合价
*/
@ExcelProperty(value = "含税合价")
private String totalPriceIncludingTax;
/**
* 税金(元)
*/
@ExcelProperty(value = "税金(元)")
private String taxAmount;
/**
* 成本科目
*/
@ExcelProperty(value = "成本科目")
private String costSubject;
/**
* 税金类型
*/
@ExcelProperty(value = "税金类型")
private String taxType;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remarks;
/**
* 数据类型(1:履约担保、保函手续费、市场营销奖励费、2:创优费:3:其他:4:保险保函:5:水电费:6:现场其他直接费:7:技术质量管理:8:工程保险类:10:报批报建、竣工验收类
*/
private String dataType;
/**
* 主键id
*/
private Long id;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目ID
*/
private Long projectId;
/**
* 父项id
*/
private Long parentId;
/**
* 处理后序号
*/
private String dealWithNumber;
}
package com.dsk.cscec.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @ClassName CbProjectOtherVo
* @Description 项目其他项目费用
* @Author Dgm
* @Date 2024/2/8 10:39
* @Version 1.0.0
*/
@Data
public class CbProjectOtherVo {
/**
* 主键id
*/
private Long id;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目ID
*/
private Long projectId;
/**
* 父项id
*/
private Long parentId;
/**
* 序号
*/
private String number;
/**
* 处理后序号
*/
private String dealWithNumber;
/**
* 清单内容
*/
private String itemContent;
/**
* 工作内容、做法/规格型号/施工现场配置说明
*/
private String workContent;
/**
* 单位
*/
private String unit;
/**
* 工程量
*/
private BigDecimal engineeringQuantity;
/**
* 不含税单价
*/
private String unitPriceExcludingTax;
/**
* 不含税合价
*/
private String totalPriceExcludeTax;
/**
* 税率(%)
*/
private String taxRate;
/**
* 含税合价
*/
private String totalPriceIncludingTax;
/**
* 税金(元)
*/
private String taxAmount;
/**
* 成本科目
*/
private String costSubject;
/**
* 税金类型
*/
private String taxType;
/**
* 数据类型(1:履约担保、保函手续费、市场营销奖励费、2:创优费:3:其他:4:保险保函:5:水电费:6:现场其他直接费:7:技术质量管理:8:工程保险类:10:报批报建、竣工验收类
*/
private String dataType;
/**
* 备注
*/
private String remarks;
/**
* 修改人
*/
private String updateBy;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
......@@ -88,4 +88,9 @@ public class CbSummaryActualListVo extends BaseEntity {
private String expenseDate;
private List<CbSummaryActualListVo> children;
/**
* 是否有子级(0否1是)
*/
private Integer hasChildren;
}
package com.dsk.cscec.listener;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.dsk.common.excel.ExcelListener;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.vo.CbProjectExpenseSummaryImportVo;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* 其他项目自定义导入
*
* @author Lion Li
*/
@Slf4j
public class CbProjectExpenseSummaryImportListener extends AnalysisEventListener<CbProjectExpenseSummaryImportVo> implements ExcelListener<CbProjectExpenseSummaryImportVo> {
private final Long projectId;
private final Integer cbStage;
private List<CbProjectExpenseSummaryImportVo> dataList = new ArrayList<>();
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public CbProjectExpenseSummaryImportListener(Long projectId, Integer cbStage) {
this.cbStage = cbStage;
this.projectId = projectId;
}
@Override
public void invoke(CbProjectExpenseSummaryImportVo importVo, AnalysisContext context) {
Integer rowIndex = context.readRowHolder().getRowIndex();
if (StrUtil.isEmpty(importVo.getExpenseName())) {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:清单内容不能为空");
}
String number = importVo.getNumber();
if (StrUtil.isEmpty(number)) {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:序号不能为空");
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<CbProjectExpenseSummaryImportVo> getExcelResult() {
return new ExcelResult<CbProjectExpenseSummaryImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<CbProjectExpenseSummaryImportVo> getList() {
return dataList;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
package com.dsk.cscec.listener;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.dsk.common.excel.ExcelListener;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.vo.CbProjectOtherImportVo;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* 其他项目自定义导入
*
* @author Lion Li
*/
@Slf4j
public class CbProjectOtherImportListener extends AnalysisEventListener<CbProjectOtherImportVo> implements ExcelListener<CbProjectOtherImportVo> {
private final Long projectId;
private final Integer cbStage;
private List<CbProjectOtherImportVo> dataList = new ArrayList<>();
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public CbProjectOtherImportListener(Long projectId, Integer cbStage) {
this.cbStage = cbStage;
this.projectId = projectId;
}
@Override
public void invoke(CbProjectOtherImportVo importVo, AnalysisContext context) {
Integer rowIndex = context.readRowHolder().getRowIndex();
if (StrUtil.isEmpty(importVo.getItemContent())) {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:清单内容不能为空");
}
String number = importVo.getNumber();
if (StrUtil.isEmpty(number)) {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:序号不能为空");
}
Boolean numberMatch = false;
String regex = "[\\((]*[一|二|三|四|五|六|七|八|九|十]+[\\))]*";
Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)*$");
Pattern pattern3 = Pattern.compile("^([1-9][0-9]*|0)$");
if (ReUtil.isMatch(regex, number) || ReUtil.isMatch(pattern, number)||ReUtil.isMatch(pattern3, number)) {
numberMatch = true;
} else {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:序号格式错误");
}
if(numberMatch){
if (ReUtil.isMatch(regex, number)){
String replace = number.replaceAll("[\\\\((]|[\\\\))]", "");
int no = Convert.chineseToNumber(replace);
importVo.setDealWithNumber(String.valueOf(no));
}else{
importVo.setDealWithNumber(importVo.getNumber());
}
dataList.add(importVo);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<CbProjectOtherImportVo> getExcelResult() {
return new ExcelResult<CbProjectOtherImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<CbProjectOtherImportVo> getList() {
return dataList;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
......@@ -53,6 +53,12 @@ public class CbSummaryCostAccountImportListener extends AnalysisEventListener<Cb
failureMsg.append("<br/>").append("第" + sort + "条数据序号为空");
return;
}
//成本科目不能为空
if (StringUtil.isBlank(importVo.getCbName())) {
failureNum++;
failureMsg.append("<br/>").append("第" + sort + "条数据成本科目为空");
return;
}
//父级数据处理
if (sort == 1) {
......@@ -74,7 +80,7 @@ public class CbSummaryCostAccountImportListener extends AnalysisEventListener<Cb
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "失败原因:共 " + failureNum + " 条数据格式不正确,错误如下:");
failureMsg.insert(0, "共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "成本科目汇总数据已全部解析成功!共 " + getList().size() + " 条");
......
package com.dsk.cscec.listener;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.dsk.common.excel.ExcelListener;
......@@ -42,8 +43,12 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
@Override
public void invoke(CbSummaryProjectImportVo importVo, AnalysisContext context) {
//第一个序号不能为空? todo
//名称不能为空
if (StringUtil.isBlank(importVo.getCbName())) {
failureNum++;
failureMsg.append("<br/>").append("第" + sort + "条数据名称为空");
return;
}
//添加父级数据
if (sort == 0) {
CbSummaryProjectImportVo firstVo = new CbSummaryProjectImportVo();
......@@ -63,8 +68,12 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
//按sort倒序取number不为空的最大level
Object[] objects = resultList.stream().sorted(Comparator.comparingInt(CbSummaryProjectImportVo::getSort).reversed())
.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];
importVo.setLevel(lastLevel + 1);
......@@ -75,8 +84,6 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
}
// failureNum++;
// failureMsg.append("<br/>").append(failureNum);
resultList.add(importVo);
}
......@@ -93,7 +100,7 @@ public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSumm
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "失败原因:共 " + failureNum + " 条数据格式不正确,错误如下:");
failureMsg.insert(0, "共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "项目汇总数据已全部解析成功!共 " + getList().size() + " 条");
......
......@@ -2,6 +2,9 @@ package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbProjectFile;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 项目成本文件表(CbProjectFile)表数据库访问层
......@@ -11,5 +14,8 @@ import com.dsk.cscec.domain.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);
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbProjectOther;
import com.dsk.cscec.domain.bo.CbProjectOtherBo;
import com.dsk.cscec.domain.vo.CbProjectOtherVo;
import java.util.List;
public interface CbProjectOtherMapper extends BaseMapper<CbProjectOther> {
List<CbProjectOtherVo> selectListByProjectAndStage(CbProjectOtherBo projectOtherBo);
}
\ No newline at end of file
......@@ -6,6 +6,8 @@ import com.dsk.cscec.domain.bo.AddProjectFileUploadBo;
import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo;
import com.dsk.system.domain.vo.SysOssVo;
import java.util.List;
/**
* 项目成本文件表(CbProjectFile)表服务接口
*
......@@ -44,4 +46,14 @@ public interface CbProjectFileService extends IService<CbProjectFile> {
* @return 文件列表
*/
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);
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbProjectOther;
import com.dsk.cscec.domain.bo.CbProjectOtherBo;
import com.dsk.cscec.domain.vo.CbProjectOtherVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
/**
* 成本-工料汇总基本表(CbQuantitySummary)表服务接口
*
* @author lcl
* @since 2024-02-05 11:06:56
*/
public interface CbProjectOtherService extends IService<CbProjectOther> {
void importExcelData(MultipartFile file, Long projectId);
List<Map<String, Object>> listByLevel(Long projectId, int i);
List<CbProjectOtherVo> selectDataList(CbProjectOtherBo projectOtherBo);
}
......@@ -2,7 +2,6 @@ package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.common.core.domain.R;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.domain.bo.CbSummaryActualBo;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
......@@ -23,10 +22,10 @@ import java.util.Map;
public interface CbSummaryService extends IService<CbSummary> {
/**
* 项目汇总导入
* 成本汇总导入
* @param projectId
*/
void importCbProject(Long projectId);
void importCbSummary(Long projectId);
/**
* 获取一级名称/成本科目列表
......
......@@ -162,6 +162,11 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C
return draftDetailVo;
}
@Override
public List<CbProjectFile> selectAnalysisList(Long projectId, Integer cbType, Integer cbStage) {
return baseMapper.selectAnalysisList(projectId, cbType, cbStage);
}
/**
* 校验项目是否存在
*
......
......@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.StringUtils;
import com.dsk.component.DataAnalysisComponent;
import com.dsk.cscec.constant.CbProjectConstants;
......@@ -20,13 +21,17 @@ import com.dsk.cscec.domain.bo.*;
import com.dsk.cscec.domain.vo.CbProjectRecordSearchVo;
import com.dsk.cscec.mapper.CbProjectFileMapper;
import com.dsk.cscec.mapper.CbProjectRecordMapper;
import com.dsk.cscec.service.CbProjectExpenseSummaryService;
import com.dsk.cscec.service.CbProjectRecordService;
import com.dsk.cscec.service.CbSummaryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 项目台账表(CbProjectRecord)表服务实现类
......@@ -42,6 +47,10 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
private CbProjectFileMapper projectFileMapper;
@Resource
private DataAnalysisComponent dataAnalysisComponent;
@Resource
private CbSummaryService cbSummaryService;
@Resource
private CbProjectExpenseSummaryService projectExpenseSummaryService;
/**
* 新增项目
......@@ -85,35 +94,44 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(projectId);
List<CbProjectFile> projectFileList = new ArrayList<>();
//校验各个成本类型是否至少有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);
baseMapper.updateById(projectRecord);
//修改所有该项目的项目文件状态:解析中
CbProjectFileServiceImpl projectFileService = new CbProjectFileServiceImpl();
projectFileService.updateBatchById(projectFileList.stream().peek(projectFile -> projectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING)).collect(Collectors.toList()));
//TODO:调各个成本类型的解析文件方法
Integer cbStage = projectRecord.getCbStage();
String username = Objects.requireNonNull(LoginHelper.getLoginUser()).getUsername();
//直接费成本
//工料汇总
CbProjectBaseBo projectBaseBo = new CbProjectBaseBo();
projectBaseBo.setProjectId(projectId);
projectBaseBo.setCbStage(projectRecord.getCbStage());
projectBaseBo.setCbStage(cbStage);
dataAnalysisComponent.quantitySummaryDataAnalysis(projectBaseBo);
//措施项目
//其他项目
//现场经费
projectExpenseSummaryService.parseSceneExpenseData(projectId,cbStage,username);
//成本汇总
cbSummaryService.importCbSummary(projectId);
}
/**
......@@ -123,13 +141,14 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
* @param cbType 成本类型字典(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
* @param cbTypeName 成本类型名称
*/
private void checkCbTypeExistFile(Long projectId, Integer cbType, String cbTypeName) {
boolean isExist = projectFileMapper.exists(new LambdaQueryWrapper<CbProjectFile>()
private List<CbProjectFile> checkCbTypeExistFile(Long projectId, Integer cbType, String cbTypeName) {
List<CbProjectFile> projectFileList = projectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId)
.eq(CbProjectFile::getCbType, cbType)
//项目文件状态:解析
//项目文件状态:准备
.eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING));
Assert.isTrue(isExist, cbTypeName + "至少需要上传1个文件");
Assert.isFalse(projectFileList.isEmpty(), cbTypeName + "至少需要上传1个文件");
return projectFileList;
}
/**
......
......@@ -5,6 +5,7 @@ import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.helper.LoginHelper;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.CbQuantitySummaryActual;
import com.dsk.cscec.domain.CbSubject;
......@@ -62,7 +63,7 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM
Map<String, Object> oneMap = new HashMap<>();
List<Map<String, Object>> oneList = new ArrayList<>();
oneMap.put("name", entry.getKey());
oneMap.put("sort", cbSubjectMapper.selectOne(Wrappers.<CbSubject>lambdaQuery().eq(CbSubject::getCbSubjectName,entry.getKey())).getSort());
oneMap.put("sort", cbSubjectMapper.selectOne(Wrappers.<CbSubject>lambdaQuery().eq(CbSubject::getCbSubjectName, entry.getKey())).getSort());
for (Map.Entry<String, Map<String, List<Map<String, Object>>>> twoEntry : entry.getValue().entrySet()) {
Map<String, Object> twoMap = new HashMap<>();
List<Map<String, Object>> twoList = new ArrayList<>();
......@@ -106,11 +107,13 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM
@Transactional(rollbackFor = Exception.class)
public void updateActual(List<CbQuantitySummaryActual> list) {
if (ObjectUtils.isEmpty(list)) throw new BeanException("数据不能为空");
String nickName = LoginHelper.getLoginUser().getNickname();
for (CbQuantitySummaryActual actual : list) {
if (ObjectUtils.isEmpty(actual.getCbQuantitySummaryId())) throw new BeanException("基础数据id不能为空!");
if (ObjectUtils.isEmpty(actual.getQuantities())) throw new BeanException("工程量(本月用料)不能为空!");
if (ObjectUtils.isEmpty(actual.getRecordDate())) throw new BeanException("填写月份不能为空!");
actual.setId(ObjectUtils.isEmpty(actual.getId()) ? SecureUtil.md5(actual.getCbQuantitySummaryId() + actual.getRecordDate()) : actual.getId());
actual.setUpdateBy(nickName);
boolean b = baseActualService.saveOrUpdate(actual);
if (!b) {
log.error("CbQuantitySummaryServiceImpl.updateActual() data insert error! data:" + JSONUtil.toJsonStr(actual));
......
<?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.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>
\ No newline at end of file
<?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.dsk.cscec.mapper.CbProjectOtherMapper">
<select id="selectListByProjectAndStage" resultType="com.dsk.cscec.domain.vo.CbProjectOtherVo">
SELECT t.* FROM cb_project_other t WHERE t.project_id=#{projectId} AND t.cb_stage=#{cbStage} AND t.parent_id=#{parentId} ORDER BY id ASC
</select>
</mapper>
\ No newline at end of file
import request from '@/utils/request'
import request from '@/utils/request';
/**
* 获取项目详情
* @param {*} params
* @returns
*/
export const getProjectDetailApi = (params = {}) => request({
url: "",
method: "get",
params
});
//校验项目编码是否存在
export function checkProjectCodeExist (data) {
export function checkProjectCodeExist(data) {
return request({
url: '/cbProjectRecord/checkProjectCodeExist/'+data,
url: '/cbProjectRecord/checkProjectCodeExist/' + data,
method: 'get',
})
});
}
//新增项目
export function addProject (data) {
export function addProject(data) {
return request({
url: '/cbProjectRecord/addProject',
method: 'post',
data:data,
})
data: data,
});
}
//修改项目
export function editProjectInfo (data) {
export function editProjectInfo(data) {
return request({
url: '/cbProjectRecord/editProjectInfo',
method: 'PUT',
data:data,
})
data: data,
});
}
//删除项目
export function batchDeleteProject(ids) {
return request({
url: '/cbProjectRecord/batchDeleteProject/'+ids,
method: 'Delete',
});
}
//新增新阶段项目
export function addNewStageProject (data) {
export function addNewStageProject(data) {
return request({
url: '/cbProjectRecord/addNewStageProject',
method: 'POST',
data:data,
})
data: data,
});
}
//获取当前项目文件上传
export function getProjectFileUploadDetail (projectId) {
export function getProjectFileUploadDetail(projectId) {
return request({
url: '/cbProjectFile/getProjectFileUploadDetail/'+projectId,
url: '/cbProjectFile/getProjectFileUploadDetail/' + projectId,
method: 'get',
})
});
}
//获取草稿箱列表
export function getDraftDialogList (projectId) {
export function getDraftDialogList(projectId) {
return request({
url: '/cbProjectRecord/getDraftDialogList',
method: 'get',
})
});
}
//上传文件
export function uploadCbProjectFile (data) {
export function uploadCbProjectFile(data) {
return request({
url: '/cbProjectFile/uploadCbProjectFile',
method: 'post',
data
})
});
}
//删除文件
export function deleteCbProjectFile (fileId) {
export function deleteCbProjectFile(fileId) {
return request({
url: '/cbProjectFile/deleteCbProjectFile/'+fileId,
url: '/cbProjectFile/deleteCbProjectFile/' + fileId,
method: 'Delete',
})
});
}
//删除草稿
export function deleteDraft (projectId) {
export function deleteDraft(projectId) {
return request({
url: '/cbProjectRecord/deleteDraft/'+projectId,
url: '/cbProjectRecord/deleteDraft/' + projectId,
method: 'Delete',
})
});
}
//查询当前项目可删除成本阶段
export function getProjectCbStageNotDraft (relatedId) {
export function getProjectCbStageNotDraft(relatedId) {
return request({
url: '/cbProjectRecord/getProjectCbStageNotDraft/'+relatedId,
url: '/cbProjectRecord/getProjectCbStageNotDraft/' + relatedId,
method: 'get',
})
});
}
//查询当前项目可删除成本阶段
export function getProjectList(data) {
return request({
url: '/cbProjectRecord/getProjectList',
method: 'get',
params:data
});
}
//盈亏分析对比 左侧菜单
export const getProfitLossMenuTreeApi = (params = {}) => request({
url: "/cbSummary/cbNameList",
method: "get",
params
})
// 工料汇总
/**
* 获取供料汇总左侧菜单
* @param {*} params
* @returns
*/
export const getFeedSummaryMenuTreeApi = (params = {}) => request({
url: "/cb/quantity/summary/subjectTree",
method: "get",
params
})
......@@ -2,7 +2,7 @@
<div class="feed-summary-container">
<div class="feed-summary-inner">
<div class="left-side-menu">
<project-side-menu :menuTree="menuTreeList" :unique-opened="false" :default-active="defaultActive">
<project-side-menu :menuTree="menuTreeList" :menuOptions="menuOptions" :unique-opened="false" :default-active="defaultActive">
<template slot="房建类成本科目-1">
<img src="@/assets/images/projectCostLedger/icon_cost_detail_2.svg" alt="">
<div class="project-sub-menu-title-text">房建类成本科目</div>
......@@ -18,74 +18,110 @@
</template>
<script>
import ProjectSideMenu from "@/views/projectCostLedger/detail/components/ProjectSideMenu";
import { getFeedSummaryMenuTreeApi } from "@/api/projectCostLedger";
export default {
name: "feedSummary",
components: {
ProjectSideMenu
props: {
// 项目ID
projectId: {
type: String,
required: true,
default: ""
},
data() {
return {
defaultActive: "",
menuTreeList: [
{
nodeName: "房建类成本科目",
id: "1",
children: [
{
nodeName: "劳务分包工程",
id: "1-1",
children: [
{
nodeName: "主体工程-结构劳务",
id: "1-1-1",
children: [
{
nodeName: "结构劳务分包",
id: "1-1-1-1",
// 详情信息
projectDetailInfo: {
type: Object,
default: () => ({})
}
]
},
{
nodeName: "二次结构及粗装修劳务",
id: "1-2-1",
children: [
{
nodeName: "二次机构及粗装修劳务",
id: "1-2-1",
}
]
watch: {
projectDetailInfo: {
handler(newValue) {
this.comProjectDetailInfo = newValue ? newValue : {};
this.init(this.comProjectDetailInfo);
},
{
nodeName: "拆除、修缮、清理、改造劳...",
id: "1-3-1",
children: [
{
nodeName: "拆除、修缮、清理、改造劳...",
id: "1-3-1",
}
]
}
]
deep: true,
immediate: true
},
{
nodeName: "专业分包工程",
id: "2-1",
projectId: {
handler(newValue) {
this.comProjectId = newValue;
},
{
nodeName: "实体工程材料(土建)",
id: "3-1",
immediate: true
}
},
{
nodeName: "其他直接费成本",
id: "4-1",
components: {
ProjectSideMenu
},
]
data() {
return {
menuOptions: {
nodeName: "name",
nodeValue: "name",
},
{
nodeName: "未归类项目",
id: "2",
children: []
}
comProjectDetailInfo: {},
comProjectId: "",
defaultActive: "",
menuTreeList: [
// {
// nodeName: "房建类成本科目",
// id: "1",
// children: [
// {
// nodeName: "劳务分包工程",
// id: "1-1",
// children: [
// {
// nodeName: "主体工程-结构劳务",
// id: "1-1-1",
// children: [
// {
// nodeName: "结构劳务分包",
// id: "1-1-1-1",
// }
// ]
// },
// {
// nodeName: "二次结构及粗装修劳务",
// id: "1-2-1",
// children: [
// {
// nodeName: "二次机构及粗装修劳务",
// id: "1-2-1",
// }
// ]
// },
// {
// nodeName: "拆除、修缮、清理、改造劳...",
// id: "1-3-1",
// children: [
// {
// nodeName: "拆除、修缮、清理、改造劳...",
// id: "1-3-1",
// }
// ]
// }
// ]
// },
// {
// nodeName: "专业分包工程",
// id: "2-1",
// },
// {
// nodeName: "实体工程材料(土建)",
// id: "3-1",
// },
// {
// nodeName: "其他直接费成本",
// id: "4-1",
// },
// ]
// },
// {
// nodeName: "未归类项目",
// id: "2",
// children: []
// }
]
};
},
......@@ -99,7 +135,29 @@ export default {
},
//方法集
methods: {
async init(detail = {}) {
try {
const { projectId, cbStage } = detail;
if (!projectId) return;
await this.getFeedSummaryMenuTree({
projectId,
cbStage
});
} catch (error) {
}
},
async getFeedSummaryMenuTree(params) {
try {
const result = await getFeedSummaryMenuTreeApi(params);
if (result.code == 200) {
const _tempArray = result.data;
this.menuTreeList = _tempArray;
}
} catch (error) {
}
}
},
}
</script>
......
<template>
<div class="otherProjects-container">
<div class="otherProjects-cont">
<div class="left">
<div class="left-menu">
</div>
</div>
<!--<div class="right-table">-->
<!--<div class="table-item">-->
<!--<tables-->
<!--v-if="!isSkeleton"-->
<!--:tableLoading="tableLoading"-->
<!--:tableData="tableData"-->
<!--:forData="forData1"-->
<!--:MaxPage=500-->
<!--:tableDataTotal="tableDataTotal"-->
<!--:queryParams="queryParams"-->
<!--@handle-current-change="handleCurrentChange"-->
<!--@sort-change="sortChange"-->
<!--&gt;-->
<!--<template slot="number" slot-scope="scope">-->
<!--<div>{{scope.row.number || '&#45;&#45;'}}</div>-->
<!--</template>-->
<!--<template slot="proportion" slot-scope="scope">-->
<!--<div>{{scope.row.proportion || '&#45;&#45;'}}{{scope.row.proportion ? '%':''}}</div>-->
<!--</template>-->
<!--</tables>-->
<!--</div>-->
<!--</div>-->
</div>
</div>
</template>
<script>
import Tables from "../../../../component/Tables"
import {getProfitLossMenuTreeApi} from '@/api/projectCostLedger/index'
export default {
name: "ProfitLoss",
props:{
// 项目ID
projectId: {
type: String,
required: true,
default: ""
},
// // 详情信息
// projectDetailInfo: {
// type: Object,
// default: () => ({})
// }
},
watch: {
// projectDetailInfo: {
// handler(newValue) {
// this.comProjectDetailInfo = newValue ? newValue : {};
// this.init(this.comProjectDetailInfo);
// },
// deep: true,
// immediate: true
// },
// projectId: {
// handler(newValue) {
// this.comProjectId = newValue;
// },
// immediate: true
// }
},
components: {
Tables,
},
data() {
return {
menuOptions: {
nodeName: "name",
nodeValue: "name",
},
comProjectDetailInfo: {},
comProjectId: "",
defaultActive: "",
menuTreeList: [
// {
// nodeName: "房建类成本科目",
// id: "1",
// children: [
// {
// nodeName: "劳务分包工程",
// id: "1-1",
// children: [
// {
// nodeName: "主体工程-结构劳务",
// id: "1-1-1",
// children: [
// {
// nodeName: "结构劳务分包",
// id: "1-1-1-1",
// }
// ]
// },
// {
// nodeName: "二次结构及粗装修劳务",
// id: "1-2-1",
// children: [
// {
// nodeName: "二次机构及粗装修劳务",
// id: "1-2-1",
// }
// ]
// },
// {
// nodeName: "拆除、修缮、清理、改造劳...",
// id: "1-3-1",
// children: [
// {
// nodeName: "拆除、修缮、清理、改造劳...",
// id: "1-3-1",
// }
// ]
// }
// ]
// },
// {
// nodeName: "专业分包工程",
// id: "2-1",
// },
// {
// nodeName: "实体工程材料(土建)",
// id: "3-1",
// },
// {
// nodeName: "其他直接费成本",
// id: "4-1",
// },
// ]
// },
// {
// nodeName: "未归类项目",
// id: "2",
// children: []
// }
]
}
},
//可访问data属性
created() {
console.log(this.projectId)
this.init()
},
//计算集
computed: {
},
async init(detail = {}) {
let cbStage = 1
try {
const { projectId, cbStage } = detail;
if (!projectId) return;
await this.getProfitLossMenuTree({
projectId,
cbStage
});
} catch (error) {
}
},
async getProfitLossMenuTree(params) {
try {
const result = await getProfitLossMenuTreeApi(params);
if (result.code == 200) {
const _tempArray = result.data;
this.menuTreeList = _tempArray;
}
} catch (error) {
}
},
}
</script>
<style lang="scss" scoped>
.otherProjects-container {
width: 100%;
box-sizing: border-box;
background: #ffffff;
height: 100%;
align-items: center;
.otherProjects-cont{
display: flex;
width: 100%;
height: 100%;
}
.left{
width: 220px;
height: 100%;
.left-menu{
width: 100%;
height: 100%;
border-right: 1px solid #eeeeee;
overflow: auto;
}
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
}
.right-table{
width: calc(100% - 220px);
padding: 16px;
}
}
</style>
......@@ -85,11 +85,11 @@ export default {
//方法集
methods: {
// 事件订阅
subMenuOpen(menuPath) {
this.$emit("open", menuPath);
subMenuOpen(menuPath, menuPathArray) {
this.$emit("open", menuPath, menuPathArray);
},
subMenuClose(menuPath) {
this.$emit("close", menuPath);
subMenuClose(menuPath, menuPathArray) {
this.$emit("close", menuPath, menuPathArray);
},
menuSelect(menuPath) {
const result = this.getCurrentData(menuPath);
......@@ -120,11 +120,12 @@ export default {
// 合并默认配置
const _options = this.mergeMenuOptions(JSON.parse(JSON.stringify(this.menuOptions)));
this.tempMenuOptions = _options;
console.log(this.tempMenuOptions);
// 映射配置
const resultData = this.mapDataByMenuOptions(JSON.parse(JSON.stringify(this.comMenuTree)), _options);
if (resultData) {
this.tempMenuTree = resultData;
}
// const resultData = this.mapDataByMenuOptions(JSON.parse(JSON.stringify(this.comMenuTree)), _options);
// if (resultData) {
// this.tempMenuTree = resultData;
// }
}
},
mergeMenuOptions(options) {
......
......@@ -15,11 +15,14 @@
<direct-cost v-if="current == 'directCost'"></direct-cost>
<!-- 工料汇总 -->
<feed-summary v-if="current == 'feedSummary'"></feed-summary>
<feed-summary v-if="current == 'feedSummary'" :project-id="projectID" :project-detail-info="detailInfo"></feed-summary>
<!-- 其他项目 -->
<other-projects v-if="current == 'otherItems'"></other-projects>
<!-- 盈亏分析对比 -->
<profit-Loss v-if="current == 'profitAndLoss'" :project-id="projectID"></profit-Loss>
</div>
</div>
</div>
......@@ -35,8 +38,11 @@ import DirectCost from "@/views/projectCostLedger/detail/components/DirectCost";
import FeedSummary from "@/views/projectCostLedger/detail/components/FeedSummary";
// 其他项目
import OtherProjects from "@/views/projectCostLedger/detail/components/OtherProjects";
// 盈亏分析对比
import ProfitLoss from "@/views/projectCostLedger/detail/components/ProfitLoss";
import { v4 } from "uuid";
import { cloneDeep } from "lodash-es";
import { getProjectDetailApi } from "@/api/projectCostLedger";
export default {
name: "projectCostLedgerDetail",
components: {
......@@ -45,14 +51,18 @@ export default {
FeedSummary,
EngineeringInformation,
DirectCost,
OtherProjects
OtherProjects,
ProfitLoss
},
data() {
return {
projectID: "",
current: "",
// 详情信息变量
detailInfo: {},
detailInfo: {
projectId: "1754425038355890177",
cbStage: 0
},
toggleTabs: [
{
value: "basicEngineeringInformation",
......
......@@ -275,6 +275,7 @@
this.formdata = JSON.parse(JSON.stringify(this.uploadData))
this.formdata.cbStage = this.formdata.cbStage.toString()
this.getDetail()
console.log(this.uploadData)
},
methods:{
goback(){
......
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