Commit ee71fe26 authored by danfuman's avatar danfuman

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

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

# Conflicts:
#	dsk-operate-ui/src/views/projectCostLedger/detail/index.vue
parents c58002ce 58eeba6c
...@@ -3,6 +3,7 @@ package com.dsk.common.excel; ...@@ -3,6 +3,7 @@ package com.dsk.common.excel;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import com.dsk.common.annotation.Excel; import com.dsk.common.annotation.Excel;
import com.dsk.common.core.domain.AjaxResult; import com.dsk.common.core.domain.AjaxResult;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.exception.UtilException; import com.dsk.common.exception.UtilException;
import com.dsk.common.utils.DateUtils; import com.dsk.common.utils.DateUtils;
import com.dsk.common.utils.DictUtils; import com.dsk.common.utils.DictUtils;
...@@ -13,6 +14,7 @@ import com.dsk.common.utils.file.ImageUtils; ...@@ -13,6 +14,7 @@ import com.dsk.common.utils.file.ImageUtils;
import com.dsk.common.utils.poi.ExcelHandlerAdapter; import com.dsk.common.utils.poi.ExcelHandlerAdapter;
import com.dsk.common.utils.poi.ExcelUtil; import com.dsk.common.utils.poi.ExcelUtil;
import com.dsk.common.utils.reflect.ReflectUtils; import com.dsk.common.utils.reflect.ReflectUtils;
import org.apache.commons.collections4.list.CursorableLinkedList;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.reflect.FieldUtils;
...@@ -40,6 +42,8 @@ import java.time.LocalDate; ...@@ -40,6 +42,8 @@ import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/** /**
* Excel相关处理 * Excel相关处理
...@@ -207,6 +211,7 @@ public class ExcelUtils<T> { ...@@ -207,6 +211,7 @@ public class ExcelUtils<T> {
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol));
} }
} }
public void createExportMessage() { public void createExportMessage() {
if (dateStatus) { if (dateStatus) {
subMergedFirstRowNum++; subMergedFirstRowNum++;
...@@ -226,6 +231,7 @@ public class ExcelUtils<T> { ...@@ -226,6 +231,7 @@ public class ExcelUtils<T> {
rownum++; rownum++;
} }
} }
public void createExportDate() { public void createExportDate() {
if (dateStatus) { if (dateStatus) {
subMergedFirstRowNum++; subMergedFirstRowNum++;
...@@ -330,8 +336,8 @@ public class ExcelUtils<T> { ...@@ -330,8 +336,8 @@ public class ExcelUtils<T> {
exportExcel(response); exportExcel(response);
} }
public ByteArrayOutputStream exportExcel( List<T> list, String sheetName, String title, boolean dateStatus) { public ByteArrayOutputStream exportExcel(List<T> list, String sheetName, String title, boolean dateStatus) {
ByteArrayOutputStream ba= new ByteArrayOutputStream(); ByteArrayOutputStream ba = new ByteArrayOutputStream();
this.init(list, sheetName, title, Excel.Type.EXPORT, dateStatus); this.init(list, sheetName, title, Excel.Type.EXPORT, dateStatus);
try { try {
writeSheet(); writeSheet();
...@@ -356,11 +362,11 @@ public class ExcelUtils<T> { ...@@ -356,11 +362,11 @@ public class ExcelUtils<T> {
* @param dateStatus 是否添加导出时间 * @param dateStatus 是否添加导出时间
* @return * @return
*/ */
public String localInit( List<T> list, String sheetName, String title, boolean dateStatus) { public String localInit(List<T> list, String sheetName, String title, boolean dateStatus) {
String fileName = title + "-" + System.currentTimeMillis() + ".xlsx"; String fileName = title + "-" + System.currentTimeMillis() + ".xlsx";
this.init(list, sheetName, title, Excel.Type.EXPORT, dateStatus); this.init(list, sheetName, title, Excel.Type.EXPORT, dateStatus);
writeSheet(); writeSheet();
try (FileOutputStream fileOutputStream = new FileOutputStream(FILE_PATH.concat(fileName))){ try (FileOutputStream fileOutputStream = new FileOutputStream(FILE_PATH.concat(fileName))) {
wb.write(fileOutputStream); wb.write(fileOutputStream);
return fileName; return fileName;
} catch (Exception e) { } catch (Exception e) {
...@@ -1384,113 +1390,148 @@ public class ExcelUtils<T> { ...@@ -1384,113 +1390,148 @@ public class ExcelUtils<T> {
public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception { public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception {
this.type = Excel.Type.IMPORT; this.type = Excel.Type.IMPORT;
this.wb = WorkbookFactory.create(is); this.wb = WorkbookFactory.create(is);
List<T> list = new ArrayList<T>(); List<T> resList = new ArrayList<T>();
// 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet
Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0);
if (sheet == null) { dealwithSheet(resList, sheet, titleNum);
throw new IOException("文件sheet不存在"); return resList;
} }
boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
Map<String, PictureData> pictures; /**
if (isXSSFWorkbook) { * 对excel表单所有表格转换成list
pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); *
} else { * @param titleNum 标题占用行数
pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); * @param is 输入流
} * @return 转换后集合
// 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 */
int rows = sheet.getLastRowNum(); public List<T> importExcelAllSheet(InputStream is, int titleNum) throws Exception {
this.type = Excel.Type.IMPORT;
if (rows > 0) { this.wb = WorkbookFactory.create(is);
// 定义一个map用于存放excel列的序号和field. List<T> resList = new ArrayList<>();
Map<String, Integer> cellMap = new HashMap<String, Integer>(); int sheetCount = wb.getNumberOfSheets();
// 获取表头 System.out.println("工作表个数为:" + sheetCount);
Row heard = sheet.getRow(titleNum); IntStream.rangeClosed(0, sheetCount - 1).parallel().forEach(sheetNum -> {
for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { Sheet sheet = wb.getSheetAt(sheetNum);
Cell cell = heard.getCell(i); dealwithSheet(resList, sheet, titleNum);
if (ObjectUtils.isEmpty(cell)) { });
cellMap.put(null, i); return resList;
} else { }
String value = this.getCellValue(heard, i).toString();
cellMap.put(value, i); private void dealwithSheet(List<T> resList, Sheet sheet, int titleNum) {
} try {
if (sheet == null) {
throw new IOException(sheet.getSheetName() + "为空表!");
} }
// 有数据时才处理 得到类的所有field. boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
List<Object[]> fields = this.getFields(); Map<String, PictureData> pictures;
Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>(); if (isXSSFWorkbook) {
for (Object[] objects : fields) { pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);
Excel attr = (Excel) objects[1]; } else {
Integer column = cellMap.get(attr.name()); pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb);
if (column != null) {
fieldsMap.put(column, objects);
}
} }
for (int i = titleNum + 1; i <= rows; i++) { // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
// 从第2行开始取数据,默认第一行是表头. int rows = sheet.getLastRowNum();
Row row = sheet.getRow(i);
// 判断当前行是否是空行 if (rows > 0) {
if (isRowEmpty(row)) { // 定义一个map用于存放excel列的序号和field.
continue; Map<String, Integer> cellMap = new HashMap<String, Integer>();
// 获取表头
Row heard = sheet.getRow(titleNum);
for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) {
Cell cell = heard.getCell(i);
if (ObjectUtils.isEmpty(cell)) {
cellMap.put(null, i);
} else {
String value = this.getCellValue(heard, i).toString();
cellMap.put(value, i);
}
} }
T entity = null; // 有数据时才处理 得到类的所有field.
for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet()) { List<Object[]> fields = this.getFields();
Object val = this.getCellValue(row, entry.getKey()); Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();
for (Object[] objects : fields) {
// 如果不存在实例则新建. Excel attr = (Excel) objects[1];
entity = (entity == null ? clazz.newInstance() : entity); Integer column = cellMap.get(attr.name());
// 从map中得到对应列的field. if (column != null) {
Field field = (Field) entry.getValue()[0]; fieldsMap.put(column, objects);
Excel attr = (Excel) entry.getValue()[1]; }
// 取得类型,并根据对象类型设置值. }
Class<?> fieldType = field.getType();
if (String.class == fieldType) { for (int i = titleNum + 1; i <= rows; i++) {
String s = Convert.toStr(val); // 从第2行开始取数据,默认第一行是表头.
if (StringUtils.endsWith(s, ".0")) { Row row = sheet.getRow(i);
val = StringUtils.substringBefore(s, ".0"); // 判断当前行是否是空行
} else { if (isRowEmpty(row)) {
String dateFormat = field.getAnnotation(Excel.class).dateFormat(); continue;
if (StringUtils.isNotEmpty(dateFormat)) { }
val = parseDateToStr(dateFormat, val);
T entity = null;
for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet()) {
Object val = this.getCellValue(row, entry.getKey());
// 如果不存在实例则新建.
entity = (entity == null ? clazz.newInstance() : entity);
// 从map中得到对应列的field.
Field field = (Field) entry.getValue()[0];
Excel attr = (Excel) entry.getValue()[1];
// 取得类型,并根据对象类型设置值.
Class<?> fieldType = field.getType();
if (String.class == fieldType) {
String s = Convert.toStr(val);
if (StringUtils.endsWith(s, ".0")) {
val = StringUtils.substringBefore(s, ".0");
} else { } else {
val = Convert.toStr(val); String dateFormat = field.getAnnotation(Excel.class).dateFormat();
if (StringUtils.isNotEmpty(dateFormat)) {
val = parseDateToStr(dateFormat, val);
} else {
val = Convert.toStr(val);
}
} }
} else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
val = Convert.toInt(val);
} else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
val = Convert.toLong(val);
} else if (Double.TYPE == fieldType || Double.class == fieldType) {
val = Convert.toDouble(val);
} else if (Float.TYPE == fieldType || Float.class == fieldType) {
val = Convert.toFloat(val);
} else if (BigDecimal.class == fieldType) {
val = Convert.toBigDecimal(val);
} else if (Date.class == fieldType) {
if (val instanceof String) {
val = DateUtils.parseDate(val);
} else if (val instanceof Double) {
val = DateUtil.getJavaDate((Double) val);
}
} else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) {
val = Convert.toBool(val, false);
} }
} else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) { if (!ObjectUtils.isEmpty(fieldType)) {
val = Convert.toInt(val); String propertyName = field.getName();
} else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
val = Convert.toLong(val); if (StringUtils.isNotEmpty(attr.targetAttr())) {
} else if (Double.TYPE == fieldType || Double.class == fieldType) { propertyName = field.getName() + "." + attr.targetAttr();
val = Convert.toDouble(val); } else if (StringUtils.isNotEmpty(attr.readConverterExp())) {
} else if (Float.TYPE == fieldType || Float.class == fieldType) { val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
val = Convert.toFloat(val); } else if (StringUtils.isNotEmpty(attr.dictType())) {
} else if (BigDecimal.class == fieldType) { val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
val = Convert.toBigDecimal(val); } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
} else if (Date.class == fieldType) { val = dataFormatHandlerAdapter(val, attr);
if (val instanceof String) { }
val = DateUtils.parseDate(val); ReflectUtils.invokeSetter(entity, propertyName, val);
} else if (val instanceof Double) {
val = DateUtil.getJavaDate((Double) val);
} }
} else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) {
val = Convert.toBool(val, false);
} }
if (!ObjectUtils.isEmpty(fieldType)) { synchronized (resList){
String propertyName = field.getName(); resList.add(entity);
if (StringUtils.isNotEmpty(attr.targetAttr())) {
propertyName = field.getName() + "." + attr.targetAttr();
} else if (StringUtils.isNotEmpty(attr.readConverterExp())) {
val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
} else if (StringUtils.isNotEmpty(attr.dictType())) {
val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
} else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
val = dataFormatHandlerAdapter(val, attr);
}
ReflectUtils.invokeSetter(entity, propertyName, val);
} }
} }
list.add(entity);
} }
} catch (Exception e) {
e.printStackTrace();
} }
return list;
} }
} }
...@@ -20,22 +20,26 @@ public interface CbProjectConstants { ...@@ -20,22 +20,26 @@ public interface CbProjectConstants {
* 成本阶段:转固 * 成本阶段:转固
*/ */
Integer CB_STAGE_TO_SOLID = 2; Integer CB_STAGE_TO_SOLID = 2;
/**
* 项目文件状态:未上传
*/
Integer PROJECT_FILE_STATUS_NOT_UPLOAD = 0;
/** /**
* 项目文件状态:待解析 * 项目文件状态:待解析
*/ */
Integer PROJECT_FILE_STATUS_NOT_PARSE = 0; Integer PROJECT_FILE_STATUS_NOT_PARSE = 1;
/** /**
* 项目文件状态:解析中 * 项目文件状态:解析中
*/ */
Integer PROJECT_FILE_STATUS_PARSING = 1; Integer PROJECT_FILE_STATUS_PARSING = 2;
/** /**
* 项目文件状态:解析成功 * 项目文件状态:解析成功
*/ */
Integer PROJECT_FILE_STATUS_PARSE_SUCCESS = 2; Integer PROJECT_FILE_STATUS_PARSE_SUCCESS = 3;
/** /**
* 项目文件状态:解析失败 * 项目文件状态:解析失败
*/ */
Integer PROJECT_FILE_STATUS_PARSE_FAIL = 3; Integer PROJECT_FILE_STATUS_PARSE_FAIL = 4;
/** /**
* 删除状态:未删除 * 删除状态:未删除
*/ */
...@@ -44,5 +48,43 @@ public interface CbProjectConstants { ...@@ -44,5 +48,43 @@ public interface CbProjectConstants {
* 删除状态:已删除 * 删除状态:已删除
*/ */
Integer DELETE_FLAG_NOT_EXIST = 2; Integer DELETE_FLAG_NOT_EXIST = 2;
/**
* 是否获取项目详情:是
*/
Integer IS_GET_PROJECT_DETAIL = 0;
/**
* 是否获取项目详情:否
*/
Integer NOT_GET_PROJECT_DETAIL = 1;
//成本类型(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总、6:未确定)
/**
* 成本类型:直接费成本
*/
Integer CB_TYPE_DIRECT_EXPENSE = 0;
/**
* 成本类型:工料汇总
*/
Integer CB_TYPE_QUANTITY_SUMMARY = 1;
/**
* 成本类型:措施项目
*/
Integer CB_TYPE_MEASURE_PROJECT = 2;
/**
* 成本类型:其他项目
*/
Integer CB_TYPE_OTHER_PROJECT = 3;
/**
* 成本类型:现场经费
*/
Integer CB_TYPE_SCENE_EXPENSE = 4;
/**
* 成本类型:成本汇总
*/
Integer CB_TYPE_ACCOUNT_SUMMARY = 5;
/**
* 成本类型:未确定
*/
Integer CB_TYPE_NOT_CONFIRM = 6;
} }
...@@ -2,11 +2,23 @@ package com.dsk.cscec.controller; ...@@ -2,11 +2,23 @@ package com.dsk.cscec.controller;
import com.dsk.common.core.controller.BaseController; import com.dsk.common.core.controller.BaseController;
import com.dsk.common.core.domain.R;
import com.dsk.common.excel.ExcelUtils;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.service.ICbQuantitySummaryService; import com.dsk.cscec.service.ICbQuantitySummaryService;
import org.springframework.web.bind.annotation.RequestMapping; import com.dsk.system.domain.vo.SysUserImportVo;
import org.springframework.web.bind.annotation.RestController; import lombok.RequiredArgsConstructor;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.reflect.generics.tree.Tree;
import javax.annotation.Resource; import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
/** /**
* 成本-工料汇总基本表(CbQuantitySummary)表控制层 * 成本-工料汇总基本表(CbQuantitySummary)表控制层
...@@ -15,14 +27,50 @@ import javax.annotation.Resource; ...@@ -15,14 +27,50 @@ import javax.annotation.Resource;
* @since 2024-02-05 11:06:56 * @since 2024-02-05 11:06:56
*/ */
@RestController @RestController
@RequiredArgsConstructor
@RequestMapping("/cb/quantity/summary") @RequestMapping("/cb/quantity/summary")
public class CbQuantitySummaryController extends BaseController { public class CbQuantitySummaryController extends BaseController {
private final ICbQuantitySummaryService baseService;
/**
* 工料汇总科目树
* @return
*/
@GetMapping(value = "/subjectTree")
public R<Map<String, Object>> subjectTree(@PathVariable CbProjectBaseBo bo){
return R.ok(baseService.subjectTree(bo));
}
/**
* 已记录月份集合
*/
@GetMapping(value = "/monthList")
public R<List<String>> monthList(@PathVariable CbProjectBaseBo bo){
return R.ok(baseService.monthList(bo));
}
/** /**
* 服务对象 * 数据导入
*/ */
@Resource @PostMapping(value = "/importData")
private ICbQuantitySummaryService baseService; public R<Void> importFile(@RequestPart("file") MultipartFile file) throws Exception {
//识别Excel内容
List<CbQuantitySummary> importList = new ExcelUtils<>(CbQuantitySummary.class).importExcelAllSheet(file.getInputStream(), 1);
if (importList.isEmpty()) {
throw new ServiceException("表格中不存在待导入数据!");
}
importList = importList.stream().parallel()
.filter(item -> !ObjectUtils.isEmpty(item.getCbName()))
.peek(item -> {
item.setProjectId(1L);
item.setCbStage(0);
}).collect(Collectors.toList());
if (importList.isEmpty()) {
throw new ServiceException("表格中不存在有效数据数据!");
}
return toAjax(baseService.saveBatch(importList));
}
} }
package com.dsk.cscec.controller;
import com.dsk.common.core.controller.BaseController;
import com.dsk.cscec.service.CbSummaryService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 成本汇总(CbSummary)表控制层
*
* @author cyf
* @since 2024-02-06
*/
@RestController
@RequestMapping("/cbSummary")
public class CbSummaryController extends BaseController {
/**
* 服务对象
*/
@Resource
private CbSummaryService cbSummaryService;
}
package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
import lombok.Data;
/**
* 项目费用汇总表
*/
@Data
@TableName(value = "cb_project_expense_summary")
public class CbProjectExpenseSummary {
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.INPUT)
private Long id;
/**
* 项目ID
*/
@TableField(value = "project_id")
private Long projectId;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
@TableField(value = "cb_stage")
private Integer cbStage;
/**
* 序号
*/
@TableField(value = "`number`")
private String number;
/**
* 数据类型(0:现场经费、1:其他费用)
*/
@TableField(value = "data_type")
private Integer dataType;
/**
* 名称
*/
@TableField(value = "expense_name")
private String expenseName;
/**
* 数值
*/
@TableField(value = "expense_value")
private String expenseValue;
/**
* 占比
*/
@TableField(value = "proportion")
private String proportion;
/**
* 删除状态(0:否、2:是)
*/
@TableField(value = "del_flag")
private Integer delFlag;
/**
* 创建者
*/
@TableField(value = "create_by")
private String createBy;
/**
* 创建时间
*/
@TableField(value = "create_time")
private Date createTime;
public static final String COL_ID = "id";
public static final String COL_PROJECT_ID = "project_id";
public static final String COL_CB_STAGE = "cb_stage";
public static final String COL_NUMBER = "number";
public static final String COL_DATA_TYPE = "data_type";
public static final String COL_EXPENSE_NAME = "expense_name";
public static final String COL_EXPENSE_VALUE = "expense_value";
public static final String COL_PROPORTION = "proportion";
public static final String COL_DEL_FLAG = "del_flag";
public static final String COL_CREATE_BY = "create_by";
public static final String COL_CREATE_TIME = "create_time";
}
\ No newline at end of file
...@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName; ...@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable; import java.io.Serializable;
import com.dsk.common.annotation.Excel;
import lombok.Data; import lombok.Data;
/** /**
...@@ -30,6 +31,7 @@ public class CbQuantitySummary implements Serializable { ...@@ -30,6 +31,7 @@ public class CbQuantitySummary implements Serializable {
/** /**
* 序号 * 序号
*/ */
@Excel(name = "序号")
private String number; private String number;
/** /**
* 成本阶段(0:标前成本 1:标后成本 2:转固成本) * 成本阶段(0:标前成本 1:标后成本 2:转固成本)
...@@ -38,6 +40,7 @@ public class CbQuantitySummary implements Serializable { ...@@ -38,6 +40,7 @@ public class CbQuantitySummary implements Serializable {
/** /**
* 成本科目名称(合约规划) * 成本科目名称(合约规划)
*/ */
@Excel(name = "成本科目")
private String cbSubjectName; private String cbSubjectName;
/** /**
* 成本科目编号(合约规划编号) * 成本科目编号(合约规划编号)
...@@ -46,66 +49,82 @@ public class CbQuantitySummary implements Serializable { ...@@ -46,66 +49,82 @@ public class CbQuantitySummary implements Serializable {
/** /**
* 公司编码 * 公司编码
*/ */
@Excel(name = "编码")
private String companyNo; private String companyNo;
/** /**
* 集团编码 * 集团编码
*/ */
@Excel(name = "集团编码")
private String orgNo; private String orgNo;
/** /**
* 成本名称 * 成本名称
*/ */
@Excel(name = "名称")
private String cbName; private String cbName;
/** /**
* 工作内容 * 工作内容
*/ */
@Excel(name = "工作内容")
private String jobContent; private String jobContent;
/** /**
* 计算规则 * 计算规则
*/ */
@Excel(name = "计算规则")
private String calculationRule; private String calculationRule;
/** /**
* 计量单位 * 计量单位
*/ */
@Excel(name = "单位")
private String unit; private String unit;
/** /**
* 材料说明 * 材料说明
*/ */
@Excel(name = "甲供材料说明")
private String materialDescription; private String materialDescription;
/** /**
* 指导价格 * 指导价格
*/ */
@Excel(name = "指导价格")
private String guidePrice; private String guidePrice;
/** /**
* 投标选用单价(不含税) * 投标选用单价(不含税)
*/ */
@Excel(name = "投标选用单价(不含税)")
private Double bidUnitPrice; private Double bidUnitPrice;
/** /**
* 单价差额 * 单价差额
*/ */
@Excel(name = "单价差额")
private Double unitPriceDifference; private Double unitPriceDifference;
/** /**
* 数量 * 数量
*/ */
@Excel(name = "数量")
private Double quantity; private Double quantity;
/** /**
* 合价(不含税) * 合价(不含税)
*/ */
@Excel(name = "合价(不含税)")
private Double combinedPrice; private Double combinedPrice;
/** /**
* 合价(含税) * 合价(含税)
*/ */
@Excel(name = "合价(含税)")
private Double combinedPriceTax; private Double combinedPriceTax;
/** /**
* 品牌名称 * 品牌名称
*/ */
@Excel(name = "品牌名称")
private String brandName; private String brandName;
/** /**
* 投标选用来源 * 投标选用来源
*/ */
@Excel(name = "投标选用来源")
private String bidSource; private String bidSource;
/** /**
* 备注 * 备注
*/ */
@Excel(name = "备注")
private String remark; private String remark;
/** /**
* 创建时间 * 创建时间
......
package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 成本汇总(CbSummary)实体类
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummary implements Serializable {
private static final long serialVersionUID = -20126964599875841L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 父级id
*/
private Long parentId;
/**
* 层级
*/
private Integer level;
/**
* 排序
*/
private Integer sort;
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目成本文件id
*/
private Long cbProjectFileId;
/**
* 序号
*/
private String number;
/**
* 名称/成本科目
*/
private String cbName;
/**
* 不含税成本合价
*/
private String taxExclusiveTotal;
/**
* 成本税金合价
*/
private String cbTaxesTotal;
/**
* 含税成本合价
*/
private String taxInclusiveTotal;
/**
* 成本占比
*/
private String cbProportion;
/**
* 含税成本平米指标
*/
private String taxInclusivePmTarget;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除状态(0:否、2:是)
*/
private Integer delFlag;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType;
}
package com.dsk.cscec.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 成本汇总-每月费用(CbSummaryActual)实体类
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummaryActual implements Serializable {
private static final long serialVersionUID = -85978330087467049L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 成本汇总id
*/
private Long cbSummaryId;
/**
* 本月费用(含税)
*/
private Double taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
private Double taxExclusiveExpense;
/**
* 费用日期
*/
private String expenseDate;
/**
* 是否锁定(0否,1是)
*/
private Integer lockStatus;
/**
* 创建时间
*/
private Date createTime;
/**
* 删除状态(0:否、2:是)
*/
private Integer delFlag;
}
package com.dsk.cscec.domain.bo;
import lombok.Data;
/**
* 项目成本基础参数
*
* @Author lcl
* @Data 2024/2/6 9:24
*/
@Data
public class CbProjectBaseBo {
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段(0:标前成本 1:标后成本 2:转固成本)
*/
private Integer cbStage;
}
package com.dsk.cscec.listener; //package com.dsk.cscec.listener;
//
import cn.dev33.satoken.secure.BCrypt; //import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil; //import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil; //import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext; //import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener; //import com.alibaba.excel.event.AnalysisEventListener;
import com.dsk.common.excel.ExcelListener; //import com.dsk.common.excel.ExcelListener;
import com.dsk.common.excel.ExcelResult; //import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException; //import com.dsk.common.exception.ServiceException;
import com.dsk.common.helper.LoginHelper; //import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.ValidatorUtils; //import com.dsk.common.utils.ValidatorUtils;
import com.dsk.common.utils.spring.SpringUtils; //import com.dsk.common.utils.spring.SpringUtils;
import com.dsk.cscec.domain.vo.ProjectMeasuresImportVo; //import com.dsk.cscec.domain.vo.ProjectMeasuresImportVo;
import com.dsk.system.domain.SysUser; //import com.dsk.system.domain.SysUser;
import com.dsk.system.domain.vo.SysUserImportVo; //import com.dsk.system.domain.vo.SysUserImportVo;
import com.dsk.system.service.ISysConfigService; //import com.dsk.system.service.ISysConfigService;
import com.dsk.system.service.ISysUserService; //import com.dsk.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
//
import java.util.List; //import java.util.List;
//
/** ///**
* 系统用户自定义导入 // * 系统用户自定义导入
* // *
* @author Lion Li // * @author Lion Li
*/ // */
@Slf4j //@Slf4j
public class ProjectCostMeasureImportListener extends AnalysisEventListener<ProjectMeasuresImportVo> implements ExcelListener<ProjectMeasuresImportVo> { //public class ProjectCostMeasureImportListener extends AnalysisEventListener<ProjectMeasuresImportVo> implements ExcelListener<ProjectMeasuresImportVo> {
//
// private final ISysUserService userService; //// private final ISysUserService userService;
//
// private final String password; //// private final String password;
//
private final Boolean isUpdateSupport; // private final Boolean isUpdateSupport;
//
private final String operName; // private final String operName;
//
private int successNum = 0; // private int successNum = 0;
private int failureNum = 0; // private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder(); // private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder(); // private final StringBuilder failureMsg = new StringBuilder();
//
public ProjectCostMeasureImportListener(Boolean isUpdateSupport) { // public ProjectCostMeasureImportListener(Boolean isUpdateSupport) {
// String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword"); //// String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
// this.userService = SpringUtils.getBean(ISysUserService.class); //// this.userService = SpringUtils.getBean(ISysUserService.class);
// this.password = BCrypt.hashpw(initPassword); //// this.password = BCrypt.hashpw(initPassword);
this.isUpdateSupport = isUpdateSupport; // this.isUpdateSupport = isUpdateSupport;
this.operName = LoginHelper.getUsername(); // this.operName = LoginHelper.getUsername();
} // }
//
@Override // @Override
public void invoke(ProjectMeasuresImportVo userVo, AnalysisContext context) { // public void invoke(ProjectMeasuresImportVo userVo, AnalysisContext context) {
// SysUser user = this.userService.selectUserByUserName(userVo.getUserName()); //// SysUser user = this.userService.selectUserByUserName(userVo.getUserName());
// try { //// try {
// // 验证是否存在这个用户 //// // 验证是否存在这个用户
// if (ObjectUtil.isNull(user)) { //// if (ObjectUtil.isNull(user)) {
// user = BeanUtil.toBean(userVo, SysUser.class); //// user = BeanUtil.toBean(userVo, SysUser.class);
// ValidatorUtils.validate(user); //// ValidatorUtils.validate(user);
// user.setPassword(password); //// user.setPassword(password);
// user.setCreateBy(operName); //// user.setCreateBy(operName);
// userService.insertUser(user); //// userService.insertUser(user);
// successNum++; //// successNum++;
// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 导入成功"); //// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 导入成功");
// } else if (isUpdateSupport) { //// } else if (isUpdateSupport) {
// Long userId = user.getUserId(); //// Long userId = user.getUserId();
// user = BeanUtil.toBean(userVo, SysUser.class); //// user = BeanUtil.toBean(userVo, SysUser.class);
// user.setUserId(userId); //// user.setUserId(userId);
// ValidatorUtils.validate(user); //// ValidatorUtils.validate(user);
// userService.checkUserAllowed(user); //// userService.checkUserAllowed(user);
// userService.checkUserDataScope(user.getUserId()); //// userService.checkUserDataScope(user.getUserId());
// user.setUpdateBy(operName); //// user.setUpdateBy(operName);
// userService.updateUser(user); //// userService.updateUser(user);
// successNum++; //// successNum++;
// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 更新成功"); //// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 更新成功");
// } else { //// } else {
// failureNum++; //// failureNum++;
// failureMsg.append("<br/>").append(failureNum).append("、账号 ").append(user.getUserName()).append(" 已存在"); //// failureMsg.append("<br/>").append(failureNum).append("、账号 ").append(user.getUserName()).append(" 已存在");
//// }
//// } catch (Exception e) {
//// failureNum++;
//// String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
//// failureMsg.append(msg).append(e.getMessage());
//// log.error(msg, e);
//// }
// }
//
// @Override
// public void doAfterAllAnalysed(AnalysisContext context) {
//
// }
//
// @Override
// public ExcelResult<ProjectMeasuresImportVo> getExcelResult() {
// return new ExcelResult<ProjectMeasuresImportVo>() {
//
// @Override
// public String getAnalysis() {
// if (failureNum > 0) {
// failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
// throw new ServiceException(failureMsg.toString());
// } else {
// successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
// }
// return successMsg.toString();
// } // }
// } catch (Exception e) { //
// failureNum++; // @Override
// String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; // public List<ProjectMeasuresImportVo> getList() {
// failureMsg.append(msg).append(e.getMessage()); // return null;
// log.error(msg, e); // }
// } //
} // @Override
// public List<String> getErrorList() {
@Override // return null;
public void doAfterAllAnalysed(AnalysisContext context) { // }
// };
} // }
//}
@Override
public ExcelResult<ProjectMeasuresImportVo> getExcelResult() {
return new ExcelResult<ProjectMeasuresImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<ProjectMeasuresImportVo> getList() {
return null;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbProjectExpenseSummary;
public interface CbProjectExpenseSummaryMapper extends BaseMapper<CbProjectExpenseSummary> {
}
\ No newline at end of file
...@@ -2,6 +2,12 @@ package com.dsk.cscec.mapper; ...@@ -2,6 +2,12 @@ package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbQuantitySummary; import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/** /**
* 成本-工料汇总基本表(CbQuantitySummary)表数据库访问层 * 成本-工料汇总基本表(CbQuantitySummary)表数据库访问层
...@@ -11,5 +17,10 @@ import com.dsk.cscec.domain.CbQuantitySummary; ...@@ -11,5 +17,10 @@ import com.dsk.cscec.domain.CbQuantitySummary;
*/ */
public interface CbQuantitySummaryMapper extends BaseMapper<CbQuantitySummary> { public interface CbQuantitySummaryMapper extends BaseMapper<CbQuantitySummary> {
List<Map<String, Object>> selectSubject(CbProjectBaseBo bo);
int selectOtherSubjectCount(CbProjectBaseBo bo);
} }
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSummaryActual;
/**
* 成本汇总-每月费用(CbSummaryActual)表数据库访问层
*
* @author cyf
* @since 2024-02-06
*/
public interface CbSummaryActualMapper extends BaseMapper<CbSummaryActual> {
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSummary;
/**
* 成本汇总(CbSummary)表数据库访问层
*
* @author cyf
* @since 2024-02-06
*/
public interface CbSummaryMapper extends BaseMapper<CbSummary> {
}
package com.dsk.cscec.service;
import com.dsk.cscec.domain.CbProjectExpenseSummary;
import com.baomidou.mybatisplus.extension.service.IService;
public interface CbProjectExpenseSummaryService extends IService<CbProjectExpenseSummary>{
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbSummaryActual;
/**
* 成本汇总-每月费用(CbSummaryActual)表服务接口
*
* @author cyf
* @since 2024-02-06
*/
public interface CbSummaryActualService extends IService<CbSummaryActual> {
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbSummary;
/**
* 成本汇总(CbSummary)表服务接口
*
* @author cyf
* @since 2024-02-06
*/
public interface CbSummaryService extends IService<CbSummary> {
}
...@@ -2,6 +2,10 @@ package com.dsk.cscec.service; ...@@ -2,6 +2,10 @@ package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbQuantitySummary; import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import java.util.List;
import java.util.Map;
/** /**
* 成本-工料汇总基本表(CbQuantitySummary)表服务接口 * 成本-工料汇总基本表(CbQuantitySummary)表服务接口
...@@ -11,5 +15,9 @@ import com.dsk.cscec.domain.CbQuantitySummary; ...@@ -11,5 +15,9 @@ import com.dsk.cscec.domain.CbQuantitySummary;
*/ */
public interface ICbQuantitySummaryService extends IService<CbQuantitySummary> { public interface ICbQuantitySummaryService extends IService<CbQuantitySummary> {
Map<String, Object> subjectTree(CbProjectBaseBo bo);
List<String> monthList(CbProjectBaseBo bo);
} }
package com.dsk.cscec.service.impl; package com.dsk.cscec.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.mapper.CbQuantitySummaryMapper;
import com.dsk.cscec.domain.CbQuantitySummary; import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.mapper.CbQuantitySummaryMapper;
import com.dsk.cscec.service.ICbQuantitySummaryService; import com.dsk.cscec.service.ICbQuantitySummaryService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 成本-工料汇总基本表(CbQuantitySummary)表服务实现类 * 成本-工料汇总基本表(CbQuantitySummary)表服务实现类
...@@ -15,5 +22,27 @@ import org.springframework.stereotype.Service; ...@@ -15,5 +22,27 @@ import org.springframework.stereotype.Service;
@Service @Service
public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryMapper, CbQuantitySummary> implements ICbQuantitySummaryService { public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryMapper, CbQuantitySummary> implements ICbQuantitySummaryService {
@Override
public Map<String, Object> subjectTree(CbProjectBaseBo bo) {
Map<String, Object> resultMap = new HashMap<>();
List<Map<String, Object>> list = baseMapper.selectSubject(bo);
if (!ObjectUtils.isEmpty(list)) {
Map<String, Map<String, Map<String, List<Map<String, Object>>>>> map = list.stream().collect(
Collectors.groupingBy(item -> item.get("one").toString(),
Collectors.groupingBy(item -> item.get("two").toString(),
Collectors.groupingBy(item -> item.get("three").toString()))));
resultMap.put("房建类成本科目", map);
}
int otherSubjectCount = baseMapper.selectOtherSubjectCount(bo);
if (otherSubjectCount > 0) {
resultMap.put("未归类项目", "other");
}
return resultMap;
}
@Override
public List<String> monthList(CbProjectBaseBo bo) {
return null;
}
} }
package com.dsk.cscec.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.domain.CbSummaryActual;
import com.dsk.cscec.mapper.CbSummaryActualMapper;
import com.dsk.cscec.service.CbSummaryActualService;
import org.springframework.stereotype.Service;
/**
* 成本汇总-每月费用(CbSummaryActual)表服务实现类
*
* @author cyf
* @since 2024-02-06
*/
@Service
public class CbSummaryActualServiceImpl extends ServiceImpl<CbSummaryActualMapper, CbSummaryActual> implements CbSummaryActualService {
}
package com.dsk.cscec.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.mapper.CbSummaryMapper;
import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.service.CbSummaryService;
import org.springframework.stereotype.Service;
/**
* 成本汇总(CbSummary)表服务实现类
*
* @author cyf
* @since 2024-02-06
*/
@Service
public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary> implements CbSummaryService {
}
<?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.CbProjectExpenseSummaryMapper">
<resultMap id="BaseResultMap" type="com.dsk.cscec.domain.CbProjectExpenseSummary">
<!--@mbg.generated-->
<!--@Table cb_project_expense_summary-->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="project_id" jdbcType="BIGINT" property="projectId" />
<result column="cb_stage" jdbcType="INTEGER" property="cbStage" />
<result column="number" jdbcType="VARCHAR" property="number" />
<result column="data_type" jdbcType="INTEGER" property="dataType" />
<result column="expense_name" jdbcType="VARCHAR" property="expenseName" />
<result column="expense_value" jdbcType="VARCHAR" property="expenseValue" />
<result column="proportion" jdbcType="VARCHAR" property="proportion" />
<result column="del_flag" jdbcType="INTEGER" property="delFlag" />
<result column="create_by" jdbcType="VARCHAR" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, project_id, cb_stage, `number`, data_type, expense_name, expense_value, proportion,
del_flag, create_by, create_time
</sql>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dsk.cscec.mapper.CbQuantitySummaryMapper">
<select id="selectSubject" resultType="java.util.Map">
select
cs1.cb_subject_name as one, cs2.cb_subject_name as two, cs3.cb_subject_name as three
from cb_subject cs1
join cb_subject cs2 on (cs2.cb_subject_no like concat(cs1.cb_subject_no,'%') and cs2.`level` = 2 )
join cb_subject cs3 on (cs3.cb_subject_no like concat(cs2.cb_subject_no,'%') and cs3.`level` = 3 )
join cb_quantity_summary cqs on (cqs.cb_subject_name = cs3.cb_subject_name and cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage})
where cs1.`level` = 1
group by cs1.cb_subject_name,cs2.cb_subject_name,cs3.cb_subject_name
</select>
<select id="selectOtherSubjectCount" resultType="java.lang.Integer">
select
count(cqs.id)
from cb_quantity_summary cqs
left join cb_subject cs1 on cqs.cb_subject_name = cs1.cb_subject_name
where cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage} and cs1.id is null
</select>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dsk.cscec.mapper.CbSummaryActualMapper">
<resultMap type="com.dsk.cscec.domain.CbSummaryActual" id="CbSummaryActualMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="cbSummaryId" column="cb_summary_id" jdbcType="INTEGER"/>
<result property="taxInclusiveExpense" column="tax_inclusive_expense" jdbcType="NUMERIC"/>
<result property="taxExclusiveExpense" column="tax_exclusive_expense" jdbcType="NUMERIC"/>
<result property="expenseDate" column="expense_date" jdbcType="VARCHAR"/>
<result property="lockStatus" column="lock_status" jdbcType="INTEGER"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="delFlag" column="del_flag" jdbcType="INTEGER"/>
</resultMap>
<sql id="baseColumn">
id, cb_summary_id, tax_inclusive_expense, tax_exclusive_expense, expense_date, lock_status, create_time, del_flag
</sql>
</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.CbSummaryMapper">
<resultMap type="com.dsk.cscec.domain.CbSummary" id="CbSummaryMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="parentId" column="parent_id" jdbcType="INTEGER"/>
<result property="level" column="level" jdbcType="INTEGER"/>
<result property="sort" column="sort" jdbcType="INTEGER"/>
<result property="projectId" column="project_id" jdbcType="INTEGER"/>
<result property="cbStage" column="cb_stage" jdbcType="INTEGER"/>
<result property="cbProjectFileId" column="cb_project_file_id" jdbcType="INTEGER"/>
<result property="number" column="number" jdbcType="VARCHAR"/>
<result property="cbName" column="cb_name" jdbcType="VARCHAR"/>
<result property="taxExclusiveTotal" column="tax_exclusive_total" jdbcType="VARCHAR"/>
<result property="cbTaxesTotal" column="cb_taxes_total" jdbcType="VARCHAR"/>
<result property="taxInclusiveTotal" column="tax_inclusive_total" jdbcType="VARCHAR"/>
<result property="cbProportion" column="cb_proportion" jdbcType="VARCHAR"/>
<result property="taxInclusivePmTarget" column="tax_inclusive_pm_target" jdbcType="VARCHAR"/>
<result property="remark" column="remark" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="delFlag" column="del_flag" jdbcType="INTEGER"/>
<result property="cbType" column="cb_type" jdbcType="INTEGER"/>
</resultMap>
<sql id="baseColumn">
id, parent_id, level, sort, project_id, cb_stage, cb_project_file_id, number, cb_name, tax_exclusive_total,
cb_taxes_total, tax_inclusive_total, cb_proportion, tax_inclusive_pm_target, remark, create_time, del_flag,
cb_type
</sql>
</mapper>
...@@ -1039,11 +1039,11 @@ export function generateRandomLowerCaseLetter() { ...@@ -1039,11 +1039,11 @@ export function generateRandomLowerCaseLetter() {
* @param {Array<any>} ancestors * @param {Array<any>} ancestors
* @returns * @returns
*/ */
export function findAncestors(data, targetId, idKey = "uid", childrenKey = "children", ancestors = []) { export function findAncestors(data, targetId, idKey = "id", childrenKey = "children", ancestors = []) {
if (data[idKey] === targetId) { if (data[idKey] === targetId) {
return [...ancestors, data]; // 找到目标节点,将其添加到祖先数组中并返回 return [...ancestors, data]; // 找到目标节点,将其添加到祖先数组中并返回
} }
if (data[childrenKey]?.length) { if (data[childrenKey]?.length) {
for (const child of data[childrenKey]) { for (const child of data[childrenKey]) {
const result = findAncestors(child, targetId, idKey, childrenKey, [...ancestors, data]); // 递归调用,将当前节点添加到祖先数组中 const result = findAncestors(child, targetId, idKey, childrenKey, [...ancestors, data]); // 递归调用,将当前节点添加到祖先数组中
......
<template> <template>
<div class="feed-summary-container"> <div class="feed-summary-container">
<div class="feed-summary-inner">
<div class="left-side-menu">
<project-side-menu></project-side-menu>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
import ProjectSideMenu from "@/views/projectCostLedger/detail/components/ProjectSideMenu";
export default { export default {
name : "feedSummary", name: "feedSummary",
data() { components: {
return { ProjectSideMenu
},
} data() {
}, return {
//可访问data属性 menuTreeList: []
created(){ };
},
//可访问data属性
created() {
}, },
//计算集 //计算集
computed:{ computed: {
}, },
//方法集 //方法集
methods:{ methods: {
}, },
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.feed-summary-container { .feed-summary-container {
width: 100%;
height: 100%;
.feed-summary-inner {
width: 100%;
height: 100%;
display: flex;
align-items: center;
.left-side-menu {
width: 220px;
min-width: 220px;
height: 100%;
}
}
} }
</style> </style>
<template> <template>
<div class="project-bread-crumb-container"> <div class="project-bread-crumb-container">
<el-breadcrumb separator-class="el-icon-arrow-right" class="project-bread-crumb-inner"> <el-breadcrumb separator-class="el-icon-arrow-right" class="project-bread-crumb-inner">
<!-- 默认展示 -->
<el-breadcrumb-item class="project-bread-crumb-item">
<span @click="$router.push('/projectCostLedger')">项目成本台账</span>
</el-breadcrumb-item>
<!-- 当前模块 -->
<transition name="breadcrumb" mode="out-in">
<el-breadcrumb-item class="project-bread-crumb-item current-bread-brumb-item" v-if="breadCrumb[module] && current">
<span>{{breadCrumb[module].breadcrumbName}}</span>
</el-breadcrumb-item>
</transition>
<!-- 下级 -->
<transition-group name="breadcrumb" tag="div" v-if="currentBreadCurmbList.length"> <transition-group name="breadcrumb" tag="div" v-if="currentBreadCurmbList.length">
<el-breadcrumb-item class="project-bread-crumb-item" v-for="(item,index) of currentBreadCurmbList" :key="item.path" <el-breadcrumb-item class="project-bread-crumb-item" v-for="(item,index) of currentBreadCurmbList" :key="item.path"
:class="{'current-bread-brumb-item' : item.path == current}"> :class="{'current-bread-brumb-item' : useTrigger(item)}">
<span @click.stop="item.path == current ? '' : breadClickHandle(item)">{{item.breadcrumbName}}</span> <slot :name="item.path" :data="item">
<span @click.stop="useTrigger(item) ? '' : breadClickHandle(item)">{{item.breadcrumbName}}</span>
</slot>
</el-breadcrumb-item> </el-breadcrumb-item>
</transition-group> </transition-group>
</el-breadcrumb> </el-breadcrumb>
...@@ -28,59 +19,30 @@ export default { ...@@ -28,59 +19,30 @@ export default {
name: "projectBreadCrumb", name: "projectBreadCrumb",
props: { props: {
current: String, current: String,
module: String indexText: String,
breadCrumbTree: {
type: Array,
default: () => []
}
}, },
watch: { watch: {
current: { current: {
handler(newValue, oldValue) { handler(newValue, oldValue) {
this.init(newValue); this.init(newValue);
} }
},
breadCrumbTree: {
handler(newValue) {
this.comBreadCrumbTree = newValue;
this.init(this.current);
},
deep: true
} }
}, },
data() { data() {
return { return {
currentBreadCurmbList: [], currentBreadCurmbList: [],
breadCrumb: { comBreadCrumbTree: this.breadCrumbTree
// 详情
detail: {
breadcrumbName: "详情",
childrenBreadCrumb: [
{
breadcrumbName: "工程项目信息",
path: "basicEngineeringInformation"
},
{
breadcrumbName: "直接费成本",
path: "directCost"
},
{
breadcrumbName: "工料汇总",
path: "feedSummary"
},
{
breadcrumbName: "措施项目",
path: "measureItem"
},
{
breadcrumbName: "其他项目",
path: "otherItems"
},
{
breadcrumbName: "现场经费",
path: "fieldExpenses"
},
{
breadcrumbName: "成本汇总",
path: "cost"
},
{
breadcrumbName: "盈亏分析对比",
path: "profitAndLoss"
}
]
}
// 缺省配置
}
}; };
}, },
//可访问data属性 //可访问data属性
...@@ -95,28 +57,33 @@ export default { ...@@ -95,28 +57,33 @@ export default {
methods: { methods: {
init(current) { init(current) {
if (!current) return; if (!current) return;
// 取出当前模块 if (this?.comBreadCrumbTree?.length) {
const _temp = cloneDeep(this.breadCrumb[this.module]); const _temp = cloneDeep(this.comBreadCrumbTree);
if (!_temp) return; // 根节点path 为root
this.currentBreadCurmbList = this.createBreadCrumb(current, _temp); _temp[0].path = "root";
this.currentBreadCurmbList = this.createBreadCrumb(current, _temp);
}
}, },
createBreadCrumb(current, data) { createBreadCrumb(current, data) {
let result = findAncestors(data, current, "path", "childrenBreadCrumb"); let result = findAncestors(data[0], current, "path", "childrenBreadCrumb");
if (result) { if (result) {
result = result.filter(item => item.path);
result = result.map(item => { result = result.map(item => {
const _temp = { const _temp = {
breadcrumbName: item.breadcrumbName, breadcrumbName: item.breadcrumbName,
triggerHandle: item.triggerHandle === false ? false : true
}; };
if (item.path) _temp["path"] = item.path; if (item.path) _temp["path"] = item.path;
return _temp; return _temp;
}); });
return result; return result;
} }
; return [];
},
useTrigger(item) {
return item.path == this.current || item.triggerHandle === false;
}, },
breadClickHandle(item) { breadClickHandle(item) {
console.log(item); this.$emit("breadCrumbTrigger", item);
} }
}, },
} }
......
<template> <template>
<div class="project-cost-ledger-detail-header"> <div class="project-cost-ledger-detail-header">
<div class="project-cost-ledger-detail-header-inner"> <div class="project-cost-ledger-detail-header-inner">
<project-bread-crumb :module="module" :current="current"></project-bread-crumb> <project-bread-crumb :current="current" :breadCrumbTree="breadCrumbTree" @breadCrumbTrigger="breadCrumbTrigger"></project-bread-crumb>
<!-- 项目名称 --> <!-- 项目名称 -->
<div class="project-detail-header-name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)</div> <div class="project-detail-header-name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)</div>
<!-- 项目信息 --> <!-- 项目信息 -->
...@@ -27,15 +27,15 @@ import ProjectBreadCrumb from "@/views/projectCostLedger/detail/components/Proje ...@@ -27,15 +27,15 @@ import ProjectBreadCrumb from "@/views/projectCostLedger/detail/components/Proje
export default { export default {
name: "projectDetailHeader", name: "projectDetailHeader",
props: { props: {
module: String, current: String,
current: String breadCrumbTree: Array
}, },
components: { components: {
ProjectBreadCrumb ProjectBreadCrumb
}, },
data() { data() {
return { return {
isShowProjectCode: ["basicEngineeringInformation", "directCost", "feedSummary", "cost"] isShowProjectCode: ["basicEngineeringInformation", "directCost", "feedSummary", "cost"],
}; };
}, },
//可访问data属性 //可访问data属性
...@@ -48,7 +48,12 @@ export default { ...@@ -48,7 +48,12 @@ export default {
}, },
//方法集 //方法集
methods: { methods: {
breadCrumbTrigger(item) {
console.log(item);
if (item.path == "root") {
this.$router.push("/projectCostLedger");
}
}
}, },
} }
</script> </script>
......
<template>
<div class="project-menu-item-container">
</div>
</template>
<script>
export default {
name : "projectMenuItem",
data() {
return {
}
},
//可访问data属性
created(){
},
//计算集
computed:{
},
//方法集
methods:{
},
}
</script>
<style lang="scss" scoped>
.project-menu-item-container {
}
</style>
<template>
<div class="project-side-menu-container">
<el-menu mode="vertical" class="project-side-menu-instance">
<project-menu-item></project-menu-item>
</el-menu>
</div>
</template>
<script>
import ProjectMenuItem from "@/views/projectCostLedger/detail/components/ProjectSideMenu/ProjectMenuItem";
export default {
name: "projectSideMenu",
components: {
ProjectMenuItem
},
props: {
// 菜单树形结构对象
menuTree: {
type: Object,
required: false,
default: () => ({})
}
},
data() {
return {
};
},
//可访问data属性
created() {
},
//计算集
computed: {
allDisabled() {
return (!this.menuTree || !Object.keys(this.menuTree)?.length) ? true : false;
}
},
//方法集
methods: {
},
}
</script>
<style lang="scss" scoped>
.project-side-menu-container {
position: relative;
width: 100%;
height: 100%;
::v-deep .project-side-menu-instance {
width: 100%;
height: 100%;
border-right: 1px solid #eeeeee;
overflow: auto;
/* 重置一级二级菜单 高度行高 */
/* .el-submenu__title {
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%
);
}
} */
}
}
</style>
<template> <template>
<div class="project-cost-ledger-detail"> <div class="project-cost-ledger-detail">
<div class="project-cost-ledger-detail-inner"> <div class="project-cost-ledger-detail-inner">
<project-detail-header :module="module" :current="current"></project-detail-header> <project-detail-header :current="current" :breadCrumbTree="createProjectBreadCrumbTree"></project-detail-header>
<!-- tab切换栏 --> <!-- tab切换栏 -->
<dsk-tab-toggle v-model="current" :tabs="toggleTabs" @tabToggle="tabToggle"></dsk-tab-toggle> <dsk-tab-toggle v-model="current" :tabs="toggleTabs" @tabToggle="tabToggle"></dsk-tab-toggle>
<!-- tab切换组件容器 --> <!-- tab切换组件容器 -->
...@@ -36,6 +36,7 @@ import FeedSummary from "@/views/projectCostLedger/detail/components/FeedSummary ...@@ -36,6 +36,7 @@ import FeedSummary from "@/views/projectCostLedger/detail/components/FeedSummary
// 其他项目 // 其他项目
import OtherProjects from "@/views/projectCostLedger/detail/components/OtherProjects"; import OtherProjects from "@/views/projectCostLedger/detail/components/OtherProjects";
import { v4 } from "uuid"; import { v4 } from "uuid";
import { cloneDeep } from "lodash-es";
export default { export default {
name: "projectCostLedgerDetail", name: "projectCostLedgerDetail",
components: { components: {
...@@ -49,8 +50,7 @@ export default { ...@@ -49,8 +50,7 @@ export default {
data() { data() {
return { return {
projectID: "", projectID: "",
current: "otherItems", current: "",
module: "detail",
// 详情信息变量 // 详情信息变量
detailInfo: {}, detailInfo: {},
toggleTabs: [ toggleTabs: [
...@@ -107,7 +107,29 @@ export default { ...@@ -107,7 +107,29 @@ export default {
}, },
//计算集 //计算集
computed: { computed: {
createProjectBreadCrumbTree() {
try {
const _tempArray = cloneDeep(this.toggleTabs.map(item => {
item.path = item.value;
item.breadcrumbName = item.name;
return item;
}));
// 创建树形结构信息
const _temp = {
breadcrumbName: "项目成本台账",
childrenBreadCrumb: [{
breadcrumbName: "详情",
path: "detail",
triggerHandle: false,
childrenBreadCrumb: _tempArray
}],
};
return [_temp];
} catch (error) {
console.log(error);
}
}
}, },
//方法集 //方法集
methods: { methods: {
......
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