Commit 30f8ca3b 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 c6218fb5 31bbc0db
...@@ -49,7 +49,8 @@ spring: ...@@ -49,7 +49,8 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://111.204.34.146:63308/cscec_bms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai # url: jdbc:mysql://111.204.34.146:63308/cscec_bms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://172.17.0.12:3306/cscec_bms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
username: dev username: dev
password: DskSzh!456 password: DskSzh!456
# 从库数据源 # 从库数据源
...@@ -101,9 +102,10 @@ spring: ...@@ -101,9 +102,10 @@ spring:
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring: spring:
redis: redis:
host: 111.204.34.146 # host: 111.204.34.146
host: 172.17.0.12
# 端口,默认为6379 # 端口,默认为6379
port: 63379 port: 6379
# 数据库索引 # 数据库索引
database: 13 database: 13
# 密码 # 密码
......
...@@ -49,7 +49,8 @@ spring: ...@@ -49,7 +49,8 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://111.204.34.146:63308/cscec_bms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai # url: jdbc:mysql://111.204.34.146:63308/cscec_bms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://172.17.0.12:3306/cscec_bms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=Asia/Shanghai
username: dev username: dev
password: DskSzh!456 password: DskSzh!456
# 从库数据源 # 从库数据源
...@@ -101,9 +102,10 @@ spring: ...@@ -101,9 +102,10 @@ spring:
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉) --- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring: spring:
redis: redis:
host: 111.204.34.146 # host: 111.204.34.146
host: 172.17.0.12
# 端口,默认为6379 # 端口,默认为6379
port: 63379 port: 6379
# 数据库索引 # 数据库索引
database: 13 database: 13
# 密码 # 密码
......
...@@ -188,6 +188,7 @@ tenant: ...@@ -188,6 +188,7 @@ tenant:
- f_ads_bsi_kpi_proj_two - f_ads_bsi_kpi_proj_two
- cb_summary - cb_summary
- cb_summary_actual - cb_summary_actual
- cb_summary_actual_lock
- cb_cost_measure - cb_cost_measure
- cb_cost_measure_actual - cb_cost_measure_actual
- cb_direct_expense - cb_direct_expense
......
...@@ -79,9 +79,9 @@ public class DataAnalysisComponent { ...@@ -79,9 +79,9 @@ public class DataAnalysisComponent {
List<CbQuantitySummary> quantitySummaryList = importList.stream().parallel() List<CbQuantitySummary> quantitySummaryList = importList.stream().parallel()
.filter(item -> !ObjectUtils.isEmpty(item.getCbName())) .filter(item -> !ObjectUtils.isEmpty(item.getCbName()))
.peek(item -> { .peek(item -> {
item.setProjectId(1L); item.setProjectId(bo.getProjectId());
item.setCbStage(0); item.setCbStage(bo.getCbStage());
item.setCbProjectFileId(1L); item.setCbProjectFileId(file.getId());
}).collect(Collectors.toList()); }).collect(Collectors.toList());
if (quantitySummaryList.isEmpty()) { if (quantitySummaryList.isEmpty()) {
throw new ServiceException("表格中不存在有效数据数据!"); throw new ServiceException("表格中不存在有效数据数据!");
......
...@@ -40,6 +40,10 @@ public interface CbProjectConstants { ...@@ -40,6 +40,10 @@ public interface CbProjectConstants {
* 删除状态:未删除 * 删除状态:未删除
*/ */
Integer DELETE_FLAG_EXIST = 0; Integer DELETE_FLAG_EXIST = 0;
/**
* 删除状态:待删除
*/
Integer DELETE_FLAG_WAIT_DELETE = 1;
/** /**
* 删除状态:已删除 * 删除状态:已删除
*/ */
......
...@@ -23,6 +23,7 @@ import java.io.UnsupportedEncodingException; ...@@ -23,6 +23,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* 项目成本文件表(CbProjectFile)表控制层 * 项目成本文件表(CbProjectFile)表控制层
...@@ -49,6 +50,12 @@ public class CbProjectFileController extends BaseController { ...@@ -49,6 +50,12 @@ public class CbProjectFileController extends BaseController {
public R<Map<String, String>> uploadCbProjectFile(@Validated @ModelAttribute AddProjectFileUploadBo fileUploadBo) throws UnsupportedEncodingException { public R<Map<String, String>> uploadCbProjectFile(@Validated @ModelAttribute AddProjectFileUploadBo fileUploadBo) throws UnsupportedEncodingException {
MultipartFile file = fileUploadBo.getFile(); MultipartFile file = fileUploadBo.getFile();
Assert.notNull(file, "上传文件不能为空"); Assert.notNull(file, "上传文件不能为空");
//校验格式
String fileFormat = Objects.requireNonNull(fileUploadBo.getFile().getOriginalFilename()).substring(fileUploadBo.getFile().getOriginalFilename().lastIndexOf("."));
Assert.isTrue(".xlsx".equals(fileFormat) || ".xls".equals(fileFormat), "文件格式不正确");
//校验同一成本类型下是否存在相同文件
baseService.checkProjectFileExist(fileUploadBo);
SysOssVo oss = iSysOssService.upload(file); SysOssVo oss = iSysOssService.upload(file);
//添加项目上传文件记录 //添加项目上传文件记录
CbProjectFile cbProjectFile; CbProjectFile cbProjectFile;
...@@ -72,7 +79,7 @@ public class CbProjectFileController extends BaseController { ...@@ -72,7 +79,7 @@ public class CbProjectFileController extends BaseController {
*/ */
@DeleteMapping("/deleteCbProjectFile/{fileId}") @DeleteMapping("/deleteCbProjectFile/{fileId}")
public R<Void> deleteCbProjectFile(@NotNull(message = "文件ID不能为空") @PathVariable Long fileId) { public R<Void> deleteCbProjectFile(@NotNull(message = "文件ID不能为空") @PathVariable Long fileId) {
return toAjax(baseService.deleteProjectFile(fileId)); return toAjax(baseService.deleteProjectFile(new Long[]{fileId}));
} }
/** /**
......
...@@ -6,11 +6,8 @@ import com.dsk.common.core.domain.PageQuery; ...@@ -6,11 +6,8 @@ import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.R; import com.dsk.common.core.domain.R;
import com.dsk.common.core.page.TableDataInfo; import com.dsk.common.core.page.TableDataInfo;
import com.dsk.cscec.domain.CbProjectRecord; import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.AddCbProjectBo; import com.dsk.cscec.domain.bo.*;
import com.dsk.cscec.domain.bo.AddNewCbProjectBo; import com.dsk.cscec.domain.vo.CbProjectRecordSearchVo;
import com.dsk.cscec.domain.bo.CbProjectSearchBo;
import com.dsk.cscec.domain.bo.EditProjectInfoBo;
import com.dsk.cscec.domain.vo.ProjectRecordSearchVo;
import com.dsk.cscec.service.CbProjectRecordService; import com.dsk.cscec.service.CbProjectRecordService;
import com.dsk.cscec.service.IDProjectService; import com.dsk.cscec.service.IDProjectService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -19,6 +16,7 @@ import org.springframework.web.bind.annotation.*; ...@@ -19,6 +16,7 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
...@@ -69,10 +67,18 @@ public class CbProjectRecordController extends BaseController { ...@@ -69,10 +67,18 @@ public class CbProjectRecordController extends BaseController {
* 获取项目台账列表 * 获取项目台账列表
*/ */
@GetMapping("/getProjectList") @GetMapping("/getProjectList")
public TableDataInfo<ProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery) { public TableDataInfo<CbProjectRecordSearchVo> getProjectList(@RequestBody CbProjectSearchBo searchBo, PageQuery pageQuery) {
return baseService.getProjectList(searchBo, pageQuery); return baseService.getProjectList(searchBo, pageQuery);
} }
/**
* 获取项目历史阶段信息(懒加载)
*/
@GetMapping("/getProjectHistoryInfo")
public R<List<CbProjectRecord>> getProjectHistoryInfo(@RequestBody CbProjectHistorySearchBo searchBo) {
return R.ok(baseService.getProjectHistoryInfo(searchBo));
}
/** /**
* 修改项目信息 * 修改项目信息
*/ */
...@@ -97,16 +103,29 @@ public class CbProjectRecordController extends BaseController { ...@@ -97,16 +103,29 @@ public class CbProjectRecordController extends BaseController {
return R.ok(baseService.addNewStageProject(newProjectBo)); return R.ok(baseService.addNewStageProject(newProjectBo));
} }
/**
* 查询当前项目可删除成本阶段
* 即查询当前项目非草稿的成本阶段
*/
@GetMapping("/getProjectCbStageNotDraft/{relatedId}")
public R<List<Integer>> getProjectCbStageNotDraft(@PathVariable Long relatedId) {
return R.ok(baseService.getProjectCbStageNotDraft(relatedId));
}
/**
* 批量删除项目
*/
@DeleteMapping("/batchDeleteProject/{projectIds}")
public R<Void> batchDeleteProject(@NotNull(message = "项目ID不能为空") @PathVariable Long[] projectIds) {
return toAjax(baseService.batchDeleteProject(Arrays.asList(projectIds)));
}
/** /**
* 获取草稿弹窗列表 * 获取草稿弹窗列表
*/ */
@GetMapping("/getDraftDialogList") @GetMapping("/getDraftDialogList")
public R<List<CbProjectRecord>> getDraftDialogList() { public TableDataInfo<CbProjectRecord> getDraftDialogList(PageQuery pageQuery) {
List<CbProjectRecord> draftList = baseService.getDraftDialogList(); return baseService.getDraftDialogList(pageQuery);
if (draftList.isEmpty()) {
return R.ok("暂无草稿记录");
}
return R.ok(draftList);
} }
/** /**
......
...@@ -34,7 +34,7 @@ public class CbQuantitySummaryController extends BaseController { ...@@ -34,7 +34,7 @@ public class CbQuantitySummaryController extends BaseController {
* @return * @return
*/ */
@GetMapping(value = "/subjectTree") @GetMapping(value = "/subjectTree")
public R<Map<String, Object>> subjectTree(CbProjectBaseBo bo) { public R<List<Map<String, Object>>> subjectTree(CbProjectBaseBo bo) {
return R.ok(baseService.subjectTree(bo)); return R.ok(baseService.subjectTree(bo));
} }
......
package com.dsk.cscec.controller;
import com.dsk.common.core.controller.BaseController;
import com.dsk.cscec.service.CbSceneExpenseChildrenService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 现场经费-工资统筹、其他费用、现场管理费表(CbSceneExpenseChildren)表控制层
*
* @author sxk
* @since 2024-02-22 09:58:57
*/
@RestController
@RequestMapping("cbSceneExpenseChildren")
public class CbSceneExpenseChildrenController extends BaseController {
/**
* 服务对象
*/
@Resource
private CbSceneExpenseChildrenService baseService;
}
package com.dsk.cscec.controller;
import com.dsk.common.core.controller.BaseController;
import com.dsk.cscec.service.CbSceneExpenseMonthService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 现场经费-每月费用表(CbSceneExpenseMonth)表控制层
*
* @author sxk
* @since 2024-02-22 09:59:28
*/
@RestController
@RequestMapping("cbSceneExpenseMonth")
public class CbSceneExpenseMonthController extends BaseController {
/**
* 服务对象
*/
@Resource
private CbSceneExpenseMonthService baseService;
}
...@@ -7,6 +7,7 @@ import com.dsk.common.core.domain.R; ...@@ -7,6 +7,7 @@ import com.dsk.common.core.domain.R;
import com.dsk.common.utils.poi.ExcelUtil; import com.dsk.common.utils.poi.ExcelUtil;
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;
import com.dsk.cscec.domain.bo.CbSummaryActualLockBo;
import com.dsk.cscec.domain.bo.CbSummaryBo; import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo; import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.domain.vo.CbSummaryCostAccountExportVo; import com.dsk.cscec.domain.vo.CbSummaryCostAccountExportVo;
...@@ -64,10 +65,20 @@ public class CbSummaryController extends BaseController { ...@@ -64,10 +65,20 @@ public class CbSummaryController extends BaseController {
* @return * @return
*/ */
@GetMapping("/expenseDateList") @GetMapping("/expenseDateList")
public R<List<String>> getExpenseDateList(@Validated CbSummaryBo bo) { public R<List<Map<String,Object>>> getExpenseDateList(@Validated CbSummaryBo bo) {
return R.ok(cbSummaryService.getExpenseDateList(bo)); return R.ok(cbSummaryService.getExpenseDateList(bo));
} }
/**
* 已锁定月份
* @param bo
* @return
*/
@GetMapping("/expenseDateList/locked")
public R<List<String>> getLockedList(@Validated CbSummaryBo bo) {
return R.ok(cbSummaryService.getLockedList(bo));
}
/** /**
* 编辑成本 * 编辑成本
* *
...@@ -79,9 +90,25 @@ public class CbSummaryController extends BaseController { ...@@ -79,9 +90,25 @@ public class CbSummaryController extends BaseController {
return cbSummaryService.insertOrUpdateActual(boList) == true ? R.ok() : R.fail(); return cbSummaryService.insertOrUpdateActual(boList) == true ? R.ok() : R.fail();
} }
//锁定成本前提示未填项(按一级大类) /**
* 锁定成本前提示未填项(按一级大类)
* @param bo
* @return
*/
@GetMapping("/getUnfilled")
public R getUnfilled(CbSummaryActualLockBo bo){
return cbSummaryService.getUnfilled(bo);
}
//锁定成本 /**
* 按月份锁定成本
* @param bo
* @return
*/
@PostMapping("/lockActual")
public R lockActual(@RequestBody CbSummaryActualLockBo bo) {
return cbSummaryService.lockActual(bo) == true ? R.ok() : R.fail();
}
/** /**
* 导出excel-按月导出所有 * 导出excel-按月导出所有
...@@ -89,7 +116,7 @@ public class CbSummaryController extends BaseController { ...@@ -89,7 +116,7 @@ public class CbSummaryController extends BaseController {
* @param response * @param response
*/ */
@PostMapping("/export") @PostMapping("/export")
public void export(CbSummaryActualListBo bo, HttpServletResponse response) { public void export(@RequestBody CbSummaryActualListBo bo, HttpServletResponse response) {
List<CbSummaryActualListVo> actualListVoList = cbSummaryService.getAll(bo); List<CbSummaryActualListVo> actualListVoList = cbSummaryService.getAll(bo);
if(bo.getCbType()==1){ if(bo.getCbType()==1){
List<CbSummaryProjectExportVo> list = BeanUtil.copyToList(actualListVoList,CbSummaryProjectExportVo.class); List<CbSummaryProjectExportVo> list = BeanUtil.copyToList(actualListVoList,CbSummaryProjectExportVo.class);
...@@ -101,6 +128,13 @@ public class CbSummaryController extends BaseController { ...@@ -101,6 +128,13 @@ public class CbSummaryController extends BaseController {
} }
//导入 /**
* 解析并保存数据
* @param projectId
*/
@PostMapping("/analysisData")
public void analysisData(Long projectId){
cbSummaryService.importCbProject(projectId);
}
} }
package com.dsk.cscec.domain; package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.dsk.common.core.domain.BaseEntity; import com.dsk.common.core.domain.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
...@@ -34,6 +35,10 @@ public class CbDirectExpense extends BaseEntity implements Serializable { ...@@ -34,6 +35,10 @@ public class CbDirectExpense extends BaseEntity implements Serializable {
* 父级ID * 父级ID
*/ */
private Long parentId; private Long parentId;
/**
* 项目文件ID
*/
private Long projectFileId;
/** /**
* 序号 * 序号
*/ */
...@@ -121,6 +126,7 @@ public class CbDirectExpense extends BaseEntity implements Serializable { ...@@ -121,6 +126,7 @@ public class CbDirectExpense extends BaseEntity implements Serializable {
/** /**
* 删除状态(0:否、2:是) * 删除状态(0:否、2:是)
*/ */
@TableLogic(value = "0", delval = "2")
private Integer delFlag; private Integer delFlag;
/** /**
* 备注 * 备注
......
...@@ -48,7 +48,7 @@ public class CbProjectFile extends BaseEntity implements Serializable { ...@@ -48,7 +48,7 @@ public class CbProjectFile extends BaseEntity implements Serializable {
*/ */
private String fileOssUrl; private String fileOssUrl;
/** /**
* 项目文件状态(0:待解析、1:解析中、2:解析成功、3:解析失败) * 项目文件状态(0:准备中、1:解析中、2:解析成功、3:解析失败)
*/ */
private Integer fileParseStatus; private Integer fileParseStatus;
/** /**
......
package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 现场经费-工资统筹、其他费用、现场管理费表(CbSceneExpenseChildren)实体类
*
* @author sxk
* @since 2024-02-22 09:59:00
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class CbSceneExpenseChildren extends BaseEntity implements Serializable {
private static final long serialVersionUID = 895279707061984760L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 项目ID
*/
private Long projectId;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 父级ID
*/
private Long parentId;
/**
* 序号
*/
private String number;
/**
* 排序
*/
private Integer sort;
/**
* 数据类型(0:工资统筹、1:现场管理费、2:其他费用)
*/
private Integer dataType;
/**
* 名称
*/
private String expenseName;
/**
* 单位
*/
private String unit;
/**
* 成本数量-工资统筹表
*/
private Integer cbCount;
/**
* 使用时间-其他费用表
*/
private Integer useTime;
/**
* 工程量-现场管理费表
*/
private String engineeringVolume;
/**
* 公司单价/不含税单价
*/
private String unitPrice;
/**
* 目标成本合价(不含税)/不含税合价
*/
private String excludeTaxSumPrice;
/**
* 目标成本合价(含税)/含税合价
*/
private String includeTaxSumPrice;
/**
* 成本科目
*/
private String cbSubject;
/**
* 税金类型
*/
private String taxType;
/**
* 删除状态(0:否、2:是)
*/
@TableLogic(value = "0", delval = "2")
private Integer delFlag;
/**
* 备注
*/
private String remark;
}
package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 现场经费-每月费用表(CbSceneExpenseMonth)实体类
*
* @author sxk
* @since 2024-02-22 09:59:28
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class CbSceneExpenseMonth extends BaseEntity implements Serializable {
private static final long serialVersionUID = -73353509267146384L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 现场经费ID
*/
private Long sceneExpenseId;
/**
* 本月费用
*/
private Double currentMonthExpense;
/**
* 费用日期
*/
private String expenseDate;
/**
* 删除状态(0:否、2:是)
*/
@TableLogic(value = "0", delval = "2")
private Integer delFlag;
}
...@@ -49,6 +49,9 @@ public class CbSubject implements Serializable { ...@@ -49,6 +49,9 @@ public class CbSubject implements Serializable {
* 类型 0: 未归类 1:房建 * 类型 0: 未归类 1:房建
*/ */
private Integer type; private Integer type;
private Date createTime; private Date createTime;
private Integer sort;
} }
package com.dsk.cscec.domain; package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
...@@ -83,6 +84,7 @@ public class CbSummary implements Serializable { ...@@ -83,6 +84,7 @@ public class CbSummary implements Serializable {
/** /**
* 删除状态(0:否、2:是) * 删除状态(0:否、2:是)
*/ */
@TableLogic
private Integer delFlag; private Integer delFlag;
/** /**
* 成本类型(1项目汇总,2成本科目汇总) * 成本类型(1项目汇总,2成本科目汇总)
......
...@@ -40,7 +40,7 @@ public class CbSummaryActual implements Serializable { ...@@ -40,7 +40,7 @@ public class CbSummaryActual implements Serializable {
/** /**
* 是否锁定(0否,1是) * 是否锁定(0否,1是)
*/ */
private Integer lockStatus; // private Integer lockStatus;
/** /**
* 创建时间 * 创建时间
*/ */
......
package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import java.util.Date;
import java.io.Serializable;
/**
* 成本汇总-每月成本锁定(CbSummaryActualLock)实体类
*
* @author makejava
* @since 2024-02-19
*/
@Data
public class CbSummaryActualLock implements Serializable {
private static final long serialVersionUID = 849892917534518164L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 费用日期
*/
private String expenseDate;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除状态(0:否、2:是)
*/
@TableLogic
private Integer delFlag;
}
package com.dsk.cscec.domain.vo; package com.dsk.cscec.domain.bo;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* @author sxk * @author sxk
* @date 2024.02.18 * @date 2024.02.18
* @time 15:08 * @time 15:04
*/ */
@Data @Data
public class ProjectRecordSearchVo { public class CbProjectHistorySearchBo {
/** /**
* 项目ID * 项目ID
*/ */
private Long id; private Long projectId;
/** /**
* 项目名称 * 项目名称
*/ */
...@@ -24,11 +22,11 @@ public class ProjectRecordSearchVo { ...@@ -24,11 +22,11 @@ public class ProjectRecordSearchVo {
*/ */
private String ipmProjectNo; private String ipmProjectNo;
/** /**
* 文件名称 * 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/ */
private String projectFileName; private Integer cbStage;
/** /**
* 项目数据 * 项目文件状态(1:解析中、2:解析成功、3:解析失败)
*/ */
private List<ProjectRecordDataVo> dataVoList; private Integer projectFileStatus;
} }
...@@ -15,6 +15,10 @@ public class CbSummaryActualListBo extends BaseEntity { ...@@ -15,6 +15,10 @@ public class CbSummaryActualListBo extends BaseEntity {
* 主键id * 主键id
*/ */
private Long id; private Long id;
/**
* 项目id
*/
private Long projectId;
/** /**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本) * 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/ */
......
package com.dsk.cscec.domain.bo;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
/**
* 成本汇总-每月成本锁定(CbSummaryActualLock)bo
*
* @author cyf
* @since 2024-02-19
*/
@Data
public class CbSummaryActualLockBo extends BaseEntity {
/**
* 项目id
*/
private Long projectId;
/**
* 费用日期
*/
private String expenseDate;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType;
}
...@@ -10,7 +10,7 @@ import java.util.Date; ...@@ -10,7 +10,7 @@ import java.util.Date;
* @time 15:18 * @time 15:18
*/ */
@Data @Data
public class ProjectRecordDataVo { public class CbProjectRecordDataVo {
/** /**
* 项目文件状态(1:解析中、2:解析成功、3:解析失败) * 项目文件状态(1:解析中、2:解析成功、3:解析失败)
*/ */
......
package com.dsk.cscec.domain.vo;
import com.dsk.cscec.domain.CbProjectRecord;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* @author sxk
* @date 2024.02.18
* @time 15:08
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class CbProjectRecordSearchVo extends CbProjectRecord {
/**
* 更新者
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否有子集
*/
private Boolean hasChildren;
}
...@@ -26,6 +26,10 @@ public class CbSummaryActualListVo extends BaseEntity { ...@@ -26,6 +26,10 @@ public class CbSummaryActualListVo extends BaseEntity {
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本) * 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/ */
private Integer cbStage; private Integer cbStage;
/**
* 层级
*/
private Integer level;
/** /**
* 序号 * 序号
*/ */
...@@ -82,10 +86,6 @@ public class CbSummaryActualListVo extends BaseEntity { ...@@ -82,10 +86,6 @@ public class CbSummaryActualListVo extends BaseEntity {
* 费用日期 * 费用日期
*/ */
private String expenseDate; private String expenseDate;
/**
* 是否锁定(0否,1是)
*/
private Integer lockStatus;
private List<CbSummaryActualListVo> children; private List<CbSummaryActualListVo> children;
} }
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 成本汇总(CbSummary)-成本科目汇总导入Vo
*
* @author cyf
* @since 2024-02-06
*/
@Data
@NoArgsConstructor
public class CbSummaryCostAccountImportVo implements Serializable {
private static final long serialVersionUID = -20126964599875841L;
/**
* 排序
*/
private Integer sort;
/**
* 层级
*/
private Integer level;
/**
* 项目id
*/
private Long projectId;
/**
* 项目成本文件id
*/
private Long cbProjectFileId;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType = 2;
/**
* 序号
*/
@ExcelProperty(value = "序号")
private String number;
/**
* 成本科目
*/
@ExcelProperty(value = "成本科目")
private String cbName;
/**
* 不含税成本合价
*/
@ExcelProperty(value = "不含税成本合价")
private String taxExclusiveTotal;
/**
* 成本税金合价
*/
@ExcelProperty(value = "成本税金合价")
private String cbTaxesTotal;
/**
* 含税成本合价
*/
@ExcelProperty(value = "含税成本合价")
private String taxInclusiveTotal;
/**
* 成本占比
*/
@ExcelProperty(value = "成本占比")
private String cbProportion;
/**
* 含税成本平米指标
*/
@ExcelProperty(value = "含税成本平米指标")
private String taxInclusivePmTarget;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}
package com.dsk.cscec.domain.vo; package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
* 成本汇总(CbSummary)-项目汇总导入Vo * 成本汇总(CbSummary)-项目汇总导入Vo
...@@ -18,7 +16,26 @@ import java.util.Date; ...@@ -18,7 +16,26 @@ import java.util.Date;
@NoArgsConstructor @NoArgsConstructor
public class CbSummaryProjectImportVo implements Serializable { public class CbSummaryProjectImportVo implements Serializable {
private static final long serialVersionUID = -20126964599875841L; private static final long serialVersionUID = -20126964599875841L;
/**
* 排序
*/
private Integer sort;
/**
* 层级
*/
private Integer level;
/**
* 项目id
*/
private Long projectId;
/**
* 项目成本文件id
*/
private Long cbProjectFileId;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType = 1;
/** /**
* 序号 * 序号
*/ */
......
package com.dsk.cscec.listener;
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.CbSummaryCostAccountImportVo;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* 成本汇总-成本科目汇总自定义导入
*
* @author cyf
*/
@Slf4j
public class CbSummaryCostAccountImportListener extends AnalysisEventListener<CbSummaryCostAccountImportVo> implements ExcelListener<CbSummaryCostAccountImportVo> {
private final Long projectId;
private final Long fileId;
private ArrayList<CbSummaryCostAccountImportVo> resultList = new ArrayList<>();
private int sort = 0;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public CbSummaryCostAccountImportListener(Long projectId, Long fileId) {
this.projectId = projectId;
this.fileId = fileId;
}
@Override
public void invoke(CbSummaryCostAccountImportVo importVo, AnalysisContext context) {
importVo.setProjectId(projectId);
importVo.setCbProjectFileId(fileId);
importVo.setSort(++sort);
//层级处理
if (StringUtil.isNotBlank(importVo.getNumber())) {
//序号包含n个 - 为n+1级
int count = StringUtil.count(importVo.getNumber(), "-");
importVo.setLevel(count + 1);
} else {
failureNum++;
failureMsg.append("<br/>").append("第" + sort + "条数据序号为空");
return;
}
//父级数据处理
if (sort == 1) {
importVo.setLevel(0);
}
resultList.add(importVo);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<CbSummaryCostAccountImportVo> getExcelResult() {
return new ExcelResult<CbSummaryCostAccountImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "失败原因:共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "成本科目汇总数据已全部解析成功!共 " + getList().size() + " 条");
}
return successMsg.toString();
}
@Override
public List<CbSummaryCostAccountImportVo> getList() {
return resultList;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
package com.dsk.cscec.listener;
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.CbSummaryProjectImportVo;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* 成本汇总-项目汇总自定义导入
*
* @author cyf
*/
@Slf4j
public class CbSummaryProjectImportListener extends AnalysisEventListener<CbSummaryProjectImportVo> implements ExcelListener<CbSummaryProjectImportVo> {
// private final CbSummaryService cbSummaryService;
private final Long projectId;
private final Long fileId;
private ArrayList<CbSummaryProjectImportVo> resultList = new ArrayList<>();
private int sort = 0;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public CbSummaryProjectImportListener(Long projectId, Long fileId) {
// this.cbSummaryService = SpringUtils.getBean(CbSummaryService.class);
this.projectId = projectId;
this.fileId = fileId;
}
@Override
public void invoke(CbSummaryProjectImportVo importVo, AnalysisContext context) {
//第一个序号不能为空? todo
//添加父级数据
if (sort == 0) {
CbSummaryProjectImportVo firstVo = new CbSummaryProjectImportVo();
firstVo.setLevel(0);
firstVo.setCbName("成本汇总");
firstVo.setProjectId(projectId);
firstVo.setCbProjectFileId(fileId);
firstVo.setSort(sort);
resultList.add(firstVo);
}
importVo.setProjectId(projectId);
importVo.setCbProjectFileId(fileId);
importVo.setSort(++sort);
//层级处理
if (StringUtil.isBlank(importVo.getNumber())) {//序号为空则为上一个序号不为空的子级
//按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
Integer lastLevel = (Integer) objects[0];
importVo.setLevel(lastLevel + 1);
} else if (importVo.getNumber().matches("[\u4E00-\u9FA5]+")) {//判断是否为中文,如果是中文则为一级
importVo.setLevel(1);
} else if (importVo.getNumber().matches("^[0-9]*[1-9][0-9]*$")) {//判断是否为正整数
importVo.setLevel(Integer.valueOf(importVo.getNumber()));
}
// failureNum++;
// failureMsg.append("<br/>").append(failureNum);
resultList.add(importVo);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<CbSummaryProjectImportVo> getExcelResult() {
return new ExcelResult<CbSummaryProjectImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "失败原因:共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "项目汇总数据已全部解析成功!共 " + getList().size() + " 条");
}
return successMsg.toString();
}
@Override
public List<CbSummaryProjectImportVo> getList() {
return resultList;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
...@@ -2,9 +2,13 @@ package com.dsk.cscec.mapper; ...@@ -2,9 +2,13 @@ package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsk.cscec.domain.CbProjectRecord; import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.vo.ProjectRecordSearchVo; import com.dsk.cscec.domain.bo.CbProjectSearchBo;
import com.dsk.cscec.domain.vo.CbProjectRecordSearchVo;
import org.apache.ibatis.annotations.Param;
/** /**
* 项目台账表(CbProjectRecord)表数据库访问层 * 项目台账表(CbProjectRecord)表数据库访问层
...@@ -16,7 +20,15 @@ public interface CbProjectRecordMapper extends BaseMapper<CbProjectRecord> { ...@@ -16,7 +20,15 @@ public interface CbProjectRecordMapper extends BaseMapper<CbProjectRecord> {
/** /**
* 获取项目台账列表 * 获取项目台账列表
*/ */
Page<ProjectRecordSearchVo> selectPageProjectRecordList(Page<ProjectRecordSearchVo> build, QueryWrapper<CbProjectRecord> wrapper); Page<CbProjectRecordSearchVo> selectPageProjectRecordList(IPage<CbProjectSearchBo> build,
@Param("searchBo") CbProjectSearchBo searchBo,
@Param("deleteFlagExist") Integer deleteFlagExist,
@Param("projectFileStatusPreparing") Integer projectFileStatusPreparing);
/**
* 获取草稿弹窗列表
*/
Page<CbProjectRecord> selectPageDraftDialogList(@Param("page") Page<CbProjectRecord> page, @Param(Constants.WRAPPER) QueryWrapper<CbProjectRecord> wrapper);
} }
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSceneExpenseChildren;
/**
* 现场经费-工资统筹、其他费用、现场管理费表(CbSceneExpenseChildren)表数据库访问层
*
* @author sxk
* @since 2024-02-22 09:58:57
*/
public interface CbSceneExpenseChildrenMapper extends BaseMapper<CbSceneExpenseChildren> {
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSceneExpenseMonth;
/**
* 现场经费-每月费用表(CbSceneExpenseMonth)表数据库访问层
*
* @author sxk
* @since 2024-02-22 09:59:28
*/
public interface CbSceneExpenseMonthMapper extends BaseMapper<CbSceneExpenseMonth> {
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSummaryActualLock;
import com.dsk.cscec.domain.bo.CbSummaryBo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 成本汇总-每月成本锁定(CbSummaryActualLock)表数据库访问层
*
* @author makejava
* @since 2024-02-19
*/
public interface CbSummaryActualLockMapper extends BaseMapper<CbSummaryActualLock> {
/**
* 获取已锁定成本月份
*
* @param bo
* @return
*/
List<String> getLockedList(@Param("bo") CbSummaryBo bo);
}
...@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; ...@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSummaryActual; import com.dsk.cscec.domain.CbSummaryActual;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 成本汇总-每月费用(CbSummaryActual)表数据库访问层 * 成本汇总-每月费用(CbSummaryActual)表数据库访问层
...@@ -21,4 +23,11 @@ public interface CbSummaryActualMapper extends BaseMapper<CbSummaryActual> { ...@@ -21,4 +23,11 @@ public interface CbSummaryActualMapper extends BaseMapper<CbSummaryActual> {
*/ */
int insertOrUpdateBatch(@Param("entities") List<CbSummaryActual> entities); int insertOrUpdateBatch(@Param("entities") List<CbSummaryActual> entities);
/**
* 截至本月费用
* @param cbSummaryId
* @param expenseDate
* @return
*/
Map<String, BigDecimal> getTotal(@Param("cbSummaryId") Long cbSummaryId, @Param("expenseDate") String expenseDate);
} }
...@@ -23,6 +23,14 @@ public interface CbSummaryMapper extends BaseMapper<CbSummary> { ...@@ -23,6 +23,14 @@ public interface CbSummaryMapper extends BaseMapper<CbSummary> {
CbSummaryActualListVo getById(@Param("id") Long id, @Param("expenseDate") String expenseDate); CbSummaryActualListVo getById(@Param("id") Long id, @Param("expenseDate") String expenseDate);
/**
* 根据ids获取实际成本
* @param entities
* @param expenseDate
* @return
*/
List<CbSummaryActualListVo> getByIds(@Param("entities") List<CbSummary> entities, @Param("expenseDate") String expenseDate);
/** /**
* 根据月份获取所有项目汇总数据 * 根据月份获取所有项目汇总数据
* *
...@@ -45,7 +53,7 @@ public interface CbSummaryMapper extends BaseMapper<CbSummary> { ...@@ -45,7 +53,7 @@ public interface CbSummaryMapper extends BaseMapper<CbSummary> {
* @param bo * @param bo
* @return * @return
*/ */
List<String> getExpenseDateList(@Param("bo") CbSummaryBo bo); List<Map<String,Object>> getExpenseDateList(@Param("bo") CbSummaryBo bo);
/** /**
* 根据level获取名称/成本科目 * 根据level获取名称/成本科目
......
...@@ -13,6 +13,13 @@ import com.dsk.system.domain.vo.SysOssVo; ...@@ -13,6 +13,13 @@ import com.dsk.system.domain.vo.SysOssVo;
* @since 2024-02-05 14:01:06 * @since 2024-02-05 14:01:06
*/ */
public interface CbProjectFileService extends IService<CbProjectFile> { public interface CbProjectFileService extends IService<CbProjectFile> {
/**
* 校验同一成本类型下是否存在相同文件
*
* @param fileUploadBo 上传信息
*/
Boolean checkProjectFileExist(AddProjectFileUploadBo fileUploadBo);
/** /**
* 添加项目上传文件记录 * 添加项目上传文件记录
* *
...@@ -23,12 +30,12 @@ public interface CbProjectFileService extends IService<CbProjectFile> { ...@@ -23,12 +30,12 @@ public interface CbProjectFileService extends IService<CbProjectFile> {
CbProjectFile addProjectFile(AddProjectFileUploadBo fileUploadBo, SysOssVo oss); CbProjectFile addProjectFile(AddProjectFileUploadBo fileUploadBo, SysOssVo oss);
/** /**
* 逻辑删除项目上传文件记录 * 批量逻辑删除项目上传文件记录
* *
* @param fileId 文件ID * @param fileIds 文件ID
* @return 删除结果 * @return 删除结果
*/ */
Integer deleteProjectFile(Long fileId); Integer deleteProjectFile(Long[] fileIds);
/** /**
* 获取项目文件上传详情 * 获取项目文件上传详情
...@@ -37,5 +44,4 @@ public interface CbProjectFileService extends IService<CbProjectFile> { ...@@ -37,5 +44,4 @@ public interface CbProjectFileService extends IService<CbProjectFile> {
* @return 文件列表 * @return 文件列表
*/ */
QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId); QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId);
} }
...@@ -4,11 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService; ...@@ -4,11 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.common.core.domain.PageQuery; import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo; import com.dsk.common.core.page.TableDataInfo;
import com.dsk.cscec.domain.CbProjectRecord; import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.AddCbProjectBo; import com.dsk.cscec.domain.bo.*;
import com.dsk.cscec.domain.bo.AddNewCbProjectBo; import com.dsk.cscec.domain.vo.CbProjectRecordSearchVo;
import com.dsk.cscec.domain.bo.CbProjectSearchBo;
import com.dsk.cscec.domain.bo.EditProjectInfoBo;
import com.dsk.cscec.domain.vo.ProjectRecordSearchVo;
import java.util.List; import java.util.List;
...@@ -41,7 +38,15 @@ public interface CbProjectRecordService extends IService<CbProjectRecord> { ...@@ -41,7 +38,15 @@ public interface CbProjectRecordService extends IService<CbProjectRecord> {
* @param pageQuery 分页对象 * @param pageQuery 分页对象
* @return 分页数据 * @return 分页数据
*/ */
TableDataInfo<ProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery); TableDataInfo<CbProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery);
/**
* 获取项目历史阶段信息(懒加载)
*
* @param searchBo 查询条件
* @return 历史阶段信息
*/
List<CbProjectRecord> getProjectHistoryInfo(CbProjectHistorySearchBo searchBo);
/** /**
* 修改项目信息 * 修改项目信息
...@@ -67,12 +72,29 @@ public interface CbProjectRecordService extends IService<CbProjectRecord> { ...@@ -67,12 +72,29 @@ public interface CbProjectRecordService extends IService<CbProjectRecord> {
*/ */
CbProjectRecord addNewStageProject(AddNewCbProjectBo newProjectBo); CbProjectRecord addNewStageProject(AddNewCbProjectBo newProjectBo);
/**
* 查询当前项目非草稿的成本阶段
*
* @param relatedId 关联ID
* @return 已有数据的成本阶段
*/
List<Integer> getProjectCbStageNotDraft(Long relatedId);
/**
* 批量删除项目
*
* @param projectIds 项目ID
* @return 删除结果
*/
Integer batchDeleteProject(List<Long> projectIds);
/** /**
* 获取草稿弹窗列表 * 获取草稿弹窗列表
* *
* @return 草稿弹窗列表 * @param pageQuery 分页对象
* @return 分页数据
*/ */
List<CbProjectRecord> getDraftDialogList(); TableDataInfo<CbProjectRecord> getDraftDialogList(PageQuery pageQuery);
/** /**
* 删除草稿 * 删除草稿
......
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbSceneExpenseChildren;
/**
* 现场经费-工资统筹、其他费用、现场管理费表(CbSceneExpenseChildren)表服务接口
*
* @author sxk
* @since 2024-02-22 09:59:01
*/
public interface CbSceneExpenseChildrenService extends IService<CbSceneExpenseChildren> {
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbSceneExpenseMonth;
/**
* 现场经费-每月费用表(CbSceneExpenseMonth)表服务接口
*
* @author sxk
* @since 2024-02-22 09:59:28
*/
public interface CbSceneExpenseMonthService extends IService<CbSceneExpenseMonth> {
}
package com.dsk.cscec.service; 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.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;
import com.dsk.cscec.domain.bo.CbSummaryActualLockBo;
import com.dsk.cscec.domain.bo.CbSummaryBo; import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo; import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
...@@ -19,8 +22,11 @@ import java.util.Map; ...@@ -19,8 +22,11 @@ import java.util.Map;
*/ */
public interface CbSummaryService extends IService<CbSummary> { public interface CbSummaryService extends IService<CbSummary> {
//项目汇总导入 todo /**
void importCbProject(Long projectId, Integer cbStage); * 项目汇总导入
* @param projectId
*/
void importCbProject(Long projectId);
/** /**
* 获取一级名称/成本科目列表 * 获取一级名称/成本科目列表
...@@ -44,7 +50,15 @@ public interface CbSummaryService extends IService<CbSummary> { ...@@ -44,7 +50,15 @@ public interface CbSummaryService extends IService<CbSummary> {
* @param bo * @param bo
* @return * @return
*/ */
List<String> getExpenseDateList(CbSummaryBo bo); List<Map<String,Object>> getExpenseDateList(CbSummaryBo bo);
/**
* 获取已锁定成本月份
*
* @param bo
* @return
*/
List<String> getLockedList(CbSummaryBo bo);
/** /**
* 新增/更新每月费用 * 新增/更新每月费用
...@@ -54,6 +68,20 @@ public interface CbSummaryService extends IService<CbSummary> { ...@@ -54,6 +68,20 @@ public interface CbSummaryService extends IService<CbSummary> {
*/ */
boolean insertOrUpdateActual(List<CbSummaryActualBo> boList); boolean insertOrUpdateActual(List<CbSummaryActualBo> boList);
/**
* 获取未填写成本一级大类
* @param bo
* @return
*/
R getUnfilled(CbSummaryActualLockBo bo);
/**
* 锁定成本
* @param bo
* @return
*/
boolean lockActual(CbSummaryActualLockBo bo);
/** /**
* 导出列表获取 * 导出列表获取
* @param bo * @param bo
......
...@@ -18,7 +18,7 @@ import java.util.Map; ...@@ -18,7 +18,7 @@ import java.util.Map;
*/ */
public interface ICbQuantitySummaryService extends IService<CbQuantitySummary> { public interface ICbQuantitySummaryService extends IService<CbQuantitySummary> {
Map<String, Object> subjectTree(CbProjectBaseBo bo); List<Map<String, Object>> subjectTree(CbProjectBaseBo bo);
List<String> monthList(CbQuantitySummaryListBo bo); List<String> monthList(CbQuantitySummaryListBo bo);
......
...@@ -2,7 +2,9 @@ package com.dsk.cscec.service.impl; ...@@ -2,7 +2,9 @@ package com.dsk.cscec.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.constant.CbProjectConstants; import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile; import com.dsk.cscec.domain.CbProjectFile;
...@@ -17,6 +19,7 @@ import org.springframework.stereotype.Service; ...@@ -17,6 +19,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
...@@ -32,13 +35,34 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C ...@@ -32,13 +35,34 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C
private CbProjectFileMapper baseMapper; private CbProjectFileMapper baseMapper;
@Resource @Resource
private CbProjectRecordMapper projectRecordMapper; private CbProjectRecordMapper projectRecordMapper;
@Resource
private CbProjectFileMapper projectFileMapper;
/**
* 校验同一成本类型下是否存在相同文件
*
* @param fileUploadBo 上传信息
*/
@Override
public Boolean checkProjectFileExist(AddProjectFileUploadBo fileUploadBo) {
String filename = fileUploadBo.getFile().getOriginalFilename();
assert filename != null;
projectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, fileUploadBo.getProjectId())
.eq(CbProjectFile::getCbType, fileUploadBo.getCbType())).forEach(projectFile -> {
//仅对比文件名,不考虑文件格式
Assert.isFalse(projectFile.getFileName().substring(0, projectFile.getFileName().lastIndexOf(".")).equals(filename.substring(0, filename.lastIndexOf(".")))
, "当前成本类型下存在同名文件,请重新上传");
});
return true;
}
/** /**
* 添加项目上传文件记录 * 添加项目上传文件记录
* *
* @param fileUploadBo 上传信息 * @param fileUploadBo 上传信息
* @param oss oss信息 * @param oss oss信息
* @return * @return 文件记录
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
...@@ -58,16 +82,34 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C ...@@ -58,16 +82,34 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C
} }
/** /**
* 逻辑删除项目上传文件记录 * 批量逻辑删除项目上传文件记录
* *
* @param fileId 文件ID * @param fileIds 文件ID
* @return 删除结果 * @return 删除结果
*/ */
@Override @Override
public Integer deleteProjectFile(Long fileId) { @Transactional(rollbackFor = Exception.class)
CbProjectFile projectFile = baseMapper.selectById(fileId); public Integer deleteProjectFile(Long[] fileIds) {
Assert.notNull(projectFile, "该文件不存在"); int flag = 0;
return baseMapper.deleteById(projectFile); //查询待删除文件
List<CbProjectFile> fileList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.in(ObjectUtil.isNotNull(fileIds), CbProjectFile::getId, Arrays.asList(fileIds)));
for (CbProjectFile file : fileList) {
//不允许删除解析中的文件
Integer fileParseStatus = file.getFileParseStatus();
Assert.isFalse(fileParseStatus.equals(CbProjectConstants.PROJECT_FILE_STATUS_PARSING),
"文件正在解析中,不允许删除");
//准备中、的文件设为已删除,否则设为待删除
//设为待删除是为了方便各个成本类型删除数据
if (fileParseStatus.equals(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)) {
flag = baseMapper.deleteById(file);
} else {
flag = baseMapper.update(null, new UpdateWrapper<CbProjectFile>()
.set("del_flag", CbProjectConstants.DELETE_FLAG_WAIT_DELETE)
.eq("id", file.getId()));
}
}
return flag;
} }
/** /**
...@@ -91,7 +133,7 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C ...@@ -91,7 +133,7 @@ public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, C
QueryProjectFileUploadDetailVo draftDetailVo = new QueryProjectFileUploadDetailVo(); QueryProjectFileUploadDetailVo draftDetailVo = new QueryProjectFileUploadDetailVo();
draftDetailVo.setProjectId(projectId); draftDetailVo.setProjectId(projectId);
if (projectFileList.isEmpty()) { if (projectFileList.isEmpty()) {
return draftDetailVo; return null;
} }
//按照成本类型分类填充 //按照成本类型分类填充
......
...@@ -3,6 +3,7 @@ package com.dsk.cscec.service.impl; ...@@ -3,6 +3,7 @@ package com.dsk.cscec.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
...@@ -16,7 +17,7 @@ import com.dsk.cscec.constant.CbProjectConstants; ...@@ -16,7 +17,7 @@ import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile; import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbProjectRecord; import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.*; import com.dsk.cscec.domain.bo.*;
import com.dsk.cscec.domain.vo.ProjectRecordSearchVo; import com.dsk.cscec.domain.vo.CbProjectRecordSearchVo;
import com.dsk.cscec.mapper.CbProjectFileMapper; import com.dsk.cscec.mapper.CbProjectFileMapper;
import com.dsk.cscec.mapper.CbProjectRecordMapper; import com.dsk.cscec.mapper.CbProjectRecordMapper;
import com.dsk.cscec.service.CbProjectRecordService; import com.dsk.cscec.service.CbProjectRecordService;
...@@ -139,24 +140,68 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe ...@@ -139,24 +140,68 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
* @return 分页数据 * @return 分页数据
*/ */
@Override @Override
public TableDataInfo<ProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery) { public TableDataInfo<CbProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery) {
QueryWrapper<CbProjectRecord> wrapper = Wrappers.query(); Page<CbProjectRecordSearchVo> page = baseMapper.selectPageProjectRecordList(pageQuery.build(), searchBo, CbProjectConstants.DELETE_FLAG_EXIST, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING);
wrapper
.like(StringUtils.isNotBlank(searchBo.getProjectName()), "project_name", searchBo.getProjectName())
.like(StringUtils.isNotBlank(searchBo.getIpmProjectNo()), "ipm_project_no", searchBo.getIpmProjectNo());
//TODO:成本阶段、文件解析状态筛选 for (CbProjectRecordSearchVo searchVo : page.getRecords()) {
Integer cbStage = searchBo.getCbStage(); //判断是否有历史阶段
Integer projectFileStatus = searchBo.getProjectFileStatus(); searchVo.setHasChildren(baseMapper.selectCount(new LambdaQueryWrapper<CbProjectRecord>()
.eq(CbProjectRecord::getRelatedId, searchVo.getRelatedId())) > 1);
//关键字标红
if (StringUtils.isNotBlank(searchBo.getProjectName())) {
searchVo.setProjectName(StringUtils.markInRed(searchVo.getProjectName(), searchBo.getProjectName()));
}
Page<ProjectRecordSearchVo> page = baseMapper.selectPageProjectRecordList(pageQuery.build(), wrapper); //补充更新时间、更新人
for (ProjectRecordSearchVo searchVo : page.getRecords()) { CbProjectFile projectFile = projectFileMapper.selectOne(new LambdaQueryWrapper<CbProjectFile>()
Long projectId = searchVo.getId(); .eq(CbProjectFile::getProjectId, searchVo.getId())
//page. .orderByDesc(CbProjectFile::getUpdateTime)
.last("LIMIT 1"));
searchVo.setUpdateBy(projectFile.getUpdateBy());
searchVo.setUpdateTime(projectFile.getUpdateTime());
} }
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }
/**
* 获取项目历史阶段信息(懒加载)
*
* @param searchBo 查询条件
* @return 历史阶段信息
*/
@Override
public List<CbProjectRecord> getProjectHistoryInfo(CbProjectHistorySearchBo searchBo) {
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(searchBo.getProjectId());
//查询所有历史阶段项目(不含准备中的项目)
List<CbProjectRecord> projectRecordList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>()
.eq(CbProjectRecord::getRelatedId, projectRecord.getRelatedId())
.ne(CbProjectRecord::getId, projectRecord.getId())
.ne(CbProjectRecord::getProjectFileStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)
.like(StringUtils.isNotBlank(searchBo.getProjectName()), CbProjectRecord::getProjectName, searchBo.getProjectName())
.eq(StringUtils.isNotBlank(searchBo.getIpmProjectNo()), CbProjectRecord::getIpmProjectNo, searchBo.getIpmProjectNo())
.eq(ObjectUtil.isNotNull(searchBo.getCbStage()), CbProjectRecord::getCbStage, searchBo.getCbStage())
.eq(ObjectUtil.isNotNull(searchBo.getProjectFileStatus()), CbProjectRecord::getProjectFileStatus, searchBo.getProjectFileStatus()));
projectRecordList.forEach(record -> {
//关键字标红
if (StringUtils.isNotBlank(searchBo.getProjectName())) {
record.setProjectName(StringUtils.markInRed(record.getProjectFileName(), searchBo.getProjectName()));
}
//补充更新时间、更新人
CbProjectFile projectFile = projectFileMapper.selectOne(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, record.getId())
.orderByDesc(CbProjectFile::getUpdateTime)
.last("LIMIT 1"));
record.setUpdateBy(projectFile.getUpdateBy());
record.setUpdateTime(projectFile.getUpdateTime());
});
return projectRecordList;
}
/** /**
* 修改项目信息 * 修改项目信息
* *
...@@ -233,13 +278,70 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe ...@@ -233,13 +278,70 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
return null; return null;
} }
/**
* 查询当前项目非草稿的成本阶段
*
* @param relatedId 关联ID
* @return 已有数据的成本阶段
*/
@Override
public List<Integer> getProjectCbStageNotDraft(Long relatedId) {
//通过关联ID校验项目是否存在
List<CbProjectRecord> projectRecordList = this.checkRelatedIdExist(relatedId);
ArrayList<Integer> cbStageList = new ArrayList<>();
projectRecordList.forEach(projectRecord -> {
//文件状态为解析成功or解析失败即为有数据
if (!projectRecord.getProjectFileStatus().equals(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)
&& !projectRecord.getProjectFileStatus().equals(CbProjectConstants.PROJECT_FILE_STATUS_PARSING)
&& projectFileMapper.exists(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectRecord.getId())
.eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PARSE_SUCCESS)
.or()
.eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL))) {
cbStageList.add(projectRecord.getCbStage());
}
});
return cbStageList;
}
/**
* 批量删除项目
*
* @param projectIds 项目ID
* @return 删除结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Integer batchDeleteProject(List<Long> projectIds) {
int flag = 0;
for (Long projectId : projectIds) {
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(projectId);
//不允许删除正在解析中的项目
Assert.isFalse(projectRecord.getProjectFileStatus().equals(CbProjectConstants.PROJECT_FILE_STATUS_PARSING)
, "存在解析中的项目,删除失败");
//TODO:各个成本类型数据和对应每月成本数据暂不做删除,项目台账列表查不出来自然也无法查看数据
//删除项目文件记录
flag = projectFileMapper.delete(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId));
//删除项目记录
Assert.isTrue(flag > 0, "操作异常,请联系管理员");
flag = baseMapper.deleteById(projectId);
}
return flag;
}
/** /**
* 通过关联ID校验项目是否存在 * 通过关联ID校验项目是否存在
* *
* @return 该关联ID下的所有项目记录 * @return 该关联ID下的所有项目记录
*/ */
private List<CbProjectRecord> checkRelatedIdExist(Long relatedId) { private List<CbProjectRecord> checkRelatedIdExist(Long relatedId) {
List<CbProjectRecord> projectRecordList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>().eq(CbProjectRecord::getRelatedId, relatedId)); List<CbProjectRecord> projectRecordList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>()
.eq(CbProjectRecord::getRelatedId, relatedId));
Assert.isFalse(projectRecordList.isEmpty(), "关联ID无效"); Assert.isFalse(projectRecordList.isEmpty(), "关联ID无效");
return projectRecordList; return projectRecordList;
} }
...@@ -247,12 +349,17 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe ...@@ -247,12 +349,17 @@ public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMappe
/** /**
* 获取草稿弹窗列表 * 获取草稿弹窗列表
* *
* @return 草稿弹窗列表 * @param pageQuery 分页对象
* @return 分页数据
*/ */
@Override @Override
public List<CbProjectRecord> getDraftDialogList() { public TableDataInfo<CbProjectRecord> getDraftDialogList(PageQuery pageQuery) {
return baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>() QueryWrapper<CbProjectRecord> wrapper = Wrappers.query();
.eq(CbProjectRecord::getProjectFileStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)); wrapper
.eq("project_file_status", CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)
.eq("del_flag", CbProjectConstants.DELETE_FLAG_EXIST)
.orderByDesc("update_time");
return TableDataInfo.build(baseMapper.selectPageDraftDialogList(pageQuery.build(), wrapper));
} }
/** /**
......
...@@ -2,14 +2,17 @@ package com.dsk.cscec.service.impl; ...@@ -2,14 +2,17 @@ package com.dsk.cscec.service.impl;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.exception.ServiceException; import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.CbQuantitySummary; import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.CbQuantitySummaryActual; import com.dsk.cscec.domain.CbQuantitySummaryActual;
import com.dsk.cscec.domain.CbSubject;
import com.dsk.cscec.domain.bo.CbProjectBaseBo; import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo; import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo;
import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo; import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo;
import com.dsk.cscec.mapper.CbQuantitySummaryMapper; import com.dsk.cscec.mapper.CbQuantitySummaryMapper;
import com.dsk.cscec.mapper.CbSubjectMapper;
import com.dsk.cscec.service.ICbQuantitySummaryActualService; import com.dsk.cscec.service.ICbQuantitySummaryActualService;
import com.dsk.cscec.service.ICbQuantitySummaryService; import com.dsk.cscec.service.ICbQuantitySummaryService;
import jodd.bean.BeanException; import jodd.bean.BeanException;
...@@ -19,6 +22,8 @@ import org.springframework.stereotype.Service; ...@@ -19,6 +22,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -36,10 +41,12 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM ...@@ -36,10 +41,12 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM
@Autowired @Autowired
private ICbQuantitySummaryActualService baseActualService; private ICbQuantitySummaryActualService baseActualService;
@Resource
private CbSubjectMapper cbSubjectMapper;
@Override @Override
public Map<String, Object> subjectTree(CbProjectBaseBo bo) { public List<Map<String, Object>> subjectTree(CbProjectBaseBo bo) {
Map<String, Object> resultMap = new HashMap<>(); List<Map<String, Object>> resultList = new ArrayList<>();
List<Map<String, Object>> list = baseMapper.selectSubject(bo); List<Map<String, Object>> list = baseMapper.selectSubject(bo);
if (!ObjectUtils.isEmpty(list)) { if (!ObjectUtils.isEmpty(list)) {
Map<String, Map<String, Map<String, List<Map<String, Object>>>>> map = list.stream() Map<String, Map<String, Map<String, List<Map<String, Object>>>>> map = list.stream()
...@@ -47,13 +54,42 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM ...@@ -47,13 +54,42 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM
Collectors.groupingBy(item -> item.get("one").toString(), Collectors.groupingBy(item -> item.get("one").toString(),
Collectors.groupingBy(item -> item.get("two").toString(), Collectors.groupingBy(item -> item.get("two").toString(),
Collectors.groupingBy(item -> item.get("three").toString())))); Collectors.groupingBy(item -> item.get("three").toString()))));
resultMap.put("房建类成本科目", map); Map<String, Object> resMap = new HashMap<>();
List<Map<String, Object>> resList = new ArrayList<>();
resMap.put("name", "房建类成本科目");
resMap.put("sort", 1);
for (Map.Entry<String, Map<String, Map<String, List<Map<String, Object>>>>> entry : map.entrySet()) {
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());
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<>();
twoMap.put("name", twoEntry.getKey());
for (Map.Entry<String, List<Map<String, Object>>> threeEntry : twoEntry.getValue().entrySet()) {
Map<String, Object> threeMap = new HashMap<>();
threeMap.put("name", threeEntry.getKey());
twoList.add(threeMap);
} }
twoMap.put("children", twoList);
oneList.add(twoMap);
}
oneMap.put("children", oneList);
resList.add(oneMap);
}
resMap.put("children", resList);
resultList.add(resMap);
}
int otherSubjectCount = baseMapper.selectOtherSubjectCount(bo); int otherSubjectCount = baseMapper.selectOtherSubjectCount(bo);
if (otherSubjectCount > 0) { if (otherSubjectCount > 0) {
resultMap.put("未归类项目", "other"); Map<String, Object> resMap = new HashMap<>();
resMap.put("name", "未归类项目");
resMap.put("sort", 2);
resultList.add(resMap);
} }
return resultMap; return resultList;
} }
@Override @Override
......
package com.dsk.cscec.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.domain.CbSceneExpenseChildren;
import com.dsk.cscec.mapper.CbSceneExpenseChildrenMapper;
import com.dsk.cscec.service.CbSceneExpenseChildrenService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 现场经费-工资统筹、其他费用、现场管理费表(CbSceneExpenseChildren)表服务实现类
*
* @author sxk
* @since 2024-02-22 09:59:01
*/
@Service("cbSceneExpenseChildrenService")
public class CbSceneExpenseChildrenServiceImpl extends ServiceImpl<CbSceneExpenseChildrenMapper, CbSceneExpenseChildren> implements CbSceneExpenseChildrenService {
@Resource
private CbSceneExpenseChildrenMapper baseMapper;
}
package com.dsk.cscec.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.domain.CbSceneExpenseMonth;
import com.dsk.cscec.mapper.CbSceneExpenseMonthMapper;
import com.dsk.cscec.service.CbSceneExpenseMonthService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 现场经费-每月费用表(CbSceneExpenseMonth)表服务实现类
*
* @author sxk
* @since 2024-02-22 09:59:28
*/
@Service("cbSceneExpenseMonthService")
public class CbSceneExpenseMonthServiceImpl extends ServiceImpl<CbSceneExpenseMonthMapper, CbSceneExpenseMonth> implements CbSceneExpenseMonthService {
@Resource
private CbSceneExpenseMonthMapper baseMapper;
}
...@@ -7,31 +7,33 @@ import cn.hutool.core.lang.Assert; ...@@ -7,31 +7,33 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.core.domain.R;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException; import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.poi.ExcelUtil;
import com.dsk.cscec.constant.CbProjectConstants; import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile; import com.dsk.cscec.domain.*;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.domain.CbSummaryActual;
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;
import com.dsk.cscec.domain.bo.CbSummaryActualLockBo;
import com.dsk.cscec.domain.bo.CbSummaryBo; import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo; import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.mapper.CbProjectFileMapper; import com.dsk.cscec.domain.vo.CbSummaryCostAccountImportVo;
import com.dsk.cscec.mapper.CbProjectRecordMapper; import com.dsk.cscec.domain.vo.CbSummaryProjectImportVo;
import com.dsk.cscec.mapper.CbSummaryActualMapper; import com.dsk.cscec.listener.CbSummaryCostAccountImportListener;
import com.dsk.cscec.mapper.CbSummaryMapper; import com.dsk.cscec.listener.CbSummaryProjectImportListener;
import com.dsk.cscec.mapper.*;
import com.dsk.cscec.service.CbSummaryService; import com.dsk.cscec.service.CbSummaryService;
import com.dsk.system.service.ISysOssService;
import jodd.util.StringUtil; import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList; import java.io.InputStream;
import java.util.Date; import java.math.BigDecimal;
import java.util.List; import java.util.*;
import java.util.Map;
/** /**
* 成本汇总(CbSummary)表服务实现类 * 成本汇总(CbSummary)表服务实现类
...@@ -39,6 +41,7 @@ import java.util.Map; ...@@ -39,6 +41,7 @@ import java.util.Map;
* @author cyf * @author cyf
* @since 2024-02-06 * @since 2024-02-06
*/ */
@Slf4j
@Service @Service
public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary> implements CbSummaryService { public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary> implements CbSummaryService {
@Autowired @Autowired
...@@ -50,35 +53,156 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -50,35 +53,156 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
@Autowired @Autowired
private CbProjectRecordMapper cbProjectRecordMapper; private CbProjectRecordMapper cbProjectRecordMapper;
@Autowired
private CbSummaryActualLockMapper cbSummaryActualLockMapper;
@Autowired
private ISysOssService ossService;
@Override @Override
public void importCbProject(Long projectId, Integer cbStage) { public void importCbProject(Long projectId) {
//获取del_flag为1的文件,若存在则根据fileId删除相关基础数据,并修改文件del_flag为2 todo
//获取文件信息 //获取文件信息
List<CbProjectFile> cbProjectFiles = cbProjectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>() List<CbProjectFile> cbProjectFiles = cbProjectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId) .eq(CbProjectFile::getProjectId, projectId)
.eq(CbProjectFile::getCbStage, cbStage) // .eq(CbProjectFile::getCbStage, cbStage)
.eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_SUMMARY) .eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_SUMMARY)
.eq(CbProjectFile::getFileParseStatus,CbProjectConstants.PROJECT_FILE_STATUS_PREPARING)
); );
//解析数据 //解析数据
cbProjectFiles.forEach(cbProjectFile -> { cbProjectFiles.forEach(cbProjectFile -> {
MultipartFile file = null;//todo
if (cbProjectFile.getFileName().contains("项目")) {
} else if (cbProjectFile.getFileName().contains("项目")) {
if (cbProjectFile.getFileName().contains("项目")) {
saveCbSummaryProject(projectId,cbProjectFile);
} else if (cbProjectFile.getFileName().contains("成本科目")) {
saveCbSummaryCostAccount(projectId,cbProjectFile);
} else { } else {
//修改文件状态 //修改文件状态
cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL); cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
cbProjectFile.setFailRemark("文件名错误!"); cbProjectFile.setFailRemark("失败原因:文件名错误");
cbProjectFileMapper.updateById(cbProjectFile); cbProjectFileMapper.updateById(cbProjectFile);
} }
}); });
} }
/**
* 成本汇总-项目汇总导入
* @param projectId
* @param file
* @return
*/
boolean saveCbSummaryProject(Long projectId, CbProjectFile file){
//修改文件状态为解析中
file.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING);
cbProjectFileMapper.updateById(file);
//文件下载
InputStream inputStream = ossService.downFileIO(file.getFileOssId());
if (ObjectUtil.isNull(inputStream)) {
file.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
file.setFailRemark("失败原因:文件数据不存在");
cbProjectFileMapper.updateById(file);
return false;
}
//解析数据
ExcelResult<CbSummaryProjectImportVo> importVoExcelResult = ExcelUtil.importExcel(inputStream, CbSummaryProjectImportVo.class,new CbSummaryProjectImportListener(projectId,file.getId()));
log.info(importVoExcelResult.getAnalysis());
List<CbSummary> addList = BeanUtil.copyToList(importVoExcelResult.getList(), CbSummary.class);
this.saveBatch(addList);
//处理父级id
List<CbSummary> cbSummaryList = baseMapper.selectList(
new LambdaQueryWrapper<CbSummary>()
.eq(CbSummary::getProjectId, projectId)
.eq(CbSummary::getCbType, 1)
.orderByAsc(CbSummary::getSort)
);
for (CbSummary cbSummary:cbSummaryList) {
if(cbSummary.getLevel()==0){
continue;
}
//获取父级id
Integer parentLevel = cbSummary.getLevel()-1;
CbSummary parent = cbSummaryList.stream().filter(summary -> summary.getSort()<cbSummary.getSort()&&summary.getLevel()==parentLevel)
.max(Comparator.comparing(CbSummary::getSort)).get();
cbSummary.setParentId(parent.getId());
}
this.updateBatchById(cbSummaryList);
//修改文件状态为解析成功
file.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_SUCCESS);
cbProjectFileMapper.updateById(file);
return true;
}
/**
* 成本汇总-成本科目汇总导入
* @param projectId
* @param file
* @return
*/
boolean saveCbSummaryCostAccount(Long projectId,CbProjectFile file) {
//修改文件状态为解析中
file.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING);
cbProjectFileMapper.updateById(file);
//文件下载
InputStream inputStream = ossService.downFileIO(file.getFileOssId());
if (ObjectUtil.isNull(inputStream)) {
file.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
file.setFailRemark("失败原因:文件数据不存在");
cbProjectFileMapper.updateById(file);
return false;
}
//解析数据
ExcelResult<CbSummaryCostAccountImportVo> importVoExcelResult = ExcelUtil.importExcel(inputStream, CbSummaryCostAccountImportVo.class,new CbSummaryCostAccountImportListener(projectId,file.getId()));
log.info(importVoExcelResult.getAnalysis());
List<CbSummary> addList = BeanUtil.copyToList(importVoExcelResult.getList(), CbSummary.class);
this.saveBatch(addList);
//处理父级id
List<CbSummary> cbSummaryList = baseMapper.selectList(
new LambdaQueryWrapper<CbSummary>()
.eq(CbSummary::getProjectId, projectId)
.eq(CbSummary::getCbType, 1)
.orderByAsc(CbSummary::getSort)
);
for (CbSummary cbSummary:cbSummaryList) {
if(cbSummary.getLevel()==0){
continue;
}
//获取父级id
Integer parentLevel = cbSummary.getLevel()-1;
CbSummary parent = cbSummaryList.stream().filter(summary -> summary.getSort()<cbSummary.getSort()&&summary.getLevel()==parentLevel)
.max(Comparator.comparing(CbSummary::getSort)).get();
cbSummary.setParentId(parent.getId());
}
this.updateBatchById(cbSummaryList);
//修改文件状态为解析成功
file.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_SUCCESS);
cbProjectFileMapper.updateById(file);
return true;
}
@Override @Override
public List<Map<String, Object>> getCbNameList(CbSummaryBo bo) { public List<Map<String, Object>> getCbNameList(CbSummaryBo bo) {
Assert.notNull(bo.getProjectId(), "项目id不能为空"); Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notNull(bo.getCbStage(), "成本阶段不能为空"); // Assert.notNull(bo.getCbStage(), "成本阶段不能为空");
Assert.notNull(bo.getCbType(), "成本类型不能为空"); Assert.notNull(bo.getCbType(), "成本类型不能为空");
List<Map<String, Object>> resultList = new ArrayList<>(); List<Map<String, Object>> resultList = new ArrayList<>();
...@@ -96,36 +220,45 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -96,36 +220,45 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
@Override @Override
public List<CbSummaryActualListVo> getActualList(CbSummaryActualListBo bo) { public List<CbSummaryActualListVo> getActualList(CbSummaryActualListBo bo) {
Assert.notNull(bo.getId(),"id不能为空"); Assert.notNull(bo.getId(), "id不能为空");
Assert.notNull(bo.getCbType(),"成本类型不能为空"); Assert.notNull(bo.getCbType(), "成本类型不能为空");
if (StringUtil.isBlank(bo.getExpenseDate())) { if (StringUtil.isBlank(bo.getExpenseDate())) {
//默认当前月 //默认当前月
bo.setExpenseDate(DatePattern.SIMPLE_MONTH_FORMAT.format(new Date())); bo.setExpenseDate(DatePattern.SIMPLE_MONTH_FORMAT.format(new Date()));
} }
List<CbSummaryActualListVo> list = new ArrayList<>();
CbSummary cbSummary = baseMapper.selectById(bo.getId()); //当前父级数据
if (ObjectUtil.isEmpty(cbSummary)) { CbSummaryActualListVo cbSummaryActualListVo = baseMapper.getById(bo.getId(), bo.getExpenseDate());
return null; if (ObjectUtil.isEmpty(cbSummaryActualListVo)) {
return list;
} }
//截至本月费用汇总
Map<String, BigDecimal> parentTotal = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate());
cbSummaryActualListVo.setTaxExclusiveExpenseTotal(parentTotal.get("taxExclusiveExpenseTotal"));
cbSummaryActualListVo.setTaxInclusiveExpenseTotal(parentTotal.get("taxInclusiveExpenseTotal"));
List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate()); List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate());
if (0 == cbSummary.getLevel() && 1 == bo.getCbType()) { //截至本月费用汇总
//项目汇总 childrenList.forEach(children -> {
Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate());
children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal"));
children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal"));
});
if (0 == cbSummaryActualListVo.getLevel() && 1 == bo.getCbType()) {
//项目汇总一级列表
return childrenList; return childrenList;
}else if(0 == cbSummary.getLevel() && 2 == bo.getCbType()) { } else if (0 == cbSummaryActualListVo.getLevel() && 2 == bo.getCbType()) {
//成本科目汇总 //成本科目汇总一级列表
CbSummaryActualListVo cbSummaryActualListVo = baseMapper.getById(bo.getId(), bo.getExpenseDate());
cbSummaryActualListVo.setChildren(childrenList); cbSummaryActualListVo.setChildren(childrenList);
List<CbSummaryActualListVo> list = new ArrayList<>();
list.add(cbSummaryActualListVo); list.add(cbSummaryActualListVo);
return list; return list;
}else { } else {
//递归列表
childrenList = getProjectSumList(bo); childrenList = getProjectSumList(bo);
CbSummaryActualListVo cbSummaryActualListVo = baseMapper.getById(bo.getId(),bo.getExpenseDate());
cbSummaryActualListVo.setChildren(childrenList); cbSummaryActualListVo.setChildren(childrenList);
List<CbSummaryActualListVo> list = new ArrayList<>();
list.add(cbSummaryActualListVo); list.add(cbSummaryActualListVo);
return list; return list;
} }
...@@ -133,7 +266,7 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -133,7 +266,7 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
} }
/** /**
* 成本汇总列表 * 成本汇总递归列表
* *
* @param bo * @param bo
* @return * @return
...@@ -146,6 +279,10 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -146,6 +279,10 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
childBo.setId(children.getId()); childBo.setId(children.getId());
childBo.setExpenseDate(bo.getExpenseDate()); childBo.setExpenseDate(bo.getExpenseDate());
children.setChildren(getProjectSumList(childBo)); children.setChildren(getProjectSumList(childBo));
//截至本月费用汇总
Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(children.getId(), bo.getExpenseDate());
children.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal"));
children.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal"));
}); });
return childrenList; return childrenList;
...@@ -153,50 +290,142 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary ...@@ -153,50 +290,142 @@ public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary
} }
@Override @Override
public List<String> getExpenseDateList(CbSummaryBo bo) { public List<Map<String, Object>> getExpenseDateList(CbSummaryBo bo) {
Assert.notNull(bo.getProjectId(),"项目id不能为空"); Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notNull(bo.getCbStage(),"成本阶段不能为空"); // Assert.notNull(bo.getCbStage(),"成本阶段不能为空");
Assert.notNull(bo.getCbType(),"成本类型不能为空"); Assert.notNull(bo.getCbType(), "成本类型不能为空");
return baseMapper.getExpenseDateList(bo); return baseMapper.getExpenseDateList(bo);
} }
@Override
public List<String> getLockedList(CbSummaryBo bo) {
Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notNull(bo.getCbType(), "成本类型不能为空");
return cbSummaryActualLockMapper.getLockedList(bo);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean insertOrUpdateActual(List<CbSummaryActualBo> boList) { public boolean insertOrUpdateActual(List<CbSummaryActualBo> boList) {
if (CollectionUtil.isEmpty(boList)) { if (CollectionUtil.isEmpty(boList)) {
return false; return false;
} }
boList.forEach(bo->{ boList.forEach(bo -> {
Assert.notNull(bo.getCbSummaryId(),"成本汇总id不能为空"); Assert.notNull(bo.getCbSummaryId(), "成本汇总id不能为空");
Assert.notNull(bo.getExpenseDate(),"费用日期不能为空"); Assert.notNull(bo.getExpenseDate(), "费用日期不能为空");
}); });
List<CbSummaryActual> actualList = BeanUtil.copyToList(boList, CbSummaryActual.class);
//todo CbSummary cbSummary = baseMapper.selectById(boList.get(0).getCbSummaryId());
// throw new ServiceException("当前成本已锁定,不允许编辑!"); Assert.isFalse(ObjectUtil.isNull(cbSummary), "成本汇总数据不存在!");
String expenseDate = boList.get(0).getExpenseDate();
boolean exists = cbSummaryActualLockMapper.exists(
new LambdaQueryWrapper<CbSummaryActualLock>()
.eq(CbSummaryActualLock::getProjectId, cbSummary.getProjectId())
.eq(CbSummaryActualLock::getExpenseDate, expenseDate)
.eq(CbSummaryActualLock::getCbType, cbSummary.getCbType())
);
Assert.isFalse(exists, "该月成本已锁定");
List<CbSummaryActual> actualList = BeanUtil.copyToList(boList, CbSummaryActual.class);
return cbSummaryActualMapper.insertOrUpdateBatch(actualList) > 0; return cbSummaryActualMapper.insertOrUpdateBatch(actualList) > 0;
} }
@Override
public R getUnfilled(CbSummaryActualLockBo bo) {
Assert.notNull(bo.getCbType(), "成本类型不能为空");
Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notBlank(bo.getExpenseDate(), "费用日期不能为空");
StringBuilder unfilled = new StringBuilder();
//获取一级大类成本id
List<CbSummary> firstList = baseMapper.selectList(
new LambdaQueryWrapper<CbSummary>()
.eq(CbSummary::getProjectId, bo.getProjectId())
.eq(CbSummary::getLevel, 1)
.eq(CbSummary::getCbType, bo.getCbType())
.orderByAsc(CbSummary::getSort)
);
firstList.forEach(firstCb -> {
//获取大类下的所有子级id
List<CbSummary> allList = new ArrayList<>();
allList.add(firstCb);
allList.addAll(getAllChild(firstCb.getId(), new ArrayList<>()));
//根据子级id查询是否填写实际成本
List<CbSummaryActualListVo> vos = baseMapper.getByIds(allList, bo.getExpenseDate());
if (CollectionUtil.isEmpty(vos)) {
unfilled.append(firstCb.getCbName()).append("、");
}
});
if (unfilled.length() > 0) {
unfilled.deleteCharAt(unfilled.lastIndexOf("、"));
unfilled.append(" 未填写成本,是否继续锁定?");
return R.fail(unfilled.toString());
} else {
return R.ok();
}
}
private List<CbSummary> getAllChild(Long id, List<CbSummary> resultList) {
List<CbSummary> childList = baseMapper.selectList(
new LambdaQueryWrapper<CbSummary>()
.eq(CbSummary::getParentId, id)
);
if (CollectionUtil.isNotEmpty(childList)) {
resultList.addAll(childList);
childList.forEach(child -> {
getAllChild(child.getId(), resultList);
});
}
return resultList;
}
@Override
public boolean lockActual(CbSummaryActualLockBo bo) {
Assert.notNull(bo.getCbType(), "成本类型不能为空");
Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notBlank(bo.getExpenseDate(), "费用日期不能为空");
boolean exists = cbSummaryActualLockMapper.exists(
new LambdaQueryWrapper<CbSummaryActualLock>()
.eq(CbSummaryActualLock::getProjectId, bo.getProjectId())
.eq(CbSummaryActualLock::getExpenseDate, bo.getExpenseDate())
.eq(CbSummaryActualLock::getCbType, bo.getCbType())
);
Assert.isFalse(exists, "该月成本已锁定,请勿重复操作!");
CbSummaryActualLock lock = BeanUtil.copyProperties(bo, CbSummaryActualLock.class);
return cbSummaryActualLockMapper.insert(lock) > 0;
}
@Override @Override
public List<CbSummaryActualListVo> getAll(CbSummaryActualListBo bo) { public List<CbSummaryActualListVo> getAll(CbSummaryActualListBo bo) {
Assert.notNull(bo.getId(), "项目id不能为空"); Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notNull(bo.getCbType(), "成本类型不能为空"); Assert.notNull(bo.getCbType(), "成本类型不能为空");
Assert.notNull(bo.getExpenseDate(), "费用日期不能为空"); Assert.notNull(bo.getExpenseDate(), "费用日期不能为空");
//获取项目成本阶段 //获取项目成本阶段
CbProjectRecord cbProjectRecord = cbProjectRecordMapper.selectById(bo.getId()); CbProjectRecord cbProjectRecord = cbProjectRecordMapper.selectById(bo.getProjectId());
if (ObjectUtil.isNull(cbProjectRecord)) { if (ObjectUtil.isNull(cbProjectRecord)) {
throw new ServiceException("当前项目不存在"); throw new ServiceException("当前项目不存在");
} }
bo.setCbStage(cbProjectRecord.getCbStage()); // bo.setCbStage(cbProjectRecord.getCbStage());
List<CbSummaryActualListVo> resultList = new ArrayList<>();
if (bo.getCbType() == 1) { if (bo.getCbType() == 1) {
return baseMapper.getProjectAll(bo); resultList = baseMapper.getProjectAll(bo);
} else { } else {
return baseMapper.getCostAccountAll(bo); resultList = baseMapper.getCostAccountAll(bo);
} }
//todo 截至本月费用汇总 //截至本月费用汇总
resultList.forEach(cbSummaryActualListVo -> {
Map<String, BigDecimal> total = cbSummaryActualMapper.getTotal(cbSummaryActualListVo.getId(), bo.getExpenseDate());
cbSummaryActualListVo.setTaxExclusiveExpenseTotal(total.get("taxExclusiveExpenseTotal"));
cbSummaryActualListVo.setTaxInclusiveExpenseTotal(total.get("taxInclusiveExpenseTotal"));
});
return resultList;
} }
} }
<?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">
</mapper> </mapper>
\ No newline at end of file
...@@ -2,11 +2,48 @@ ...@@ -2,11 +2,48 @@
<!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.CbProjectRecordMapper"> <mapper namespace="com.dsk.cscec.mapper.CbProjectRecordMapper">
<!--获取项目台账列表--> <!--获取项目台账列表-->
<select id="selectPageProjectRecordList" resultType="com.dsk.cscec.domain.vo.ProjectRecordSearchVo"> <select id="selectPageProjectRecordList" resultType="com.dsk.cscec.domain.vo.CbProjectRecordSearchVo">
select cpr.id, select
cpr.id,
cpr.related_id,
cpr.project_name, cpr.project_name,
cpr.cb_stage,
cpr.project_file_status,
cpr.ipm_project_no, cpr.ipm_project_no,
cpr.project_file_name cpr.is_get_project_detail,
cpr.project_file_name,
cpr.create_time
from cb_project_record cpr
left join cb_project_record cprr
on cpr.related_id = cprr.related_id
and cpr.cb_stage &lt; cprr.cb_stage
where
cprr.cb_stage is null
and
cpr.del_flag=#{deleteFlagExist}
<if test="searchBo.projectName != null and searchBo.projectName != ''">
and cpr.project_name like concat('%',#{searchBo.projectName},'%')
</if>
<if test="searchBo.ipmProjectNo != null and searchBo.ipmProjectNo != ''">
and cpr.ipm_project_no = #{searchBo.ipmProjectNo}
</if>
<if test="searchBo.cbStage != null">
and cpr.cb_stage = #{searchBo.cbStage}
</if>
<if test="searchBo.projectFileStatus != null">
and project_file_status = #{searchBo.projectFileStatus}
</if>
and
cpr.project_file_status != #{projectFileStatusPreparing}
order by cpr.create_time desc
</select>
<!--获取草稿弹窗列表-->
<select id="selectPageDraftDialogList" resultType="com.dsk.cscec.domain.CbProjectRecord">
select cpr.id,
cpr.project_name,
cpr.cb_stage,
cpr.update_time
from cb_project_record cpr from cb_project_record cpr
${ew.getCustomSqlSegment}; ${ew.getCustomSqlSegment};
</select> </select>
......
...@@ -26,7 +26,14 @@ ...@@ -26,7 +26,14 @@
cqsa.record_date cqsa.record_date
from cb_quantity_summary cqs from cb_quantity_summary cqs
join cb_quantity_summary_actual cqsa on cqs.id = cqsa.cb_quantity_summary_id join cb_quantity_summary_actual cqsa on cqs.id = cqsa.cb_quantity_summary_id
where cqs.del_falg = 0 and cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage} and cqs.cb_subject_name = #{cbSubjectName} left join cb_subject cs1 on cqs.cb_subject_name = cs1.cb_subject_name
where cqs.del_falg = 0 and cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage}
<if test="cbSubjectName != null and cbSubjectName !=''">
<choose>
<when test="cbSubjectName == '未归类项目'"> and cs1.id is null </when>
<otherwise> and cqs.cb_subject_name = #{cbSubjectName} </otherwise>
</choose>
</if>
group by cqsa.record_date group by cqsa.record_date
order by cqsa.record_date order by cqsa.record_date
</select> </select>
...@@ -38,11 +45,18 @@ ...@@ -38,11 +45,18 @@
cqs.unit, cqs.material_description, cqs.guide_price, cqs.bid_unit_price, cqs.unit_price_difference, cqs.quantity, cqs.unit, cqs.material_description, cqs.guide_price, cqs.bid_unit_price, cqs.unit_price_difference, cqs.quantity,
cqs.combined_price, cqs.combined_price_tax, cqs.brand_name, cqs.bid_source, cqs.remark, cqs.`number`, cqsa.quantities, cqs.combined_price, cqs.combined_price_tax, cqs.brand_name, cqs.bid_source, cqs.remark, cqs.`number`, cqsa.quantities,
cqsa.quantities_unit, cqsa.conversion_quantities, cqsa.conversion_unit, cqsa.purchase_unit_price, cqsa.create_time, cqsa.quantities_unit, cqsa.conversion_quantities, cqsa.conversion_unit, cqsa.purchase_unit_price, cqsa.create_time,
cqsa.id actualId, cqsa.ipm_project_code, cqsa.ipm_contract_code, cqsa.ipm_job_code, cqsa.push_quantities cqsa.id actualId, cqsa.ipm_project_code, cqsa.ipm_contract_code, cqsa.ipm_biz_code, cqsa.push_quantities
from cb_quantity_summary cqs from cb_quantity_summary cqs
left join cb_quantity_summary_actual cqsa on cqs.id = cqsa.cb_quantity_summary_id left join cb_quantity_summary_actual cqsa on cqs.id = cqsa.cb_quantity_summary_id
where cqs.del_falg = 0 and cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage} and cqs.cb_subject_name = #{cbSubjectName} left join cb_subject cs1 on cqs.cb_subject_name = cs1.cb_subject_name
where cqs.del_falg = 0 and cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage}
<if test="recordDate != null and recordDate != ''"> and cqsa.record_date &lt;= #{recordDate} </if> <if test="recordDate != null and recordDate != ''"> and cqsa.record_date &lt;= #{recordDate} </if>
<if test="cbSubjectName != null and cbSubjectName !=''">
<choose>
<when test="cbSubjectName == '未归类项目'"> and cs1.id is null </when>
<otherwise> and cqs.cb_subject_name = #{cbSubjectName} </otherwise>
</choose>
</if>
order by cqsa.record_date desc order by cqsa.record_date desc
) a ) a
group by a.id group by a.id
......
<?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.CbSceneExpenseChildrenMapper">
</mapper>
<?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.CbSceneExpenseMonthMapper">
</mapper>
<?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.CbSummaryActualLockMapper">
<resultMap type="com.dsk.cscec.domain.CbSummaryActualLock" id="CbSummaryActualLockMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="projectId" column="project_id" jdbcType="INTEGER"/>
<result property="expenseDate" column="expense_date" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="delFlag" column="del_flag" jdbcType="INTEGER"/>
</resultMap>
<sql id="baseColumn">
id, project_id, expense_date, create_time, del_flag
</sql>
<select id="getLockedList" resultType="java.lang.String">
select csal.expense_date
from cb_summary_actual_lock csal
where
csal.project_id = #{bo.projectId}
and csal.cb_type = #{bo.cbType}
and csal.del_flag = 0
order by csal.expense_date desc
</select>
</mapper>
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
<result property="taxInclusiveExpense" column="tax_inclusive_expense" jdbcType="NUMERIC"/> <result property="taxInclusiveExpense" column="tax_inclusive_expense" jdbcType="NUMERIC"/>
<result property="taxExclusiveExpense" column="tax_exclusive_expense" jdbcType="NUMERIC"/> <result property="taxExclusiveExpense" column="tax_exclusive_expense" jdbcType="NUMERIC"/>
<result property="expenseDate" column="expense_date" jdbcType="VARCHAR"/> <result property="expenseDate" column="expense_date" jdbcType="VARCHAR"/>
<result property="lockStatus" column="lock_status" jdbcType="INTEGER"/> <!-- <result property="lockStatus" column="lock_status" jdbcType="INTEGER"/>-->
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="delFlag" column="del_flag" jdbcType="INTEGER"/> <result property="delFlag" column="del_flag" jdbcType="INTEGER"/>
</resultMap> </resultMap>
<sql id="baseColumn"> <sql id="baseColumn">
id, cb_summary_id, tax_inclusive_expense, tax_exclusive_expense, expense_date, lock_status, create_time, del_flag id, cb_summary_id, tax_inclusive_expense, tax_exclusive_expense, expense_date, create_time, del_flag
</sql> </sql>
<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true"> <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
...@@ -27,5 +27,16 @@ ...@@ -27,5 +27,16 @@
cb_summary_id = values(cb_summary_id) , tax_inclusive_expense = values(tax_inclusive_expense) , cb_summary_id = values(cb_summary_id) , tax_inclusive_expense = values(tax_inclusive_expense) ,
tax_exclusive_expense = values(tax_exclusive_expense) , expense_date = values(expense_date) tax_exclusive_expense = values(tax_exclusive_expense) , expense_date = values(expense_date)
</insert> </insert>
<select id="getTotal" resultType="map">
select ifnull(sum(csa.tax_inclusive_expense),0) taxInclusiveExpenseTotal,
ifnull(sum(csa.tax_exclusive_expense),0) taxExclusiveExpenseTotal
from cb_summary_actual csa
<where>
csa.cb_summary_id = #{cbSummaryId}
and csa.expense_date &lt;= #{expenseDate}
and csa.del_flag = 0
</where>
</select>
</mapper> </mapper>
...@@ -50,15 +50,32 @@ ...@@ -50,15 +50,32 @@
</where> </where>
</select> </select>
<select id="getByIds" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select csu.*,csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense,csa.expense_date
from cb_summary csu
left join cb_summary_actual csa on csu.id = csa.cb_summary_id
<where>
csa.expense_date = #{expenseDate}
and csa.del_flag = 0
and csu.del_flag = 0
and csu.id in
<foreach collection="entities" item="entity" separator="," open="(" close=")">
#{entity.id}
</foreach>
</where>
</select>
<select id="getProjectAll" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo"> <select id="getProjectAll" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select select
<include refid="baseColumn"></include>, <include refid="baseColumn"></include>,
csa.tax_inclusive_expense,csa.tax_exclusive_expense csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense
from cb_summary csu from cb_summary csu
left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{expenseDate} AND csa.del_flag = 0 left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{bo.expenseDate} AND csa.del_flag = 0
<where> <where>
csu.project_id = #{bo.id} csu.project_id = #{bo.projectId}
<if test="bo.cbStage != null">
and csu.cb_stage = #{bo.cbStage} and csu.cb_stage = #{bo.cbStage}
</if>
and csu.cb_type = #{bo.cbType} and csu.cb_type = #{bo.cbType}
and csu.del_flag = 0 and csu.del_flag = 0
and csu.level != 0 and csu.level != 0
...@@ -69,30 +86,33 @@ ...@@ -69,30 +86,33 @@
<select id="getCostAccountAll" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo"> <select id="getCostAccountAll" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select select
<include refid="baseColumn"></include>, <include refid="baseColumn"></include>,
csa.tax_inclusive_expense,csa.tax_exclusive_expense csa.id actualId,csa.tax_inclusive_expense,csa.tax_exclusive_expense
from cb_summary csu from cb_summary csu
left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{expenseDate} AND csa.del_flag = 0 left join cb_summary_actual csa on csu.id = csa.cb_summary_id and csa.expense_date = #{bo.expenseDate} AND csa.del_flag = 0
<where> <where>
csu.project_id = #{bo.projectId} csu.project_id = #{bo.projectId}
<if test="bo.cbStage != null">
and csu.cb_stage = #{bo.cbStage} and csu.cb_stage = #{bo.cbStage}
</if>
and csu.cb_type = #{bo.cbType} and csu.cb_type = #{bo.cbType}
and csu.del_flag = 0 and csu.del_flag = 0
</where> </where>
order by csu.sort order by csu.sort
</select> </select>
<select id="getExpenseDateList" resultType="string"> <select id="getExpenseDateList" resultType="map">
select csa.expense_date select csa.expense_date expenseDate,
if(csal.id is null,0,1) as isLock
from cb_summary_actual csa from cb_summary_actual csa
left join cb_summary csu on csu.id = csa.cb_summary_id left join cb_summary csu on csu.id = csa.cb_summary_id
left join cb_summary_actual_lock csal on csal.project_id = csu.project_id and csal.expense_date = csa.expense_date and csal.del_flag = 0
where where
csu.project_id = #{bo.projectId} csu.project_id = #{bo.projectId}
and csu.cb_stage = #{bo.cbStage}
and csu.cb_type = #{bo.cbType} and csu.cb_type = #{bo.cbType}
and csu.del_flag = 0 and csu.del_flag = 0
and csa.del_flag = 0 and csa.del_flag = 0
group by csa.expense_date group by csa.expense_date
order by csa.expense_date asc order by csa.expense_date desc
</select> </select>
<select id="selectByLevel" resultType="map"> <select id="selectByLevel" resultType="map">
...@@ -101,7 +121,7 @@ ...@@ -101,7 +121,7 @@
where where
csu.del_flag = 0 csu.del_flag = 0
and csu.project_id = #{bo.projectId} and csu.project_id = #{bo.projectId}
and csu.cb_stage = #{bo.cbStage}
and csu.cb_type = #{bo.cbType} and csu.cb_type = #{bo.cbType}
and csu.level = #{bo.level} and csu.level = #{bo.level}
order by csu.sort order by csu.sort
......
...@@ -15,6 +15,22 @@ export function addProject (data) { ...@@ -15,6 +15,22 @@ export function addProject (data) {
data:data, data:data,
}) })
} }
//修改项目
export function editProjectInfo (data) {
return request({
url: '/cbProjectRecord/editProjectInfo',
method: 'PUT',
data:data,
})
}
//新增新阶段项目
export function addNewStageProject (data) {
return request({
url: '/cbProjectRecord/addNewStageProject',
method: 'POST',
data:data,
})
}
//获取当前项目文件上传 //获取当前项目文件上传
export function getProjectFileUploadDetail (projectId) { export function getProjectFileUploadDetail (projectId) {
return request({ return request({
...@@ -30,3 +46,35 @@ export function getDraftDialogList (projectId) { ...@@ -30,3 +46,35 @@ export function getDraftDialogList (projectId) {
method: 'get', method: 'get',
}) })
} }
//上传文件
export function uploadCbProjectFile (data) {
return request({
url: '/cbProjectFile/uploadCbProjectFile',
method: 'post',
data
})
}
//删除文件
export function deleteCbProjectFile (fileId) {
return request({
url: '/cbProjectFile/deleteCbProjectFile/'+fileId,
method: 'Delete',
})
}
//删除草稿
export function deleteDraft (projectId) {
return request({
url: '/cbProjectRecord/deleteDraft/'+projectId,
method: 'Delete',
})
}
//查询当前项目可删除成本阶段
export function getProjectCbStageNotDraft (relatedId) {
return request({
url: '/cbProjectRecord/getProjectCbStageNotDraft/'+relatedId,
method: 'get',
})
}
<template>
<div class="Tables" :class="{'is-empty-table' : !tableDataTotal}">
<div class="table-item">
<el-table v-if="tableDataTotal>0" class="fixed-table" :class="headerFixed ? 'headerFixed':''" v-loading="tableLoading" :data="tableData"
element-loading-text="Loading" ref="tableRef" v-horizontal-scroll="'hover'" border fit highlight-current-row :height="height"
:maxHeight="comMaxHeight" :default-sort="defaultSort?defaultSort:{}" @sort-change="sortChange">
<el-table-column v-if="isIndex" label="序号" :width="flexWidth(tableData)" align="left" :fixed="indexFixed" :resizable="false">
<template slot-scope="scope">{{ queryParams.pageNum * queryParams.pageSize - queryParams.pageSize + scope.$index + 1 }}</template>
</el-table-column>
<template>
<el-table-column v-for="(item,index) in forData" :key="index" :label="item.label" :prop="item.prop" :width="item.width"
:min-width="item.minWidth" :align="item.align?item.align:'left'" :fixed="item.fixed"
:sortable="item.sortable ?item.sortable=='custom'? 'custom':true : false" :show-overflow-tooltip="item.showOverflowTooltip"
:resizable="false">
<template v-if="item.children&&item.children.length">
<el-table-column v-for="(cld, i) in item.children" :key="i" :prop="cld.prop" :label="cld.label" :width="cld.width" :resizable="false">
<template slot-scope="cldscope">
<template v-if="cld.slot">
<slot :name="cld.prop" :row="cldscope.row" :data="cld"></slot>
</template>
<template v-else>
<span>{{cldscope.row[cld.prop] || '-'}}</span>
</template>
</template>
</el-table-column>
</template>
<template v-else-if="item.slotHeader" slot="header">
<slot :name="item.slotName"></slot>
</template>
<template slot-scope="scope">
<slot v-if="item.slot" :name="item.prop" :row="scope.row" :index="scope.$index" :data="item"></slot>
<span v-else>
{{ scope.row[item.prop] || '-' }}
</span>
</template>
</el-table-column>
</template>
<template slot="empty">
</template>
</el-table>
<div class="table-empty-container" v-else>
<no-data />
</div>
</div>
<div class="pagination-box" v-if="show_page && tableDataTotal>queryParams.pageSize">
<el-pagination background :current-page="current_page" :page-size="queryParams.pageSize" :total="tableDataTotal"
layout="prev, pager, next, jumper" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
</div>
</div>
</template>
<script>
import NoData from '../component/noData';
export default {
name: "Tables",
props: {
height: {
type: [String, Number]
},
maxHeight: {
type: Boolean
},
isIndex: {
type: Boolean,
default: true
},
headerFixed: {
type: Boolean,
default: false
},
indexFixed: {
type: Boolean,
default: false
},
tableLoading: {
type: Boolean,
default: false
},
defaultSort: {
type: Object,
default: null
},
tableData: {
type: Array,
default: []
},
forData: {
type: Array,
default: []
},
tableDataTotal: {
type: Number,
default: 0
},
queryParams: {
type: Object,
default: {}
},
paging: {
type: Boolean,
default: true
},
MaxPage: { //最大页码
type: Number,
default: 1000000
},
},
components: {
NoData
},
data() {
return {
current_page: this.queryParams.pageNum,
show_page: this.paging,
comMaxHeight: null
};
},
watch: {
'queryParams.pageNum'(newVal, oldVal) {
this.current_page = newVal;
}
},
created() {
this.maxHeight ? this.maxHeightInit() : null;
},
methods: {
// 自适应当前容器
async maxHeightInit() {
try {
await this.$nextTick();
/**
* @type {HTMLDivElement}
*/
const container = this.$el.querySelector(".table-item");
if (container) {
this.comMaxHeight = `${container.offsetHeight}px`;
}
} catch (error) {
}
},
handleCurrentChange(e) {
if (this.MaxPage < e) {
this.show_page = false;
this.$nextTick(() => {
this.current_page = this.queryParams.pageNum;
this.$message.warning(`对不起,最多只能访问${this.MaxPage}页`);
this.show_page = true;
});
} else {
this.$emit('handle-current-change', e);
}
},
handleSizeChange(e) {
this.$emit('handle-current-change', e);
},
sortChange(e) {
this.$emit('sort-change', e);
},
flexWidth(tableData) {
let currentMax = this.queryParams.pageNum * this.queryParams.pageSize - this.queryParams.pageSize + tableData.length, wdth = 59;
// return currentMax.toString().length*25 + 'px'
if (currentMax.toString().length > 3) {
wdth = wdth + (currentMax.toString().length - 3) * 10;
}
return wdth + 'px';
}
}
}
</script>
<style lang="scss" scoped>
.Tables {
::v-deep .el-table__body tr.current-row > td.el-table__cell {
background-color: #ffffff;
}
::v-deep .el-table__row {
&:nth-child(even) {
background-color: #f9fcff;
.more {
background: #f8fbff;
span {
color: #0081ff;
}
}
}
&:nth-child(odd) {
.more {
span {
color: #0081ff;
}
}
}
}
&.is-empty-table {
.table-item {
max-height: unset;
height: 100%;
}
}
::v-deep .table-item {
position: relative;
max-height: calc(100% - 56px);
.table-empty-container {
min-height: 360px;
display: flex;
height: 100%;
width: 100%;
align-items: center;
justify-content: center;
box-sizing: border-box;
.no-data {
min-height: unset;
}
}
.el-table td.el-table__cell {
border-bottom: 0;
}
.el-table {
.cell {
font-size: 14px;
}
.el-table__header-wrapper {
min-height: 40px;
}
}
.el-table--border th.gutter:last-of-type {
display: block !important;
padding-right: 16px;
}
}
::v-deep .el-table th.el-table__cell.is-leaf,
::v-deep .el-table td.el-table__cell {
border-bottom: 1px solid #e6eaf1;
}
::v-deep .el-table--border .el-table__cell {
border-right: 1px solid #e6eaf1;
}
::v-deep .el-table__body tr.hover-row.current-row > td,
::v-deep .el-table__body tr.hover-row.el-table__row--striped.current-row > td,
::v-deep .el-table__body tr.hover-row.el-table__row--striped > td,
::v-deep .el-table__body tr.hover-row > td {
background-color: #dcebff !important;
.more {
background: #dcebff;
}
}
::v-deep .el-table--enable-row-hover .el-table__body tr:hover > td {
background-color: #dcebff;
}
::v-deep .fixed-table {
overflow: visible;
}
::v-deep .el-table__header-wrapper {
position: sticky;
top: 0;
z-index: 9;
}
::v-deep .el-table__fixed-header-wrapper {
position: sticky;
z-index: 9;
top: 0;
}
.headerFixed {
::v-deep .el-table__header-wrapper {
position: sticky;
top: 80px;
z-index: 9;
}
::v-deep .el-table__fixed-header-wrapper {
position: sticky;
z-index: 9;
top: 80px;
}
}
::v-deep .el-table__fixed {
overflow-x: clip;
overflow-y: clip;
}
}
</style>
<template> <template>
<div class="detail-container"> <div class="directCost-container">
直接费成本 <div class="directCost-main">
<div class="search">
<el-select v-model="date" placeholder="请选择" clearable>
<el-option v-for="(item,index) in datelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select>
</div>
<div class="directCost-cont">
<div class="left">
<!--<div class="left-menu">-->
<!--<el-menu class="project-menu-instance">-->
<!--&lt;!&ndash;<el-submenu index="1" class="project-sub-menu-item">&ndash;&gt;-->
<!--&lt;!&ndash;<template slot="title">&ndash;&gt;-->
<!--&lt;!&ndash;<i class="el-icon-location icon"></i>&ndash;&gt;-->
<!--&lt;!&ndash;<span>宝安中学(集团)初中部改扩建工程施工总承包-加固修缮工程</span>&ndash;&gt;-->
<!--&lt;!&ndash;</template>&ndash;&gt;-->
<!--&lt;!&ndash;</el-submenu>&ndash;&gt;-->
<!--<template v-for="(el,index) in menuList">-->
<!--&lt;!&ndash; 一级标题无子菜单 &ndash;&gt;-->
<!--<el-menu-item v-if="!el.children" :index="el.path" :key="el.id">-->
<!--<template slot="title">-->
<!--<i class="el-icon-location icon"></i>-->
<!--<span>{{el.name}}</span>-->
<!--</template>-->
<!--</el-menu-item>-->
<!--&lt;!&ndash; 一级标题有子菜单 &ndash;&gt;-->
<!--<el-submenu v-else :index="'index' + index" :key="el.id" class="project-sub-menu-item">-->
<!--<template slot="title">-->
<!--<i class="el-icon-location icon"></i>-->
<!--<span>{{el.name}}</span>-->
<!--</template>-->
<!--&lt;!&ndash; 二级标题 &ndash;&gt;-->
<!--<el-menu-item :index="children.path" v-for="children in el.children" :key="children.id">-->
<!--{{children.name}}-->
<!--</el-menu-item>-->
<!--</el-submenu>-->
<!--</template>-->
<!--</el-menu>-->
<!--</div>-->
</div>
<div class="right-table">
<div class="table-item">
<el-table
element-loading-text="Loading"
:data="tableData"
:row-class-name="tableRowClassName"
row-key="id"
v-horizontal-scroll="'hover'"
default-expand-all
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
border
highlight-current-row
>
<el-table-column label="序号" width="60" align="left" prop="index"></el-table-column>
<el-table-column label="编码" width="130" prop="bm"></el-table-column>
<el-table-column label="名称" width="230" prop="mc"></el-table-column>
<el-table-column label="清单" width="130" prop="qd"></el-table-column>
<el-table-column label="项目特征" width="340" prop="xmtz"></el-table-column>
<el-table-column label="单位" width="130" prop="qd"></el-table-column>
<el-table-column label="计划成本" align="center">
<el-table-column prop="name" label="工程表达式" width="94"></el-table-column>
<el-table-column prop="name" label="工程量" width="66"></el-table-column>
<el-table-column prop="name" label="成本科目" width="80"></el-table-column>
<el-table-column prop="name" label="招标控制单价" width="108"></el-table-column>
<el-table-column prop="name" label="招标控制合价" width="108"></el-table-column>
<el-table-column prop="name" label="不含税成本单价" width="122"></el-table-column>
<el-table-column prop="name" label="不含税成本合计" width="122"></el-table-column>
<el-table-column prop="name" label="成本税金合计" width="108"></el-table-column>
<el-table-column prop="name" label="含税成本单价" width="108"></el-table-column>
<el-table-column prop="name" label="含税成本合价" width="108"></el-table-column>
<el-table-column prop="name" label="合价偏差" width="80"></el-table-column>
</el-table-column>
<el-table-column label="盈亏率" width="66" prop="qd"></el-table-column>
<el-table-column label="标准费用项" width="94" prop="qd"></el-table-column>
<el-table-column label="备注" width="114" prop="qd"></el-table-column>
<el-table-column label="操作" width="114" fixed="right">
<template slot-scope="scope" v-if="scope.row.qd ==='清'">
<span style="color:#0081FF;font-size: 14px;cursor: pointer;" @click="dialogVisible=true">增加费用项</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</div>
<el-dialog :visible.sync="dialogVisible" width="480px" append-to-body class="dialogVisible" title="增加费用项">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" class="addForm" label-width="107px">
<el-form-item label="编码" prop="str">
<el-input v-model="ruleForm.str" placeholder="请输入编码"></el-input>
</el-form-item>
<el-form-item label="项目名称" prop="mxmc">
<el-input v-model="ruleForm.mxmc" placeholder="请输入项目名称"></el-input>
</el-form-item>
<el-form-item label="计算规则" prop="jsgz">
<el-input v-model="ruleForm.jsgz" placeholder="请输入计算规则"></el-input>
</el-form-item>
<el-form-item label="单位" prop="dw">
<el-input v-model="ruleForm.dw" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="单价" prop="dj">
<el-input v-model="ruleForm.dj" placeholder="请输入单价"></el-input>
</el-form-item>
<el-form-item label="特征描述">
<el-input type="textarea" v-model="ruleForm.str" placeholder="请输入特征描述"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible=false">取消</el-button>
<el-button type="primary">确定增加</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import InfoTable from '../../../../component/infoTable';
export default { export default {
name: "directCost", name: "directCost",
components: {InfoTable}, components: {},
data() { data() {
return { return {
date:'2023年11月',
datelist:[
{
dictValue:'2023年11月',
dictLabel:'2023年11月',
},
{
dictValue:'2023年12月',
dictLabel:'2023年12月',
},
{
dictValue:'2024年1月',
dictLabel:'2024年1月',
}
],
tableData:[
{
bm:'010101002001',
mc:'挖一般土石方(开挖方式支撑下)1',
qd:'清',
id:1,
xmtz:'(1)不区分土石类别(含淤泥等),投标人综合考虑(2)开挖方式:综合考虑(3)挖土深度:综合考虑(4)开挖土石比例,投标人应结合地勘报告和岩面等高线综合考虑,施工中出现的实际土石比例变化,结算时不得调整(5)含装车等费用(6)具体详见招标文件、图纸及相关规范要求',
children:[
{
bm:'010101002001',
mc:'挖一般土石方(开挖方式支撑下2)',
qd:'专',
id:111,
xmtz:'(1)不区分土石类别(含淤泥等),投标人综合考虑(2)开挖方式:综合考虑(3)挖土深度:综合考虑(4)开挖土石比例,投标人应结合地勘报告和岩面等高线综合考虑,施工中出现的实际土石比例变化,结算时不得调整(5)含装车等费用(6)具体详见招标文件、图纸及相关规范要求',
},
{
bm:'010101002001',
mc:'挖一般土石方(开挖方式支撑下2)',
qd:'专',
id:122,
xmtz:'(1)不区分土石类别(含淤泥等),投标人综合考虑(2)开挖方式:综合考虑(3)挖土深度:综合考虑(4)开挖土石比例,投标人应结合地勘报告和岩面等高线综合考虑,施工中出现的实际土石比例变化,结算时不得调整(5)含装车等费用(6)具体详见招标文件、图纸及相关规范要求',
},
]
},
{
bm:'010101002001',
mc:'挖一般土石方(开挖方式支撑下)1',
qd:'清',
id:2,
xmtz:'(1)不区分土石类别(含淤泥等),投标人综合考虑(2)开挖方式:综合考虑(3)挖土深度:综合考虑(4)开挖土石比例,投标人应结合地勘报告和岩面等高线综合考虑,施工中出现的实际土石比例变化,结算时不得调整(5)含装车等费用(6)具体详见招标文件、图纸及相关规范要求',
children:[
{
bm:'010101002001',
mc:'挖一般土石方(开挖方式支撑下2)',
qd:'专',
id:11,
xmtz:'(1)不区分土石类别(含淤泥等),投标人综合考虑(2)开挖方式:综合考虑(3)挖土深度:综合考虑(4)开挖土石比例,投标人应结合地勘报告和岩面等高线综合考虑,施工中出现的实际土石比例变化,结算时不得调整(5)含装车等费用(6)具体详见招标文件、图纸及相关规范要求'
},
{
bm:'010101002001',
mc:'挖一般土石方(开挖方式支撑下2)',
qd:'专',
id:21,
xmtz:'(1)不区分土石类别(含淤泥等),投标人综合考虑(2)开挖方式:综合考虑(3)挖土深度:综合考虑(4)开挖土石比例,投标人应结合地勘报告和岩面等高线综合考虑,施工中出现的实际土石比例变化,结算时不得调整(5)含装车等费用(6)具体详见招标文件、图纸及相关规范要求'
},
]
},
],
queryParams:{
pageNum:1,
pageSize:10,
},
ruleForm:{
},
rules: {
str: { required: true, message: '编码不能为空', trigger: 'blur' }, // 限制必填
mxmc:{ required: true, message: '项目名称不能为空', trigger: 'blur' }, // 限制必填
jsgz:{ required: true, message: '计算规则不能为空', trigger: 'blur' }, // 限制必填
dw:{ required: true, message: '单位不能为空', trigger: 'blur' }, // 限制必填
dj:{ required: true, message: '单价不能为空', trigger: 'blur' }, // 限制必填
},
dialogVisible:false,
menuList:[
{
children: [
{
href: "暂无",
id: "2",
name: "测试2",
parentId: "1",
children: [
{
href: "暂无",
id: "3",
name: "测试3",
parentId: "2",
children: [
{
href: "暂无",
id: "4",
name: "测试4",
parentId: "3",
children: [],
},
],
},
],
},
],
id: "1",
name: "宝安中学(集团)初中部改扩建工程施工总承包-加固修缮工程",
parentId: "0",
},
],
}; };
}, },
//可访问data属性 //可访问data属性
created() { created() {
this.tableData.forEach((item,index)=>{
item.index=index+1
})
console.log(this.tableData)
const newData = [...this.tableData]; // 创建一个新的数组,避免修改原始数据
const totalRow = { bm: "增加费用项" }; // 合计行的数据
// 计算合计值
this.tableData.forEach(item => {
totalRow.column2 += item.column2;
totalRow.column3 += item.column3;
});
// 将合计行插入到正确的位置
newData.splice(1, 0, totalRow); // 假设将合计行插入到第二行的位置
// this.tableData=newData
},
mounted() {
}, },
//计算集 //计算集
...@@ -23,16 +262,128 @@ export default { ...@@ -23,16 +262,128 @@ export default {
}, },
//方法集 //方法集
methods: { methods: {
tableRowClassName({row, rowIndex}) {
if (row.qd === '清') {
return 'color1';
} else{
return 'color2';
}
return '';
},
}, },
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.detail-container { .directCost-container {
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
padding: 0 24px;
background: #ffffff; background: #ffffff;
height: 100%;
align-items: center;
.directCost-main{
width: 100%;
height: 100%;
overflow: hidden;
}
.search{
height: 64px;
border-bottom: 1px solid #EEEEEE;
::v-deep .el-select{
width: 140px;
height: 32px;
border-radius: 2px 2px 2px 2px;
margin: 16px;
.el-input--medium{
.el-input__inner{
height: 32px;
line-height: 32px;
}
.el-input__suffix{
top: 2px;
}
}
}
}
.directCost-cont{
display: flex;
height: 100%;
}
.left{
width: 220px;
height: 100%;
.left-menu{
width: 100%;
height: 100%;
overflow: auto;
::v-deep .project-menu-instance {
width: 100%;
height: 100%;
padding-top: 16px;
border-right: 1px solid #eeeeee;
overflow: auto;
.project-sub-menu-item {
& > .el-submenu__title,.el-menu-item {
height: 32px;
line-height: 32px;
&:hover {
background-color: unset;
background: linear-gradient( 91deg, rgba(0, 129, 255, 0.1) 0%, rgba(0, 129, 255, 0) 100%);
}
}
}
.is-opened{
.el-submenu__title{
color:#0081FF;
}
}
.el-submenu__title{
padding: 0 14px !important;
span{
width: 160px;
display: inline-block;
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 超出部分隐藏 */
text-overflow: ellipsis; /* 显示省略号 */
}
.icon{
width: 16px;
}
}
.el-submenu__icon-arrow{
right: 14px;
}
}
}
}
.right-table{
width: calc(100% - 220px);
height: 100%;
overflow: auto;
padding: 16px;
::v-deep .el-table{
.color1{
background: #FFF8E8;
}
.color2{
background: #FFFFFF;
}
}
}
}
.dialogVisible{
::v-deep .el-dialog {
.el-dialog__body{
padding:24px 20px 0 20px;
border-top: 1px solid #EEEEEE;
border-bottom: 1px solid #EEEEEE;
.el-input{
width: 320px !important;
}
}
.el-dialog__footer{
padding: 16px 20px;
}
}
} }
</style> </style>
<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"
>
<template slot="number" slot-scope="scope">
<div>{{scope.row.number || '--'}}</div>
</template>
<template slot="proportion" slot-scope="scope">
<div>{{scope.row.proportion || '--'}}{{scope.row.proportion ? '%':''}}</div>
</template>
</tables>
</div>
</div>
</div>
</div>
</template>
<script>
import Tables from "../../../../component/Tables"
export default {
name: "directCost",
components: {
Tables,
},
data() {
return {
data:[
{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}
],
defaultProps: {
children: 'children',
label: 'label'
},
isSkeleton:false,
tableLoading:false,
tableData:[
{
name:'技术质量管理类',
number:'236',
proportion:'64'
},
{
name:'工程保险类',
number:'336',
proportion:'64'
},
],
forData: [
{label: '其他项目费用', prop: 'name'},
{label: '数量', prop: 'number',slot: true},
{label: '占比', prop: 'proportion', slot: true},
],
forData1: [
{label: '清单内容', prop: 'name',minWidth:'215'},
{label: '工作内容、做法/规格型号/施工现场配置说明', prop: 'number',minWidth:'302'},
{label: '单位', prop: 'proportion',minWidth:'215'},
{label: '不含税单价', prop: 'proportion',minWidth:'215'},
{label: '不含税合价', prop: 'proportion',minWidth:'215'},
{label: '税率(%)', prop: 'proportion',minWidth:'215'},
{label: '含税合价', prop: 'proportion',minWidth:'215'},
{label: '税金(元)', prop: 'proportion',minWidth:'215'},
{label: '成本科目', prop: 'proportion',minWidth:'215'},
{label: '税金类型', prop: 'proportion',minWidth:'215'},
{label: '备注', prop: 'proportion',minWidth:'215'},
],
queryParams:{
pageNum:1,
pageSize:10,
},
tableDataTotal:2,
};
},
//可访问data属性
created() {
},
//计算集
computed: {
},
//方法集
methods: {
handleNodeClick(data) {
console.log(data);
},
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
//分页
handleCurrentChange(e){
let params = this.formParams()
params.pageNum = e
this.queryParams.pageNum = e
// this.handleQuery(params)
},
sortChange(){
}
},
}
</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>
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
<!-- 工料汇总 --> <!-- 工料汇总 -->
<feed-summary v-if="current == 'feedSummary'"></feed-summary> <feed-summary v-if="current == 'feedSummary'"></feed-summary>
<!-- 其他项目 -->
<other-projects v-if="current == 'otherItems'"></other-projects>
</div> </div>
</div> </div>
</div> </div>
...@@ -30,6 +33,8 @@ import EngineeringInformation from "@/views/projectCostLedger/detail/components/ ...@@ -30,6 +33,8 @@ import EngineeringInformation from "@/views/projectCostLedger/detail/components/
import DirectCost from "@/views/projectCostLedger/detail/components/DirectCost"; import DirectCost from "@/views/projectCostLedger/detail/components/DirectCost";
// 工料汇总 // 工料汇总
import FeedSummary from "@/views/projectCostLedger/detail/components/FeedSummary"; import FeedSummary from "@/views/projectCostLedger/detail/components/FeedSummary";
// 其他项目
import OtherProjects from "@/views/projectCostLedger/detail/components/OtherProjects";
import { v4 } from "uuid"; import { v4 } from "uuid";
import { cloneDeep } from "lodash-es"; import { cloneDeep } from "lodash-es";
export default { export default {
...@@ -39,7 +44,8 @@ export default { ...@@ -39,7 +44,8 @@ export default {
DskTabToggle, DskTabToggle,
FeedSummary, FeedSummary,
EngineeringInformation, EngineeringInformation,
DirectCost DirectCost,
OtherProjects
}, },
data() { data() {
return { return {
......
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
<el-input v-model="formdata.customerName" placeholder="请输入IPM项目编码" clearable></el-input> <el-input v-model="formdata.customerName" placeholder="请输入IPM项目编码" clearable></el-input>
</el-form-item> </el-form-item>
<el-form-item label="成本阶段"> <el-form-item label="成本阶段">
<el-select v-model="formdata.customerClass" multiple placeholder="请选择" :collapse-tags="true" clearable> <el-select v-model="formdata.customerClass" placeholder="请选择" :collapse-tags="true" clearable>
<el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option> <el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="项目状态"> <el-form-item label="项目状态">
<el-select v-model="formdata.customerClass" multiple placeholder="请选择" :collapse-tags="true" clearable> <el-select v-model="formdata.customerClass" placeholder="请选择" :collapse-tags="true" clearable>
<el-option v-for="(item,index) in ztStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option> <el-option v-for="(item,index) in ztStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
...@@ -64,19 +64,19 @@ ...@@ -64,19 +64,19 @@
<el-table-column label="工程名称" width="416" :resizable="false"> <el-table-column label="工程名称" width="416" :resizable="false">
<template slot-scope="scope"> <template slot-scope="scope">
<div style="display:flex;align-items:center"> <div style="display:flex;align-items:center">
<el-tooltip placement="top" v-if="scope.row.customerText.length>20"> <!--<el-tooltip placement="top" v-if="scope.row.customerText.length>20">-->
<div slot="content">{{scope.row.customerText}}</div> <!--<div slot="content">{{scope.row.customerText}}</div>-->
<div class="renling"> <!--<div class="renling">-->
<router-link v-if="scope.row.companyId" :to="`/enterprise/${encodeStr(scope.row.companyId)}?path=cooperationRecord&companyName=${scope.row.customerName}`" tag="a" <!--<router-link v-if="scope.row.companyId" :to="`/enterprise/${encodeStr(scope.row.companyId)}?path=cooperationRecord&companyName=${scope.row.customerName}`" tag="a"-->
class="wordprimary" v-html="scope.row.customerName"></router-link> <!--class="wordprimary" v-html="scope.row.customerName"></router-link>-->
<span v-else v-html="scope.row.customerName"></span> <!--<span v-else v-html="scope.row.customerName"></span>-->
</div> <!--</div>-->
</el-tooltip> <!--</el-tooltip>-->
<div class="renling" v-else> <!--<div class="renling" v-else>-->
<router-link v-if="scope.row.companyId" :to="`/enterprise/${encodeStr(scope.row.companyId)}?path=cooperationRecord&companyName=${scope.row.customerName}`" tag="a" <!--<router-link v-if="scope.row.companyId" :to="`/enterprise/${encodeStr(scope.row.companyId)}?path=cooperationRecord&companyName=${scope.row.customerName}`" tag="a"-->
class="wordprimary" v-html="scope.row.customerName"></router-link> <!--class="wordprimary" v-html="scope.row.customerName"></router-link>-->
<span v-else v-html="scope.row.customerName"></span> <!--<span v-else v-html="scope.row.customerName"></span>-->
</div> <!--</div>-->
</div> </div>
</template> </template>
...@@ -107,9 +107,9 @@ ...@@ -107,9 +107,9 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" min-width="256" :resizable="false" fixed="right"> <el-table-column label="操作" min-width="256" :resizable="false" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<span class="wordprimary tabs" @click="goAccess(scope.row)">修改项目信息</span> <span class="wordprimary tabs" @click="editpro(scope.row)">修改项目信息</span>
<span class="wordprimary tabs" @click="goAssessment(scope.row)">查看导入进度</span> <span class="wordprimary tabs" @click="detailpro(scope.row)">查看导入进度</span>
<span class="worddel tabs" @click="goDisposal(scope.row)">删除</span> <span class="worddel tabs" @click="deleetpro(scope.row)">删除</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -121,6 +121,24 @@ ...@@ -121,6 +121,24 @@
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
<el-dialog title="删除项目" :visible.sync="deletevisible" width="480px" custom-class='dialog-supplier'>
<el-divider></el-divider>
<div class="protypes">
<div class="ck" v-if="typenum>1">项目台账共有3个阶段</div>
<div class="ck" v-else>是否删除此项目?删除后无法返回。</div>
<div class="ck"><el-checkbox :indeterminate="indeterminate" v-model="checkAll" @change="handleCheckAllChange">删除全部</el-checkbox></div>
<el-checkbox-group v-model="checkds" @change="handleCheck">
<div class="ck" v-for="(item,index) in allchecks">
<el-checkbox :key="index" :label="item.label">{{item.text}}</el-checkbox>
</div>
</el-checkbox-group>
</div>
<el-divider></el-divider>
<div style="padding: 16px 20px 24px;text-align: right">
<el-button size="small" @click="deletevisible = false">取消</el-button>
<el-button type="primary" size="small" @click="getDelete">确定删除</el-button>
</div>
</el-dialog>
<el-dialog <el-dialog
class="pro-news" class="pro-news"
:visible.sync="dialogVisible" :visible.sync="dialogVisible"
...@@ -141,19 +159,22 @@ ...@@ -141,19 +159,22 @@
<el-input type="text" placeholder="请输入文件名称" v-model="queryParam.projectFileName"></el-input> <el-input type="text" placeholder="请输入文件名称" v-model="queryParam.projectFileName"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="成本阶段" class="row" prop="cbStage"> <el-form-item label="成本阶段" class="row" prop="cbStage">
<el-select placeholder="请选择成本阶段" v-model="queryParam.cbStage"> <el-checkbox v-model="ischeck" v-if="isedit" class="checkcb"></el-checkbox>
<el-select placeholder="请选择成本阶段" v-model="queryParam.cbStage" :disabled="!ischeck">
<el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option> <el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form > </el-form >
<div class="popbot"> <div class="popbot">
<div class="btn btn_cancel h32" @click="dialogVisible = false">取消</div> <div class="btn btn_cancel h32" @click="dialogVisible = false">取消</div>
<div class="btn btn_primary h32" @click="insertPro" :class="{'btn_disabled':!queryParam.cbStage}" :disabled="!queryParam.cbStage">下一步,导入数据</div> <div class="btn btn_primary h32" v-if="isedit && !ischeck" @click="savepro">保存</div>
<div class="btn btn_primary h32" v-if="isedit && ischeck" @click="changepro">下一步,导入数据</div>
<div class="btn btn_primary h32" v-if="!isedit && !ischeck" @click="insertPro" :class="{'btn_disabled':!queryParam.cbStage}" :disabled="!queryParam.cbStage">下一步,导入数据</div>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
<proupload v-if="isupload" :uploadData=uploadData></proupload> <proupload v-if="isupload" :uploadData="uploadData" :cbStagelist="cbStagelist" :prodetail="prodetail" @closeupload="colsepro"></proupload>
<el-dialog title="草稿箱" :visible.sync="cgxVisible" width="960px" custom-class='dialog-supplier'> <el-dialog title="草稿箱" :visible.sync="cgxVisible" width="960px" custom-class='dialog-supplier'>
<el-divider></el-divider> <el-divider></el-divider>
...@@ -176,7 +197,7 @@ ...@@ -176,7 +197,7 @@
</el-table-column> </el-table-column>
<el-table-column label="成本阶段" width="105px"> <el-table-column label="成本阶段" width="105px">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-for="item in cbStagelist"> <div v-for="(item,index) in cbStagelist" :key="index+11">
<span v-if="scope.row.cbStage == item.dictValue">{{item.dictLabel}}</span> <span v-if="scope.row.cbStage == item.dictValue">{{item.dictLabel}}</span>
</div> </div>
</template> </template>
...@@ -189,14 +210,14 @@ ...@@ -189,14 +210,14 @@
<el-table-column label="操作"> <el-table-column label="操作">
<template slot-scope="scope"> <template slot-scope="scope">
<span class="wordprimary" @click="jxbj(scope.row)">继续编辑</span> <span class="wordprimary" @click="jxbj(scope.row)">继续编辑</span>
<span class="worddel">删除</span> <span class="worddel" @click="deletecg(scope.row.id)">删除</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div class="pagination clearfix" v-show="total>formdata.pageSize"> <div class="pagination clearfix" v-show="total>cgPagesize">
<el-pagination background :page-size="formdata.pageSize" :current-page.sync="formdata.pageNum" <el-pagination background :page-size="cgPagesize" :current-page.sync="cgPagenum"
@current-change="handleCurrentChange" layout="prev, pager, next" @current-change="getCGXlist" layout="prev, pager, next"
:total="cgxtotal"> :total="cgxtotal">
</el-pagination> </el-pagination>
</div> </div>
...@@ -206,7 +227,14 @@ ...@@ -206,7 +227,14 @@
</template> </template>
<script> <script>
import '@/assets/styles/public.scss' import '@/assets/styles/public.scss'
import { checkProjectCodeExist,addProject,getDraftDialogList } from '@/api/projectCostLedger/index' import {
addNewStageProject,
addProject,
checkProjectCodeExist,
deleteDraft,
editProjectInfo,
getDraftDialogList,getProjectCbStageNotDraft
} from '@/api/projectCostLedger/index'
import { getDicts } from '@/api/system/dict/data' import { getDicts } from '@/api/system/dict/data'
import proupload from '@/views/projectCostLedger/upload/index' import proupload from '@/views/projectCostLedger/upload/index'
import skeleton from '@/views/project/projectList/component/skeleton' import skeleton from '@/views/project/projectList/component/skeleton'
...@@ -216,6 +244,7 @@ ...@@ -216,6 +244,7 @@
components:{proupload,skeleton}, components:{proupload,skeleton},
data() { data() {
return { return {
typenum:2,
formdata:{}, formdata:{},
isSkeleton:false, isSkeleton:false,
total:10, total:10,
...@@ -235,12 +264,24 @@ ...@@ -235,12 +264,24 @@
cbStage:[{ required: true, message: '请选择成本阶段!', trigger: 'blur' },], cbStage:[{ required: true, message: '请选择成本阶段!', trigger: 'blur' },],
}, },
isupload:false, isupload:false,
tableData:[], tableData:[{}],
cgxVisible:false, cgxVisible:false,
cgxSkeleton:false, cgxSkeleton:false,
cgxtotal:0, cgxtotal:0,
cgxlist:[], cgxlist:[],
uploadData:{},//新增项目返回的数据 uploadData:{
cbStage:0,
},//新增项目返回的数据
cgPagesize:10,
cgPagenum:1,
prodetail:false,
isedit:false,//是否修改项目
ischeck:false,//是否可选
deletevisible:false,
indeterminate:false,//半选状态
checkAll:false,
checkds:[],
allchecks:[],//可以用的项目阶段
}; };
}, },
//可访问data属性 //可访问data属性
...@@ -256,6 +297,8 @@ ...@@ -256,6 +297,8 @@
}) })
//获取草稿箱 //获取草稿箱
this.getCGXlist() this.getCGXlist()
//获取列表
this.getlist()
}, },
//计算集 //计算集
computed: { computed: {
...@@ -263,7 +306,79 @@ ...@@ -263,7 +306,79 @@
}, },
//方法集 //方法集
methods: { methods: {
getlist(){
},
handleCheckAllChange(val){
this.checkAll = val
this.checkds = []
if(val == true){
this.allchecks.forEach(item=>{
this.checkds.push(item.label)
})
}
this.indeterminate = false
},
handleCheck(){
if(this.checkds.length == this.typenum){
this.checkAll = true
}else{
this.checkAll = false
}
this.indeterminate = this.checkds.length > 0 && this.checkds.length < this.typenum
},
//修改项目
editpro(row){
this.isedit = true
this.ischeck = false
this.prodetail = false
this.dialogVisible = true
this.queryParam = {}
this.queryParam = [...this.queryParam,...row]
this.protitle = '修改项目信息'
},
//查看进度
detailpro(row){
this.uploadData = row
this.uploadData.id = this.uploadData.projectId
this.prodetail = true
},
//删除项目
deleetpro(row){
this.deletevisible = true
this.prodetail = false
getProjectCbStageNotDraft(row.relatedId).then(res=>{
let list = res.data
let cb = this.cbStagelist
let datas = []
list.forEach(item =>{
cb.for(i=>{
if(item.dictValue == i){
let arr = {'label':i,'text':item.dictLabel}
datas.push(arr)
}
})
})
this.allchecks = datas
this.typenum = list.length
this.checkds = []
})
},
getDelete(){
// this.checkds 勾选了要删除的数据
this.getlist()
},
//返回列表
colsepro(){
this.isupload = false
this.getCGXlist()
this.getlist()
},
addPro(){ addPro(){
this.ischeck = true
this.isedit = false
this.dialogVisible = true this.dialogVisible = true
this.queryParam = { this.queryParam = {
projectName: '',//项目名称 projectName: '',//项目名称
...@@ -276,7 +391,8 @@ ...@@ -276,7 +391,8 @@
}, },
getSearch(){ getSearch(){
this.formdata.pageNum = 1 this.formdata.pageNum = 1
// this.customerAll()
this.getlist()
}, },
getipmProjectNo(){ getipmProjectNo(){
//点击且校验了当前编码有数据才获取 //点击且校验了当前编码有数据才获取
...@@ -315,10 +431,25 @@ ...@@ -315,10 +431,25 @@
} }
}) })
}, },
//修改项目
savepro(){
editProjectInfo(JSON.stringify(this.queryParam)).then(res=>{
if(res.code == 200){
this.dialogVisible = false
this.getlist()
}
})
},
//修改阶段
changepro(){
addNewStageProject(JSON.parse(JSON.stringify(this.queryParam))).then(res=>{
this.uploadData = res.data
this.uploadData.id = this.uploadData.projectId
this.isupload = true
})
},
//继续编辑 //继续编辑
jxbj(data){ jxbj(data){
console.log(this.cgxlist)
console.log(data)
this.uploadData = data this.uploadData = data
this.isupload = true this.isupload = true
this.cgxVisible = false this.cgxVisible = false
...@@ -339,18 +470,47 @@ ...@@ -339,18 +470,47 @@
return "enterprise-name-row"; return "enterprise-name-row";
}, },
getcgx(){ getcgx(){
this.getCGXlist() if(this.cgxtotal>0){
this.getCGXlist(1)
this.cgxVisible = true this.cgxVisible = true
}
}, },
getCGXlist(){ getCGXlist(page){
this.cgxSkeleton = true this.cgxSkeleton = true
getDraftDialogList().then(res=>{ this.cgPagenum = page
this.cgxtotal = res.data.length let param = {
this.cgxlist = res.data pageSize: this.cgPagesize,
pageNum: this.cgPagenum
}
getDraftDialogList(param).then(res=>{
this.cgxtotal = res.total
this.cgxlist = res.rows
this.cgPagenum = res.currentPage
this.cgxSkeleton = false this.cgxSkeleton = false
}) })
},
deletecg(id){
this.$confirm('是否确定删除此项目,删除后无法找回。', '提示', {
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteDraft(id).then(res=>{
if(res.code == 200){
this.$message({
type: 'success',
message: '删除成功!'
});
this.getCGXlist(1)
} }
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
}, },
} }
</script> </script>
...@@ -455,7 +615,10 @@ ...@@ -455,7 +615,10 @@
.row { .row {
margin-bottom: 16px; margin-bottom: 16px;
position: relative; position: relative;
.checkcb{
position: absolute;
left: -100px;
}
.el-form-item__label { .el-form-item__label {
font-weight: 400; font-weight: 400;
opacity: 0.8; opacity: 0.8;
...@@ -575,8 +738,29 @@ ...@@ -575,8 +738,29 @@
padding: 0; padding: 0;
} }
} }
.wordprimary{
margin-left: 12px;
}
.worddel{ .worddel{
color: #FA5351; color: #FA5351;
padding-left: 12px; padding-left: 12px;
cursor: pointer;
} }
.pagination{
padding-top: 16px;
text-align: right;
}
.protypes{
padding: 24px 20px;
.ck{
margin-bottom: 12px;
height: 22px;
font-size: 14px;
color: rgba(35,35,35,0.8);
line-height: 22px;
&:last-child{
margin-bottom: 0;
}
}
}
</style> </style>
<template> <template>
<div class="project-cost-ledger-inner"> <div class="project-cost-ledger-inner">
<el-upload
ref="uploadpro"
class="upload-demo"
:multiple="true"
accept=".xls,.xlsx"
action=""
drag
:auto-upload="false"
:on-change="handleFileListChange"
:headers="headers">
</el-upload>
<div class="pro-upload"> <div class="pro-upload">
<div class="title_wrap i"> <div class="title_wrap i">
<div class="title-small"><span>项目成本台账 <i class="el-icon-arrow-right"></i> </span>导入项目</div> <div class="title-small"><span>项目成本台账 <i class="el-icon-arrow-right"></i> </span>导入项目</div>
...@@ -11,7 +23,7 @@ ...@@ -11,7 +23,7 @@
<el-form :model="formdata" label-width="82px" :rules="rules" label-position="right" :inline="true"> <el-form :model="formdata" label-width="82px" :rules="rules" label-position="right" :inline="true">
<el-row> <el-row>
<el-form-item label="项目名称"> <el-form-item label="项目名称">
<el-input v-model="formdata.customerName" disabled placeholder="请输入工程名称" clearable></el-input> <el-input v-model="formdata.projectName" disabled placeholder="请输入工程名称" clearable></el-input>
</el-form-item> </el-form-item>
<el-form-item label="IPM项目编码" label-width="100px"> <el-form-item label="IPM项目编码" label-width="100px">
<el-input v-model="formdata.ipmProjectNo" disabled placeholder="请输入IPM项目编码" clearable></el-input> <el-input v-model="formdata.ipmProjectNo" disabled placeholder="请输入IPM项目编码" clearable></el-input>
...@@ -20,7 +32,7 @@ ...@@ -20,7 +32,7 @@
<el-input v-model="formdata.projectFileName" disabled placeholder="请输入文件名称" clearable></el-input> <el-input v-model="formdata.projectFileName" disabled placeholder="请输入文件名称" clearable></el-input>
</el-form-item> </el-form-item>
<el-form-item label="成本阶段" prop="cbStage"> <el-form-item label="成本阶段" prop="cbStage">
<el-select v-model="formdata.cbStage" disabled multiple placeholder="请选择" :collapse-tags="true" <el-select v-model="formdata.cbStage" disabled placeholder="请选择" :collapse-tags="true"
clearable> clearable>
<el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" <el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue"
:key="index"></el-option> :key="index"></el-option>
...@@ -39,152 +51,168 @@ ...@@ -39,152 +51,168 @@
<el-row> <el-row>
<el-form-item label="直接费成本" prop="zjfcb"> <el-form-item label="直接费成本" prop="zjfcb">
<div class="filelist"> <div class="filelist">
<div class="fileli"> <div class="fileli" v-for="(item,index) in directExpense">
<div> <div>
<img src="../../../assets/images/icon_wrapper.png"> <img src="../../../assets/images/icon_wrapper.png">
<div class="name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)-加固修缮工程.xls</div> <div class="name">{{item.fileName}}</div>
<div class="prostatus i1">解析成功</div> <template v-if="item.fileParseStatus">
<div class="cz"> <div class="prostatus i2" v-if="item.fileParseStatus == 1">解析中</div>
<div>重新上传</div> <div class="prostatus i1" v-if="item.fileParseStatus == 2">解析成功</div>
<div>删除</div> <div class="prostatus i3" v-if="item.fileParseStatus == 3">解析失败</div>
</div> </template>
<div class="cz" v-if="item.fileParseStatus != 1">
<div v-if="item.fileParseStatus != 3"><a :href="item.fileOssUrl">下载</a></div>
<div v-if="item.fileParseStatus == 3 && prodetail == false">重新上传</div>
<div class="i" @click="deletefille(item.id)" v-if="prodetail == false">删除</div>
</div> </div>
<div class="wrong">
失败原因:解析失败的原因展示
</div> </div>
<div class="wrong" v-if="item.fileParseStatus&&item.fileParseStatus == 3">
失败原因:{{item.failRemark||'--'}}
</div> </div>
<div class="fileli">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)-加固修缮工程.xls</div>
<div class="prostatus i2">解析中</div>
<div class="cz">
<div>重新上传</div>
<div>删除</div>
</div> </div>
</div> </div>
<div class="upload">
<el-button class="uploadpro" @click="uplpro(0)"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
</div> </div>
<div class="fileli"> </el-form-item>
</el-row>
<el-row>
<el-form-item label="工料汇总" prop="glhz">
<div class="filelist">
<div class="fileli" v-for="(item,index) in quantitySummary">
<div> <div>
<img src="../../../assets/images/icon_wrapper.png"> <img src="../../../assets/images/icon_wrapper.png">
<div class="name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)-加固修缮工程.xls</div> <div class="name">{{item.fileName}}</div>
<div class="prostatus i3">解析失败</div> <template v-if="item.fileParseStatus">
<div class="cz"> <div class="prostatus i2" v-if="item.fileParseStatus == 1">解析中</div>
<div>重新上传</div> <div class="prostatus i1" v-if="item.fileParseStatus == 2">解析成功</div>
<div>删除</div> <div class="prostatus i3" v-if="item.fileParseStatus == 3">解析失败</div>
</template>
<div class="cz" v-if="item.fileParseStatus != 1">
<div v-if="item.fileParseStatus != 3"><a :href="item.fileOssUrl">下载</a></div>
<div v-if="item.fileParseStatus == 3 && prodetail == false">重新上传</div>
<div class="i" @click="deletefille(item.id)" v-if="prodetail == false">删除</div>
</div> </div>
</div> </div>
<div class="wrong" v-if="item.fileParseStatus&&item.fileParseStatus == 3">
失败原因:{{item.failRemark||'--'}}
</div> </div>
</div> </div>
<div class="upload">
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button class="uploadpro"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
<!--<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>-->
</el-upload>
</div> </div>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="工料汇总" prop="glhz">
<div class="upload"> <div class="upload">
<el-upload <el-button class="uploadpro" @click="uplpro(1)"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button class="uploadpro"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
<!--<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>-->
</el-upload>
</div> </div>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<el-form-item label="措施项目" prop="csxm"> <el-form-item label="措施项目" prop="csxm">
<div class="filelist">
<div class="fileli" v-for="(item,index) in measureProject">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">{{item.fileName}}</div>
<template v-if="item.fileParseStatus">
<div class="prostatus i2" v-if="item.fileParseStatus == 1">解析中</div>
<div class="prostatus i1" v-if="item.fileParseStatus == 2">解析成功</div>
<div class="prostatus i3" v-if="item.fileParseStatus == 3">解析失败</div>
</template>
<div class="cz" v-if="item.fileParseStatus != 1">
<div v-if="item.fileParseStatus != 3"><a :href="item.fileOssUrl">下载</a></div>
<div v-if="item.fileParseStatus == 3 && prodetail == false">重新上传</div>
<div class="i" @click="deletefille(item.id)" v-if="prodetail == false">删除</div>
</div>
</div>
<div class="wrong" v-if="item.fileParseStatus&&item.fileParseStatus == 3">
失败原因:{{item.failRemark||'--'}}
</div>
</div>
</div>
<div class="upload"> <div class="upload">
<el-upload <el-button class="uploadpro" @click="uplpro(2)"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button class="uploadpro"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
<!--<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>-->
</el-upload>
</div> </div>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<el-form-item label="其他项目" prop="qtxm"> <el-form-item label="其他项目" prop="qtxm">
<div class="filelist">
<div class="fileli" v-for="(item,index) in otherProject">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">{{item.fileName}}</div>
<template v-if="item.fileParseStatus">
<div class="prostatus i2" v-if="item.fileParseStatus == 1">解析中</div>
<div class="prostatus i1" v-if="item.fileParseStatus == 2">解析成功</div>
<div class="prostatus i3" v-if="item.fileParseStatus == 3">解析失败</div>
</template>
<div class="cz" v-if="item.fileParseStatus != 1">
<div v-if="item.fileParseStatus != 3"><a :href="item.fileOssUrl">下载</a></div>
<div v-if="item.fileParseStatus == 3 && prodetail == false">重新上传</div>
<div class="i" @click="deletefille(item.id)" v-if="prodetail == false">删除</div>
</div>
</div>
<div class="wrong" v-if="item.fileParseStatus&&item.fileParseStatus == 3">
失败原因:{{item.failRemark||'--'}}
</div>
</div>
</div>
<div class="upload"> <div class="upload">
<el-upload <el-button class="uploadpro" @click="uplpro(3)"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button class="uploadpro"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
<!--<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>-->
</el-upload>
</div> </div>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<el-form-item label="现场经费" prop="xcjf"> <el-form-item label="现场经费" prop="xcjf">
<div class="filelist">
<div class="fileli" v-for="(item,index) in sceneExpense">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">{{item.fileName}}</div>
<template v-if="item.fileParseStatus">
<div class="prostatus i2" v-if="item.fileParseStatus == 1">解析中</div>
<div class="prostatus i1" v-if="item.fileParseStatus == 2">解析成功</div>
<div class="prostatus i3" v-if="item.fileParseStatus == 3">解析失败</div>
</template>
<div class="cz" v-if="item.fileParseStatus != 1">
<div v-if="item.fileParseStatus != 3"><a :href="item.fileOssUrl">下载</a></div>
<div v-if="item.fileParseStatus == 3 && prodetail == false">重新上传</div>
<div class="i" @click="deletefille(item.id)" v-if="prodetail == false">删除</div>
</div>
</div>
<div class="wrong" v-if="item.fileParseStatus&&item.fileParseStatus == 3">
失败原因:{{item.failRemark||'--'}}
</div>
</div>
</div>
<div class="upload"> <div class="upload">
<el-upload <el-button class="uploadpro" @click="uplpro(4)"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button class="uploadpro"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
<!--<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>-->
</el-upload>
</div> </div>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row> <el-row>
<el-form-item label="成本汇总" prop="cbhz"> <el-form-item label="成本汇总" prop="cbhz">
<div class="filelist">
<div class="fileli" v-for="(item,index) in cbSummary">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">{{item.fileName}}</div>
<template v-if="item.fileParseStatus">
<div class="prostatus i2" v-if="item.fileParseStatus == 1">解析中</div>
<div class="prostatus i1" v-if="item.fileParseStatus == 2">解析成功</div>
<div class="prostatus i3" v-if="item.fileParseStatus == 3">解析失败</div>
</template>
<div class="cz" v-if="item.fileParseStatus != 1">
<div v-if="item.fileParseStatus != 3"><a :href="item.fileOssUrl">下载</a></div>
<div v-if="item.fileParseStatus == 3 && prodetail == false">重新上传</div>
<div class="i" @click="deletefille(item.id)" v-if="prodetail == false">删除</div>
</div>
</div>
<div class="wrong" v-if="item.fileParseStatus&&item.fileParseStatus == 3">
失败原因:{{item.failRemark||'--'}}
</div>
</div>
</div>
<div class="upload"> <div class="upload">
<el-upload <el-button class="uploadpro" @click="uplpro(5)"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button class="uploadpro"><img src="../../../assets/images/tips-plus.png">上传文件</el-button>
<!--<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>-->
</el-upload>
</div> </div>
</el-form-item> </el-form-item>
</el-row> </el-row>
...@@ -193,7 +221,7 @@ ...@@ -193,7 +221,7 @@
<el-divider></el-divider> <el-divider></el-divider>
<div class="pro-btns"> <div class="pro-btns">
<el-button type="primary" size="small" >导入数据</el-button> <el-button type="primary" size="small" >导入数据</el-button>
<el-button size="small">返回</el-button> <el-button size="small" @click="goback">返回</el-button>
</div> </div>
</div> </div>
...@@ -201,18 +229,25 @@ ...@@ -201,18 +229,25 @@
</template> </template>
<script> <script>
import { getDicts } from '@/api/system/dict/data' import { getToken } from '@/utils/auth'
import { getProjectFileUploadDetail } from '@/api/projectCostLedger/index' // import { getDicts } from '@/api/system/dict/data'
import { deleteCbProjectFile, getProjectFileUploadDetail, uploadCbProjectFile } from '@/api/projectCostLedger/index'
export default { export default {
name: 'upload', name: 'upload',
props:{uploadData:null}, props: {
uploadData: Object,
cbStagelist: Array,
prodetail: Boolean,//是否是查看 true 不可编辑 false 可编辑
},
data(){ data(){
return{ return{
formdata:{ formdata:{
cbStage:null, cbStage:"",
},
headers: {
Authorization: "Bearer " + getToken(),
}, },
cbStagelist:[],
rules:{ rules:{
cbStage:[{ required: true, message: '请选择成本阶段!', trigger: 'blur' },], cbStage:[{ required: true, message: '请选择成本阶段!', trigger: 'blur' },],
}, },
...@@ -225,57 +260,127 @@ ...@@ -225,57 +260,127 @@
xcjf:[{ required: true, trigger: 'blur' },], xcjf:[{ required: true, trigger: 'blur' },],
cbhz:[{ required: true, trigger: 'blur' },], cbhz:[{ required: true, trigger: 'blur' },],
}, },
fileList:[],
//各个类型数据集
directExpense:[], directExpense:[],
quantitySummary:[], quantitySummary:[],
measureProject:[], measureProject:[],
otherProject:[], otherProject:[],
sceneExpense:[], sceneExpense:[],
cbSummary:[], cbSummary:[],
uploadtype:0,//上传的版块类型
} }
}, },
created() { created() {
//成本阶段 this.formdata = JSON.parse(JSON.stringify(this.uploadData))
getDicts('pro_cbstage').then(res => { this.formdata.cbStage = this.formdata.cbStage.toString()
this.cbStagelist = res.data this.getDetail()
}) },
getProjectFileUploadDetail(this.uploadData.id).then(res=>{ methods:{
if(res.code == 200){ goback(){
if(res.data){ this.$emit('closeupload')
this.directExpense=res.data.directExpense },
this.quantitySummary=res.data.quantitySummary getDetail(){
this.measureProject=res.data.measureProject
this.otherProject=res.data.otherProject
this.sceneExpense=res.data.sceneExpense
this.cbSummary=res.data.cbSummary
}else{
this.directExpense=[] this.directExpense=[]
this.quantitySummary=[] this.quantitySummary=[]
this.measureProject=[] this.measureProject=[]
this.otherProject=[] this.otherProject=[]
this.sceneExpense=[] this.sceneExpense=[]
this.cbSummary=[] this.cbSummary=[]
getProjectFileUploadDetail(this.uploadData.id).then(res=>{
if(res.code == 200){
if(res.data){
this.directExpense = [...this.directExpense,...res.data.directExpense]
this.quantitySummary = [...this.quantitySummary,...res.data.quantitySummary]
this.measureProject = [...this.measureProject,...res.data.measureProject]
this.otherProject = [...this.otherProject,...res.data.otherProject]
this.sceneExpense = [...this.sceneExpense,...res.data.sceneExpense]
this.cbSummary = [...this.cbSummary,...res.data.cbSummary]
} }
} }
}) })
this.formdata = this.uploadData
console.log(this.uploadData)
}, },
methods:{ uplpro(type){
handleRemove(file, fileList) { if(!this.prodetail){
console.log(file, fileList); this.uploadtype = type
}, this.$refs.uploadpro.$el.querySelector('input').click()
handlePreview(file) { }
console.log(file);
}, },
handleExceed(files, fileList) { deletefille(id){
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`); this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteCbProjectFile(id).then(res=>{
if(res.code == 200){
this.$message({
type: 'success',
message: '删除成功!'
});
this.getDetail()
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}, },
beforeRemove(file, fileList) { handleFileListChange(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`); var testmsg = file.name.substring(file.name.lastIndexOf(".") + 1);
const extension = testmsg === "xlsx";
const extension1 = testmsg === "xls";
if (!extension && !extension1 ) {
this.$message({
message: "上传文件只能是.xls,.xlsx格式!",
type: "warning",
});
return false;
}
const isLt2M = file.size / 1024 / 1024 < 10
if (!isLt2M) {
this.$refs.upload.clearFiles()
this.$message({
message: '上传文件大小不能超过 10MB!',
type: 'warning'
})
return false
} }
const formdata = new FormData()
formdata.append("file",new File([file.raw],encodeURIComponent(file.name)))
formdata.append("projectId",this.formdata.id)
formdata.append("cbType",this.uploadtype)
uploadCbProjectFile(formdata).then(res=>{
if(res.code == 200){
let data = res.data
data.id = data.fileId
switch (this.uploadtype) {
case 0:
this.directExpense.push(data)
break;
case 1:
this.quantitySummary.push(data)
break;
case 2:
this.measureProject.push(data)
break;
case 3:
this.otherProject.push(data)
break;
case 4:
this.sceneExpense.push(data)
break;
case 5:
this.cbSummary.push(data)
break;
default:
break
}
}
})
},
} }
} }
</script> </script>
...@@ -389,7 +494,7 @@ ...@@ -389,7 +494,7 @@
margin-left: 12px; margin-left: 12px;
color: #0081FF; color: #0081FF;
display: inline-block; display: inline-block;
&:last-child{ &.i{
color: #FF3C3C; color: #FF3C3C;
} }
} }
...@@ -445,5 +550,9 @@ ...@@ -445,5 +550,9 @@
margin-left: 12px; margin-left: 12px;
} }
} }
.upload-demo{
opacity: 0;
position: absolute;
z-index: -9999;
}
</style> </style>
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