Commit bdfe36c4 authored by danfuman's avatar danfuman

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

Merge branch 'V20231129-中建一局二公司' of http://192.168.60.201/root/dsk-operate-sys into V20231129-中建一局二公司
parents 49841d11 75819ccd
......@@ -186,16 +186,14 @@ tenant:
- d_customer_tax_certificate
- f_supplier_limited
- f_ads_bsi_kpi_proj_two
- cb_account_summary
- cb_account_summary_actual
- cb_summary
- cb_summary_actual
- cb_cost_measure
- cb_cost_measure_actual
- cb_direct_expense
- cb_project_expense_summary
- cb_project_file
- cb_project_record
- cb_project_summary
- cb_project_summary_actual
- cb_quantity_summary
- cb_quantity_summary_actual
- cb_scene_expense_children
......
package com.dsk.component;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dsk.common.excel.ExcelUtils;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.service.CbProjectFileService;
import com.dsk.cscec.service.ICbQuantitySummaryService;
import com.dsk.oss.factory.OssFactory;
import com.dsk.system.domain.vo.SysOssVo;
import com.dsk.system.service.ISysOssService;
import org.apache.el.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 数据解析组件
*
* @Author lcl
* @Data 2024/2/7 17:43
*/
@Component
public class DataAnalysisComponent {
@Autowired
private ICbQuantitySummaryService quantitySummaryService;
@Autowired
private CbProjectFileService projectFileService;
@Autowired
private ISysOssService ossService;
@Resource
private TransactionTemplate transactionTemplate;
/**
* 工料汇总数据解析
*/
@Async
public void quantitySummaryDataAnalysis(CbProjectBaseBo bo) throws Exception {
//查询工料汇总导入文件
List<CbProjectFile> fileList = projectFileService.list(Wrappers.<CbProjectFile>lambdaQuery()
.eq(CbProjectFile::getProjectId, bo.getProjectId())
.eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY)
.eq(CbProjectFile::getCbStage, bo.getCbStage())
.in(CbProjectFile::getFileParseStatus, Arrays.asList(1, 3)));
if (ObjectUtils.isEmpty(fileList)) return;
//文件处理
for (CbProjectFile file : fileList) {
if (file.getDelFlag() == 0) {
//文件下载
InputStream inputStream = ossService.downFileIO(file.getFileOssId());
if (ObjectUtil.isNull(inputStream)) {
file.setFileParseStatus(3);
file.setFailRemark("文件数据不存在");
projectFileService.updateById(file);
break;
}
//解析数据
List<CbQuantitySummary> importList = new ExcelUtils<>(CbQuantitySummary.class).importExcelAllSheet(inputStream, 1);
if (importList.isEmpty()) {
file.setFileParseStatus(3);
file.setFailRemark("表格中不存在待导入数据!");
projectFileService.updateById(file);
break;
}
List<CbQuantitySummary> quantitySummaryList = importList.stream().parallel()
.filter(item -> !ObjectUtils.isEmpty(item.getCbName()))
.peek(item -> {
item.setProjectId(1L);
item.setCbStage(0);
item.setCbProjectFileId(1L);
}).collect(Collectors.toList());
if (quantitySummaryList.isEmpty()) {
throw new ServiceException("表格中不存在有效数据数据!");
}
transactionTemplate.execute(status -> {
try {
//分批次插入
if (quantitySummaryList.size() > 1000) {
int index = 0;
int sum = quantitySummaryList.size();
while (index < sum) {
List<CbQuantitySummary> divideList = quantitySummaryList.subList(index, Math.max((index + 1) * 1000, sum));
boolean b = quantitySummaryService.saveBatch(divideList);
if (!b) {
throw new ServiceException("数据插入失败!");
}
index += 1000;
}
} else {
boolean b = quantitySummaryService.saveBatch(quantitySummaryList);
if (!b) {
throw new ServiceException("数据插入失败!");
}
}
file.setFileParseStatus(2);
boolean b = projectFileService.updateById(file);
if (!b) {
throw new ServiceException("文件状态更新失败!");
}
} catch (Exception e) {
status.setRollbackOnly();
file.setFileParseStatus(3);
file.setFailRemark(e.getMessage());
projectFileService.updateById(file);
}
return Boolean.TRUE;
});
} else {
quantitySummaryService.remove(Wrappers.<CbQuantitySummary>lambdaQuery().eq(CbQuantitySummary::getCbProjectFileId, file.getId()));
projectFileService.removeById(file);
}
}
}
}
......@@ -21,25 +21,21 @@ public interface CbProjectConstants {
*/
Integer CB_STAGE_TO_SOLID = 2;
/**
* 项目文件状态:未上传
* 项目文件状态:准备中
*/
Integer PROJECT_FILE_STATUS_NOT_UPLOAD = 0;
/**
* 项目文件状态:待解析
*/
Integer PROJECT_FILE_STATUS_NOT_PARSE = 1;
Integer PROJECT_FILE_STATUS_PREPARING = 0;
/**
* 项目文件状态:解析中
*/
Integer PROJECT_FILE_STATUS_PARSING = 2;
Integer PROJECT_FILE_STATUS_PARSING = 1;
/**
* 项目文件状态:解析成功
*/
Integer PROJECT_FILE_STATUS_PARSE_SUCCESS = 3;
Integer PROJECT_FILE_STATUS_PARSE_SUCCESS = 2;
/**
* 项目文件状态:解析失败
*/
Integer PROJECT_FILE_STATUS_PARSE_FAIL = 4;
Integer PROJECT_FILE_STATUS_PARSE_FAIL = 3;
/**
* 删除状态:未删除
*/
......@@ -57,34 +53,36 @@ public interface CbProjectConstants {
*/
Integer NOT_GET_PROJECT_DETAIL = 1;
//成本类型(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总、6:未确定
//成本类型(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
/**
* 成本类型:直接费成本
*/
Integer CB_TYPE_DIRECT_EXPENSE = 0;
String CB_TYPE_DIRECT_EXPENSE_NAME = "直接费成本";
/**
* 成本类型:工料汇总
*/
Integer CB_TYPE_QUANTITY_SUMMARY = 1;
String CB_TYPE_QUANTITY_SUMMARY_NAME = "工料汇总";
/**
* 成本类型:措施项目
*/
Integer CB_TYPE_MEASURE_PROJECT = 2;
String CB_TYPE_MEASURE_PROJECT_NAME = "措施项目";
/**
* 成本类型:其他项目
*/
Integer CB_TYPE_OTHER_PROJECT = 3;
String CB_TYPE_OTHER_PROJECT_NAME = "其他项目";
/**
* 成本类型:现场经费
*/
Integer CB_TYPE_SCENE_EXPENSE = 4;
String CB_TYPE_SCENE_EXPENSE_NAME = "现场经费";
/**
* 成本类型:成本汇总
*/
Integer CB_TYPE_ACCOUNT_SUMMARY = 5;
/**
* 成本类型:未确定
*/
Integer CB_TYPE_NOT_CONFIRM = 6;
Integer CB_TYPE_SUMMARY = 5;
String CB_TYPE_SUMMARY_NAME = "成本汇总";
}
package com.dsk.cscec.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.dsk.common.annotation.Log;
import com.dsk.common.constant.GlobalConstants;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.R;
import com.dsk.common.core.domain.entity.SysDictData;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.enums.BusinessType;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.poi.ExcelUtil;
import com.dsk.common.utils.redis.RedisUtils;
import com.dsk.cscec.domain.CbCostMeasure;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualPushBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import com.dsk.cscec.domain.vo.CbCostMeasuresImportVo;
import com.dsk.cscec.domain.vo.CbCostMeasuresItemVo;
import com.dsk.cscec.listener.ProjectCostMeasureImportListener;
import com.dsk.cscec.service.ICbCostMeasureService;
import com.dsk.system.domain.vo.SysUserImportVo;
import com.dsk.system.listener.SysUserImportListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 措施费导入
*
* @author tanyang
* @create 2024-02-04 11:44
**/
@RequestMapping("/cb/cost/measures")
@RestController
public class CbCostMeasureController {
@Autowired
private ICbCostMeasureService cbCostMeasureService;
/**
* 措施费一级大类
* 根据项目查询措施费一级大类
*
* @param projectId 项目ID
* @return {@link R}<{@link List}<{@link Map}<{@link String}, {@link Object}>>>
*/
@SaIgnore
@GetMapping(value = "/type/{projectId}")
public R<List<Map<String, Object>>> dictType(@PathVariable Long projectId) {
List<Map<String, Object>> data = cbCostMeasureService.listByLevel(projectId,0);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}
return R.ok(data);
}
/**
* 措施费列表
* 查询措施费列表
*
* @param cbCostMeasure CB成本衡量标准
* @return {@link R}<{@link List}<{@link CbCostMeasureActualVo}>>
*/
// @SaCheckPermission("cb:costmeasures:list")
@SaIgnore
@GetMapping("/list")
public R<List<CbCostMeasureActualVo>> list(CbCostMeasureActualBo cbCostMeasure) {
List<CbCostMeasureActualVo> data= cbCostMeasureService.selectDataList(cbCostMeasure);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}
return R.ok(data);
}
/**
* 批量保存或修改每月措施费
*/
// @SaCheckPermission("cb:costmeasures:actual:saveBatch")
@SaIgnore
@PostMapping("/saveBatch")
public R saveBatch(@RequestBody List<CbCostMeasureActualSaveBo> boList) {
Assert.notEmpty(boList,"措施费填写信息不能为空!");
cbCostMeasureService.saveBatchCostMeasureActual(boList);
return R.ok();
}
/**
* 推送工程量
* 措施费-推送每月工程量
*
* @param pushBo 推送BO
* @return {@link R}<{@link List}<{@link CbCostMeasureActualVo}>>
*/
// @SaCheckPermission("cb:costmeasures:actual:push")
@SaIgnore
@PostMapping("/push/project/volume")
public R pushProjectVolume(@RequestBody CbCostMeasureActualPushBo pushBo) {
Assert.notNull(pushBo,"推送工程量信息不能为空!");
cbCostMeasureService.pushCostMeasureActual(pushBo);
return R.ok();
}
/**
* 获取批量措施费列表
*/
@Log(title = "措施费导出", businessType = BusinessType.EXPORT)
// @SaCheckPermission("system:user:export")
@PostMapping("/export")
public void exportProjectMeasures(HttpServletResponse response) {
String BATCH_IMPORT_FAIL_USERS = GlobalConstants.GLOBAL_REDIS_KEY + "batch_import_fail_users";
String key = BATCH_IMPORT_FAIL_USERS + LoginHelper.getUserId();
ExcelUtil.exportExcel(RedisUtils.getCacheList(key), "措施费", CbCostMeasuresImportVo.class, response);
RedisUtils.deleteObject(key);
}
/**
* 导入数据
*
* @param file 导入文件
* @param projectId 项目id
*/
// @SaIgnore
@Log(title = "措施费导入", businessType = BusinessType.IMPORT)
// @SaCheckPermission("system:user:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, Long projectId) throws Exception {
cbCostMeasureService.importExcelData(file,projectId);
return R.ok();
}
/**
* 导入数据
*
* @param file 导入文件
* @param projectId 项目id
*/
@SaIgnore
@Log(title = "措施费汇总导入", businessType = BusinessType.IMPORT)
// @SaCheckPermission("system:user:import")
@PostMapping(value = "/summary/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importSummaryData(@RequestPart("file") MultipartFile file, Long projectId) throws Exception {
Integer dataType=2;
cbCostMeasureService.importExcelSummaryData(file,projectId,dataType);
return R.ok();
}
public static void main(String[] args) throws FileNotFoundException {
List list =new ArrayList<>();
File file=new File("E:\\dingding\\202401\\导入表格\\措施费\\大型机械费.xlsx");
FileInputStream inputStream=new FileInputStream(file);
ExcelResult<CbCostMeasuresImportVo> result = ExcelUtil.importExcel(inputStream, CbCostMeasuresImportVo.class, new ProjectCostMeasureImportListener(1L,1));
String analysis = result.getAnalysis();
List<CbCostMeasuresImportVo> list1 = result.getList();
System.out.println(">>>>>>>>>>"+analysis);
// System.out.println(JSONUtil.toJsonStr(list));
}
}
package com.dsk.cscec.controller;
import com.dsk.common.core.controller.BaseController;
import com.dsk.common.core.domain.R;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.vo.CbGainLossAnalysisListVo;
import com.dsk.cscec.service.ICbGainLossAnalysisService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 成本-盈亏分析对比
*
* @Author lcl
* @Data 2024/2/18 14:01
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/cb/gain/loss/analysis")
public class CbGainLossAnalysisController extends BaseController {
private final ICbGainLossAnalysisService baseService;
/**
* 数据列表
*/
@GetMapping("/list")
public R<List<CbGainLossAnalysisListVo>> getList(CbSummaryActualListBo bo) {
return R.ok(baseService.getList(bo));
}
}
package com.dsk.cscec.controller;
import cn.hutool.core.lang.Assert;
import com.dsk.common.annotation.Log;
import com.dsk.common.core.controller.BaseController;
import com.dsk.common.core.domain.R;
import com.dsk.common.enums.BusinessType;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.bo.AddProjectFileUploadBo;
import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo;
import com.dsk.cscec.service.CbProjectFileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dsk.system.domain.vo.SysOssVo;
import com.dsk.system.service.ISysOssService;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* 项目成本文件表(CbProjectFile)表控制层
......@@ -14,13 +32,54 @@ import javax.annotation.Resource;
*/
@RestController
@RequestMapping("cbProjectFile")
public class CbProjectFileController {
public class CbProjectFileController extends BaseController {
/**
* 服务对象
*/
@Resource
private CbProjectFileService baseService;
@Resource
private ISysOssService iSysOssService;
/**
* 上传项目台账文件
*/
@Log(title = "项目台账上传OSS对象存储", businessType = BusinessType.INSERT)
@PostMapping(value = "/uploadCbProjectFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Map<String, String>> uploadCbProjectFile(@Validated @ModelAttribute AddProjectFileUploadBo fileUploadBo) throws UnsupportedEncodingException {
MultipartFile file = fileUploadBo.getFile();
Assert.notNull(file, "上传文件不能为空");
SysOssVo oss = iSysOssService.upload(file);
//添加项目上传文件记录
CbProjectFile cbProjectFile;
try {
cbProjectFile = baseService.addProjectFile(fileUploadBo, oss);
} catch (ServiceException e) {
//删除oss中的文件
iSysOssService.deleteWithValidByIds(Collections.singletonList(oss.getOssId()), true);
throw e;
}
Map<String, String> map = new HashMap<>(2);
map.put("fileId", cbProjectFile.getId().toString());
map.put("fileName", oss.getOriginalName());
map.put("fileOssId", oss.getOssId().toString());
map.put("fileOssUrl", oss.getUrl());
return R.ok(map);
}
}
/**
* 删除项目台账文件
*/
@DeleteMapping("/deleteCbProjectFile/{fileId}")
public R<Void> deleteCbProjectFile(@NotNull(message = "文件ID不能为空") @PathVariable Long fileId) {
return toAjax(baseService.deleteProjectFile(fileId));
}
/**
* 获取项目文件上传详情
*/
@GetMapping("/getProjectFileUploadDetail/{projectId}")
public R<QueryProjectFileUploadDetailVo> getProjectFileUploadDetail(@NotNull(message = "项目ID不能为空") @PathVariable Long projectId) {
return R.ok(baseService.getProjectFileUploadDetail(projectId));
}
}
\ No newline at end of file
package com.dsk.cscec.controller;
import cn.hutool.core.lang.Assert;
import com.dsk.common.core.controller.BaseController;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.R;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.AddCbProjectBo;
import com.dsk.cscec.domain.bo.AddNewCbProjectBo;
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.IDProjectService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 项目台账表(CbProjectRecord)表控制层
......@@ -13,12 +29,92 @@ import javax.annotation.Resource;
*/
@RestController
@RequestMapping("cbProjectRecord")
public class CbProjectRecordController {
public class CbProjectRecordController extends BaseController {
/**
* 服务对象
*/
@Resource
private CbProjectRecordService baseService;
@Resource
private IDProjectService dProjectService;
/**
* 校验项目编码是否存在
*/
@GetMapping("/checkProjectCodeExist/{projectCode}")
public R<Boolean> checkProjectCodeExist(@NotBlank(message = "项目编码不能为空") @PathVariable String projectCode) {
return R.ok(dProjectService.checkProjectCodeExist(projectCode));
}
/**
* 新增项目
*/
@PostMapping("/addProject")
public R<CbProjectRecord> addProject(@Validated @RequestBody AddCbProjectBo addCbProjectBo) {
CbProjectRecord projectRecord = baseService.addProject(addCbProjectBo);
Assert.notNull(projectRecord, "新增项目失败,请联系管理员");
return R.ok(projectRecord);
}
/**
* 根据项目文件导入数据
*/
@PostMapping("/importData/{projectId}")
public R<Void> importData(@NotNull(message = "项目ID不能为空") @PathVariable Long projectId) throws Exception {
baseService.importData(projectId);
return R.ok("已开始解析成本数据,过程需3~10分钟,稍后可到项目列表查看导入结果");
}
/**
* 获取项目台账列表
*/
@GetMapping("/getProjectList")
public TableDataInfo<ProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery) {
return baseService.getProjectList(searchBo, pageQuery);
}
/**
* 修改项目信息
*/
@PutMapping("/editProjectInfo")
public R<Void> editProjectInfo(@Validated @RequestBody EditProjectInfoBo editBo) {
return toAjax(baseService.editProjectInfo(editBo));
}
/**
* 获取新阶段项目可选成本阶段
*/
@GetMapping("/getProjectAvailableCbStage/{relatedId}")
public R<List<Integer>> getProjectAvailableCbStage(@NotNull(message = "关联ID不能为空") @PathVariable Long relatedId) {
return R.ok(baseService.getProjectAvailableCbStage(relatedId));
}
/**
* 新增新阶段项目
*/
@PostMapping("/addNewStageProject")
public R<CbProjectRecord> addNewStageProject(@Validated @RequestBody AddNewCbProjectBo newProjectBo) {
return R.ok(baseService.addNewStageProject(newProjectBo));
}
/**
* 获取草稿弹窗列表
*/
@GetMapping("/getDraftDialogList")
public R<List<CbProjectRecord>> getDraftDialogList() {
List<CbProjectRecord> draftList = baseService.getDraftDialogList();
if (draftList.isEmpty()) {
return R.ok("暂无草稿记录");
}
return R.ok(draftList);
}
/**
* 删除草稿
*/
@DeleteMapping("/deleteDraft/{projectId}")
public R<Void> deleteDraft(@NotNull(message = "项目ID不能为空") @PathVariable Long projectId) {
return toAjax(baseService.deleteDraft(projectId));
}
}
package com.dsk.cscec.controller;
import com.dsk.common.annotation.RepeatSubmit;
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.CbQuantitySummaryActual;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo;
import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo;
import com.dsk.cscec.service.ICbQuantitySummaryService;
import com.dsk.system.domain.vo.SysUserImportVo;
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 java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
/**
* 成本-工料汇总基本表(CbQuantitySummary)表控制层
......@@ -35,10 +30,11 @@ public class CbQuantitySummaryController extends BaseController {
/**
* 工料汇总科目树
*
* @return
*/
@GetMapping(value = "/subjectTree")
public R<Map<String, Object>> subjectTree(@PathVariable CbProjectBaseBo bo){
public R<Map<String, Object>> subjectTree(CbProjectBaseBo bo) {
return R.ok(baseService.subjectTree(bo));
}
......@@ -46,30 +42,36 @@ public class CbQuantitySummaryController extends BaseController {
* 已记录月份集合
*/
@GetMapping(value = "/monthList")
public R<List<String>> monthList(@PathVariable CbProjectBaseBo bo){
public R<List<String>> monthList(CbQuantitySummaryListBo bo) {
return R.ok(baseService.monthList(bo));
}
/**
* 数据导入
* 科目月份列表
*/
@PostMapping(value = "/importData")
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("表格中不存在待导入数据!");
@GetMapping(value = "/subjectList")
public R<List<CbQuantitySummaryListVo>> subjectList(CbQuantitySummaryListBo bo) {
return R.ok(baseService.subjectList(bo));
}
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("表格中不存在有效数据数据!");
/**
* 更新月成本信息
*/
@PutMapping(value = "/updateActual")
@RepeatSubmit
public R<Void> updateActual(@RequestBody List<CbQuantitySummaryActual> list) {
baseService.updateActual(list);
return R.ok();
}
return toAjax(baseService.saveBatch(importList));
/**
* 数据推送
*/
@PutMapping(value = "/pushData")
@RepeatSubmit
public R<Void> pushData(@RequestBody CbQuantitySummaryActual bo) {
baseService.pushData(bo);
return R.ok();
}
}
......
package com.dsk.cscec.controller;
import cn.hutool.core.bean.BeanUtil;
import com.dsk.common.core.controller.BaseController;
import com.dsk.common.core.domain.R;
import com.dsk.common.utils.poi.ExcelUtil;
import com.dsk.cscec.domain.bo.CbSummaryActualBo;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.domain.vo.CbSummaryCostAccountExportVo;
import com.dsk.cscec.domain.vo.CbSummaryProjectExportVo;
import com.dsk.cscec.service.CbSummaryService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
* 成本汇总(CbSummary)表控制层
......@@ -24,4 +36,71 @@ public class CbSummaryController extends BaseController {
private CbSummaryService cbSummaryService;
/**
* 成本汇总左侧一级数据列表
*
* @param bo
* @return
*/
@GetMapping("/cbNameList")
public R<List<Map<String, Object>>> getCbNameList(CbSummaryBo bo) {
return R.ok(cbSummaryService.getCbNameList(bo));
}
/**
* 成本汇总数据列表
* @param bo
* @return
*/
@GetMapping("/list")
public R<List<CbSummaryActualListVo>> getList(CbSummaryActualListBo bo) {
return R.ok(cbSummaryService.getActualList(bo));
}
/**
* 已添加成本月份
*
* @param bo
* @return
*/
@GetMapping("/expenseDateList")
public R<List<String>> getExpenseDateList(@Validated CbSummaryBo bo) {
return R.ok(cbSummaryService.getExpenseDateList(bo));
}
/**
* 编辑成本
*
* @param boList
* @return
*/
@PutMapping("/editActual")
public R editActual(@RequestBody List<CbSummaryActualBo> boList) {
return cbSummaryService.insertOrUpdateActual(boList) == true ? R.ok() : R.fail();
}
//锁定成本前提示未填项(按一级大类)
//锁定成本
/**
* 导出excel-按月导出所有
* @param bo
* @param response
*/
@PostMapping("/export")
public void export(CbSummaryActualListBo bo, HttpServletResponse response) {
List<CbSummaryActualListVo> actualListVoList = cbSummaryService.getAll(bo);
if(bo.getCbType()==1){
List<CbSummaryProjectExportVo> list = BeanUtil.copyToList(actualListVoList,CbSummaryProjectExportVo.class);
ExcelUtil.exportExcel(list, "成本汇总按项目汇总"+bo.getExpenseDate(), CbSummaryProjectExportVo.class, response);
}else {
List<CbSummaryCostAccountExportVo> list = BeanUtil.copyToList(actualListVoList,CbSummaryCostAccountExportVo.class);
ExcelUtil.exportExcel(list, "成本汇总按成本科目汇总"+bo.getExpenseDate(), CbSummaryCostAccountExportVo.class, response);
}
}
//导入
}
package com.dsk.cscec.domain;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 项目每月实际措施费
*/
@Data
@TableName(value="cb_cost_measure")
public class CbCostMeasure {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 项目ID
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 父项id
*/
private Long parentId;
/**
* 层级数
*/
private Integer level;
private String number;
private String no;
/**
* 清单内容
*/
private String itemContent;
/**
* 工作内容、做法/规格型号/施工现场配置说明
*/
private String workContent;
/**
* 单位
*/
private String unit;
/**
* 工程量
*/
private BigDecimal quantity;
/**
* 不含税单价
*/
private String unitPriceExcludingTax;
/**
* 使用时间
*/
private String usageTime;
/**
* 不含税合价
*/
private String amountExcludingTax;
/**
* 税率(%)
*/
private String taxRate;
/**
* 含税合价
*/
private String amountIncludingTax;
/**
* 摊销比例(%)
*/
private String amortizationRatio;
/**
* 摊销后不含税合价
*/
private String amountExcludeTaxAmortized;
/**
* 摊销后含税合价
*/
private String amountIncludeTaxAmortized;
/**
* 税金(元)
*/
private String taxAmount;
/**
* 备注
*/
private String remarks;
/**
* 成本科目
*/
private String costSubject;
/**
* 税金类型
*/
private String taxType;
/**
* 数据来源(0:导入,1:手动添加)
*/
private Integer dataSource;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
\ No newline at end of file
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.math.BigDecimal;
import java.util.Date;
import lombok.Data;
@Data
@TableName(value = "cb_cost_measure_actual")
public class CbCostMeasureActual {
/**
* 主键
*/
@TableId(value = "id", type = IdType.INPUT)
private Long id;
/**
* 计划成本措施费id
*/
@TableField(value = "plan_measure_id")
private Long planMeasureId;
/**
* 本月发生成本比例
*/
@TableField(value = "month_cost_rate")
private BigDecimal monthCostRate;
/**
* 成本合价
*/
@TableField(value = "cost_effective")
private BigDecimal costEffective;
/**
* 截止本月工程量
*/
@TableField(value = "current_project_volume")
private BigDecimal currentProjectVolume;
/**
* 推送工程量
*/
@TableField(value = "submit_project_volume")
private BigDecimal submitProjectVolume;
/**
* 年月
*/
@TableField(value = "`month`")
private String month;
/**
* 推送时间
*/
@TableField(value = "push_time")
private Date pushTime;
/**
* 推送数据json
*/
@TableField(value = "push_data_json")
private String pushDataJson;
/**
* 是否删除
*/
@TableField(value = "del_flag")
private Integer delFlag;
/**
* 修改人
*/
@TableField(value = "update_user")
private String updateUser;
/**
* 修改人id
*/
@TableField(value = "update_id")
private Long updateId;
/**
* 创建时间
*/
@TableField(value = "create_time")
private Date createTime;
/**
* 更新时间
*/
@TableField(value = "update_time")
private Date updateTime;
public static final String COL_ID = "id";
public static final String COL_PLAN_MEASURE_ID = "plan_measure_id";
public static final String COL_MONTH_COST_RATE = "month_cost_rate";
public static final String COL_COST_EFFECTIVE = "cost_effective";
public static final String COL_CURRENT_PROJECT_VOLUME = "current_project_volume";
public static final String COL_SUBMIT_PROJECT_VOLUME = "submit_project_volume";
public static final String COL_MONTH = "month";
public static final String COL_PUSH_TIME = "push_time";
public static final String COL_PUSH_DATA_JSON = "push_data_json";
public static final String COL_DEL_FLAG = "del_flag";
public static final String COL_UPDATE_USER = "update_user";
public static final String COL_UPDATE_ID = "update_id";
public static final String COL_CREATE_TIME = "create_time";
public static final String COL_UPDATE_TIME = "update_time";
}
\ No newline at end of file
......@@ -16,7 +16,7 @@ public class CbProjectExpenseSummary {
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.INPUT)
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
......
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;
......@@ -31,7 +32,7 @@ public class CbProjectFile extends BaseEntity implements Serializable {
*/
private Integer cbStage;
/**
* 成本类型(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
* 成本类型(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
*/
private Integer cbType;
/**
......@@ -41,13 +42,13 @@ public class CbProjectFile extends BaseEntity implements Serializable {
/**
* OSS文件ID
*/
private String fileOssId;
private Long fileOssId;
/**
* OSS文件路径
*/
private String fileOssUrl;
/**
* 文件解析状态(0:待解析、1:解析中、2:解析成功、3:解析失败)
* 项目文件状态(0:待解析、1:解析中、2:解析成功、3:解析失败)
*/
private Integer fileParseStatus;
/**
......@@ -55,7 +56,8 @@ public class CbProjectFile extends BaseEntity implements Serializable {
*/
private String failRemark;
/**
* 删除状态(0:否、2:是)
* 删除状态(0:否、1:待删除、2:是)
*/
@TableLogic(value = "0", delval = "2")
private Integer delFlag;
}
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;
......@@ -23,21 +24,29 @@ public class CbProjectRecord extends BaseEntity implements Serializable {
@TableId(value = "id")
private Long id;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
* 关联ID(关联多个阶段)
*/
private Integer cbStage;
private Long relatedId;
/**
* 项目名称
*/
private String projectName;
/**
* 项目文件状态(0:待解析、1:解析中、2:解析成功、3:解析失败)
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目文件状态(0:准备中、1:解析中、2:解析成功、3:解析失败)
*/
private Integer projectFileStatus;
/**
* IPM项目编码
*/
private String ipmProjectNo;
/**
* 是否获取项目详情(0:是、1:否)
*/
private Integer isGetProjectDetail;
/**
* 文件名称
*/
......@@ -45,5 +54,6 @@ public class CbProjectRecord extends BaseEntity implements Serializable {
/**
* 删除状态(0:否、2:是)
*/
@TableLogic(value = "0", delval = "2")
private Integer delFlag;
}
......@@ -3,6 +3,7 @@ package com.dsk.cscec.domain;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
......@@ -32,7 +33,7 @@ public class CbQuantitySummary implements Serializable {
* 序号
*/
@Excel(name = "序号")
private String number;
private Integer number;
/**
* 成本阶段(0:标前成本 1:标后成本 2:转固成本)
*/
......@@ -130,6 +131,15 @@ public class CbQuantitySummary implements Serializable {
* 创建时间
*/
private Date createTime;
/**
* 项目成本文件id
*/
private Long cbProjectFileId;
/**
* 删除状态(0:否、2:是)
*/
@TableLogic(value = "0", delval = "2")
private Integer delFalg;
}
......@@ -2,6 +2,7 @@ package com.dsk.cscec.domain;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
......@@ -21,8 +22,8 @@ public class CbQuantitySummaryActual implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id")
private Long id;
@TableId(value = "id", type = IdType.INPUT)
private String id;
/**
* 成本汇总基本数据id
*/
......@@ -32,9 +33,9 @@ public class CbQuantitySummaryActual implements Serializable {
*/
private Double quantities;
/**
* 单位
* 本月用料单位
*/
private String unit;
private String quantitiesUnit;
/**
* 换算后本月用料
*/
......@@ -47,6 +48,9 @@ public class CbQuantitySummaryActual implements Serializable {
* 采购单价
*/
private Double purchaseUnitPrice;
/**
* 创建时间
*/
private Date createTime;
/**
* 推送时间
......@@ -57,9 +61,21 @@ public class CbQuantitySummaryActual implements Serializable {
*/
private String recordDate;
/**
* 推送数据json
* 推送工程量
*/
private Double pushQuantities;
/**
* IPM项目编码
*/
private String ipmProjectCode;
/**
* IPM合同编码
*/
private String ipmContractCode;
/**
* IPM作业编码
*/
private String pushDataJson;
private String ipmBizCode;
}
......@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
......@@ -27,11 +28,11 @@ public class CbSummaryActual implements Serializable {
/**
* 本月费用(含税)
*/
private Double taxInclusiveExpense;
private BigDecimal taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
private Double taxExclusiveExpense;
private BigDecimal taxExclusiveExpense;
/**
* 费用日期
*/
......
package com.dsk.cscec.domain.bo;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author sxk
* @date 2024.02.05
* @time 15:26
*/
@Data
public class AddCbProjectBo {
/**
* 项目名称
*/
private String projectName;
/**
* IPM项目编码
*/
private String ipmProjectNo;
/**
* 是否获取项目详情(0:否、1:是)
*/
@NotNull(message = "是否获取项目详情不能为空")
private Integer isGetProjectDetail;
/**
* 文件名称
*/
private String projectFileName;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
@NotNull(message = "未选择成本阶段")
private Integer cbStage;
}
package com.dsk.cscec.domain.bo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
/**
* @author sxk
* @date 2024.02.19
* @time 14:22
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class AddNewCbProjectBo extends EditProjectInfoBo {
/**
* 关联ID(关联多个阶段)
*/
@NotNull(message = "关联ID不能为空")
private Long relatedId;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
@NotNull(message = "成本阶段不能为空")
private Integer cbStage;
}
package com.dsk.cscec.domain.bo;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
/**
* @author sxk
* @date 2024.02.06
* @time 16:07
*/
@Data
public class AddProjectFileUploadBo {
/**
* 文件
*/
private MultipartFile file;
/**
* 项目ID
*/
@NotNull(message = "项目ID不能为空")
private Long projectId;
/**
* 成本类型
*/
@NotNull(message = "成本类型不能为空")
private Integer cbType;
}
package com.dsk.cscec.domain.bo;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class CbCostMeasureActualBo {
/**
* 措施费用项id
*/
private Long id;
/**
* 年月
*/
private String month;
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
}
\ No newline at end of file
package com.dsk.cscec.domain.bo;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class CbCostMeasureActualPushBo {
/**
* 主键
*/
private Long id;
/**
* 截止本月工程量
*/
@TableField(value = "current_project_volume")
private BigDecimal currentProjectVolume;
/**
* 推送工程量
*/
@TableField(value = "submit_project_volume")
private BigDecimal submitProjectVolume;
/**
* 年月
*/
@TableField(value = "`month`")
private String month;
/**
* 推送时间
*/
@TableField(value = "push_time")
private Date pushTime;
/**
* 推送数据json
*/
@TableField(value = "push_data_json")
private String pushDataJson;
/**
* IPM项目编码
*/
private String ipmProjectCode;
/**
* IPM合同编码
*/
private String ipmContractCode;
/**
* IPM作业编码
*/
private String ipmBizCode;
}
\ No newline at end of file
package com.dsk.cscec.domain.bo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class CbCostMeasureActualSaveBo {
/**
* 主键
*/
private Long id;
/**
* 计划成本措施费id
*/
@TableField(value = "plan_measure_id")
private Long planMeasureId;
/**
* 本月发生成本比例
*/
@TableField(value = "month_cost_rate")
private BigDecimal monthCostRate;
/**
* 成本合价
*/
@TableField(value = "cost_effective")
private BigDecimal costEffective;
/**
* 截止本月工程量
*/
@TableField(value = "current_project_volume")
private BigDecimal currentProjectVolume;
/**
* 推送工程量
*/
@TableField(value = "submit_project_volume")
private BigDecimal submitProjectVolume;
/**
* 年月
*/
@TableField(value = "`month`")
private String month;
/**
* 推送时间
*/
@TableField(value = "push_time")
private Date pushTime;
/**
* 推送数据json
*/
@TableField(value = "push_data_json")
private String pushDataJson;
/**
* 修改人
*/
@TableField(value = "update_user")
private String updateUser;
/**
* 修改人id
*/
@TableField(value = "update_id")
private String updateId;
}
\ No newline at end of file
package com.dsk.cscec.domain.bo;
import lombok.Data;
/**
* @author sxk
* @date 2024.02.18
* @time 15:04
*/
@Data
public class CbProjectSearchBo {
/**
* 项目名称
*/
private String projectName;
/**
* IPM项目编码
*/
private String ipmProjectNo;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目文件状态(1:解析中、2:解析成功、3:解析失败)
*/
private Integer projectFileStatus;
}
package com.dsk.cscec.domain.bo;
import lombok.Data;
/**
* @Author lcl
* @Data 2024/2/6 13:37
*/
@Data
public class CbQuantitySummaryListBo extends CbProjectBaseBo {
/**
* 成本科目
*/
private String cbSubjectName;
/**
* 记录月份
*/
private String recordDate;
}
package com.dsk.cscec.domain.bo;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 成本汇总-每月费用Bo
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummaryActualBo extends BaseEntity {
/**
* 费用id
*/
private Long id;
/**
* 成本汇总id
*/
@NotNull(message = "成本汇总id不能为空")
private Long cbSummaryId;
/**
* 本月费用(含税)
*/
private BigDecimal taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
private BigDecimal taxExclusiveExpense;
/**
* 费用日期
*/
@NotEmpty(message = "费用日期不能为空")
private String expenseDate;
}
package com.dsk.cscec.domain.bo;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
/**
* 成本汇总-列表查询Bo
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummaryActualListBo extends BaseEntity {
/**
* 主键id
*/
private Long id;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType;
/**
* 费用日期
*/
private String expenseDate;
}
package com.dsk.cscec.domain.bo;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
/**
* 成本汇总Bo
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummaryBo extends BaseEntity {
/**
* 主键id
*/
private Long id;
/**
* 父级id
*/
private Long parentId;
/**
* 层级
*/
private Integer level;
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 项目成本文件id
*/
private Long cbProjectFileId;
/**
* 成本类型(1项目汇总,2成本科目汇总)
*/
private Integer cbType;
}
package com.dsk.cscec.domain.bo;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author sxk
* @date 2024.02.08
* @time 16:07
*/
@Data
public class EditProjectInfoBo {
/**
* 项目ID
*/
@NotNull(message = "项目ID不能为空")
private Long projectId;
/**
* 项目名称
*/
private String projectName;
/**
* IPM项目编码
*/
private String ipmProjectNo;
/**
* 是否获取项目详情(0:否、1:是)
*/
@NotNull(message = "是否获取项目详情不能为空")
private Integer isGetProjectDetail;
/**
* 文件名称
*/
private String projectFileName;
}
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
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 lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class CbCostMeasureActualVo {
/**
* 主键id
*/
private Long id;
/**
* 序号
*/
private String number;
/**
* 清单内容
*/
private String itemContent; // 清单内容
/**
* 工作内容
*/
private String workContent; // 工作内容、做法/规格型号/施工现场配置说明
/**
* 单位
*/
private String unit; // 单位
/**
* 工程量
*/
private BigDecimal quantity; // 工程量
/**
* 不含税单价
*/
private String unitPriceExcludingTax; // 不含税单价
/**
* 使用时间
*/
private String usageTime; // 使用时间
/**
* 不含税合价
*/
private String amountExcludingTax; //
/**
* 税率(%)
*/
private String taxRate; // 税率(%)
/**
* 含税合价
*/
private String amountIncludingTax; //
/**
* 摊销比例(%)
*/
private String amortizationRatio; //
/**
* 摊销后不含税合价
*/
private String amountExcludeTaxAmortized; //
/**
* 摊销后含税合价
*/
private String amountIncludeTaxAmortized; //
/**
* 税金(元)
*/
private String taxAmount; //
/**
* 备注
*/
private String remarks; //
/**
* 成本科目
*/
private String costSubject; // 成本科目
/**
* 税金类型
*/
private String taxType; //
/**
* 计划成本措施费id
*/
private Long planMeasureId;
/**
* 本月发生成本比例
*/
private BigDecimal monthCostRate;
/**
* 成本合价
*/
private BigDecimal costEffective;
/**
* 截止本月工程量
*/
private BigDecimal currentProjectVolume;
/**
* 推送工程量
*/
private BigDecimal submitProjectVolume;
/**
* 年月
*/
private String month;
/**
* 推送时间
*/
private Date pushTime;
/**
* 修改人
*/
@TableField(value = "update_user")
private String updateUser;
/**
* 修改人id
*/
@TableField(value = "update_id")
private String updateId;
/**
* 创建时间
*/
@TableField(value = "create_time")
private Date createTime;
/**
* 更新时间
*/
@TableField(value = "update_time")
private Date updateTime;
public static final String COL_ID = "id";
public static final String COL_PLAN_MEASURE_ID = "plan_measure_id";
public static final String COL_MONTH_COST_RATE = "month_cost_rate";
public static final String COL_COST_EFFECTIVE = "cost_effective";
public static final String COL_CURRENT_PROJECT_VOLUME = "current_project_volume";
public static final String COL_SUBMIT_PROJECT_VOLUME = "submit_project_volume";
public static final String COL_MONTH = "month";
public static final String COL_PUSH_TIME = "push_time";
public static final String COL_PUSH_DATA_JSON = "push_data_json";
public static final String COL_DEL_FLAG = "del_flag";
public static final String COL_UPDATE_USER = "update_user";
public static final String COL_UPDATE_ID = "update_id";
public static final String COL_CREATE_TIME = "create_time";
public static final String COL_UPDATE_TIME = "update_time";
}
\ No newline at end of file
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 措施费导入数据
*
* @author tanyang
* @create 2024-02-04 13:49
**/
@Data
public class CbCostMeasuresImportVo {
@ExcelProperty(value = "序号")
private String number; // 清单内容
@ExcelProperty(value = "清单内容")
private String itemContent; // 清单内容
@ExcelProperty(value = "工作内容")
private String workContent; // 工作内容、做法/规格型号/施工现场配置说明
@ExcelProperty(value = "单位")
private String unit; // 单位
@ExcelProperty(value = "工程量")
private BigDecimal quantity; // 工程量
@ExcelProperty(value = "不含税单价")
private String unitPriceExcludingTax; // 不含税单价
@ExcelProperty(value = "使用时间")
private String usageTime; // 使用时间
@ExcelProperty(value = "不含税合价")
private String amountExcludingTax; // 不含税合价
@ExcelProperty(value = "税率(%)")
private String taxRate; // 税率(%)
@ExcelProperty(value = "含税合价")
private String amountIncludingTax; // 含税合价
@ExcelProperty(value = "摊销比例(%)")
private String amortizationRatio; // 摊销比例(%)
@ExcelProperty(value = "摊销后不含税合价")
private String amountExcludeTaxAmortized; // 摊销后不含税合价
@ExcelProperty(value = "摊销后含税合价")
private String amountIncludeTaxAmortized; // 摊销后含税合价
@ExcelProperty(value = "税金(元)")
private String taxAmount; // 税金(元)
@ExcelProperty(value = "备注")
private String remarks; // 备注
@ExcelProperty(value = "成本科目")
private String costSubject; // 成本科目
@ExcelProperty(value = "税金类型")
private String taxType; // 税金类型
// @ExcelProperty(value = "主键")
private Long id; // 主键
// @ExcelProperty(value = "项目ID")
private Long cbProjectId; // 项目ID
private Long parentId; // 父项id
private Integer level; // 层级数
private String no; // 处理后内容
}
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 措施费导入数据
*
* @author tanyang
* @create 2024-02-04 13:49
**/
@Data
public class CbCostMeasuresItemVo {
private String itemContent; // 清单内容
private Long id; // 主键
}
package com.dsk.cscec.domain.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @Author lcl
* @Data 2024/2/19 9:42
*/
@Data
public class CbGainLossAnalysisListVo implements Serializable {
private Long id;
/**
* 名称
*/
private String cbName;
/**
* 招标控制价(招标控制价合价)
*/
private String tenderSumPrice;
/**
* 招标控制价(不含税招标合价)
*/
private String taxExcludeTenderSumPrice;
/**
* 招标控制价(含税招标合价)
*/
private String taxIncludeTenderSumPrice;
/**
* 投标报价(投标报价合价)
*/
private String bidSumPrice;
/**
* 投标报价(不含税投标合价)
*/
private String taxExcludeBidSumPrice;
/**
* 投标报价(含税投标合价)
*/
private String taxIncludebBidSumPrice;
/**
* 成本汇总(不含税成本合价)
*/
private String taxExclusiveTotal;
/**
* 成本汇总(成本税金合价)
*/
private String cbTaxesTotal;
/**
* 成本汇总(含税成本合价)
*/
private String taxInclusiveTotal;
/**
* 造价指标(招标控制价)
*/
private String costTender;
/**
* 造价指标(投标报价)
*/
private String costBid;
/**
* 造价指标(成本)
*/
private String costExpense;
/**
* 含税成本占比
*/
private String taxInclusiveExpenseProportion;
/**
* 招标控制价(含税合价偏差)
*/
private String tenderSumPriceDeviation;
/**
* 招标控制价(含税盈亏率)
*/
private String tenderProfitLossRatio;
/**
* 投标报价(含税合价偏差)
*/
private String bidSumPriceDeviation;
/**
* 投标报价(含税盈亏率)
*/
private String bidProfitLossRatio;
/**
* 实际成本费用(本月费用(含税))
*/
private String taxInclusiveExpense;
/**
* 实际成本费用(本月费用(不含税))
*/
private String taxExclusiveExpense;
/**
* 实际成本费用(截至本月费用(含税))
*/
private String sumTaxInclusiveExpense;
/**
* 实际成本费用(截至本月费用(不含税))
*/
private String sumTaxExclusiveExpense;
private List<CbGainLossAnalysisListVo> children;
}
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 措施费导入数据
*
* @author tanyang
* @create 2024-02-04 13:49
**/
@Data
public class CbProjectExpenseSummaryImportVo {
@ExcelProperty(value = "名称")
private String expenseName; // 名称
@ExcelProperty(value = "数值")
private String expenseValue; // 数值
@ExcelProperty(value = "占比")
private String proportion; // 占比
// @ExcelProperty(value = "序号")
private String number; // 清单内容
private Long id; // 主键
private Long cbProjectId; // 项目ID
private Long parentId; // 父项id
private Integer dataType; // 数据类型(0:现场经费、1:其他费用、2:措施费)
private String no; // 处理后内容
}
package com.dsk.cscec.domain.vo;
import lombok.Data;
import java.util.Date;
/**
* @Author lcl
* @Data 2024/2/6 14:46
*/
@Data
public class CbQuantitySummaryListVo {
private Long id;
/**
* 成本科目名称(合约规划)
*/
private String cbSubjectName;
/**
* 公司编码
*/
private String companyNo;
/**
* 集团编码
*/
private String orgNo;
/**
* 成本名称
*/
private String cbName;
/**
* 工作内容
*/
private String jobContent;
/**
* 计算规则
*/
private String calculationRule;
/**
* 计量单位
*/
private String unit;
/**
* 材料说明
*/
private String materialDescription;
/**
* 指导价格
*/
private String guidePrice;
/**
* 投标选用单价(不含税)
*/
private Double bidUnitPrice;
/**
* 单价差额
*/
private Double unitPriceDifference;
/**
* 数量
*/
private Double quantity;
/**
* 合价(不含税)
*/
private Double combinedPrice;
/**
* 合价(含税)
*/
private Double combinedPriceTax;
/**
* 品牌名称
*/
private String brandName;
/**
* 投标选用来源
*/
private String bidSource;
/**
* 备注
*/
private String remark;
/**
* 工程量(本月用料)
*/
private Double quantities;
/**
* 单位
*/
private String quantitiesUnit;
/**
* 换算后本月用料
*/
private Double conversionQuantities;
/**
* 换算单位
*/
private String conversionUnit;
/**
* 采购单价
*/
private Double purchaseUnitPrice;
/**
* 创建时间
*/
private Date createTime;
/**
* 截至本月总量
*/
private Double totalQuantities;
/**
* 本月已填写成本Id
*/
private String actualId;
/**
* 推送工程量
*/
private Double pushQuantities;
/**
* IPM项目编码
*/
private String ipmProjectCode;
/**
* IPM合同编码
*/
private String ipmContractCode;
/**
* IPM作业编码
*/
private String ipmJobCode;
}
package com.dsk.cscec.domain.vo;
import com.dsk.common.core.domain.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 成本汇总Bo
*
* @author cyf
* @since 2024-02-06
*/
@Data
public class CbSummaryActualListVo extends BaseEntity {
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 成本阶段( 0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 序号
*/
private String number;
/**
* 名称/成本科目
*/
private String cbName;
/**
* 不含税成本合价
*/
private String taxExclusiveTotal;
/**
* 成本税金合价
*/
private String cbTaxesTotal;
/**
* 含税成本合价
*/
private String taxInclusiveTotal;
/**
* 成本占比
*/
private String cbProportion;
/**
* 含税成本平米指标
*/
private String taxInclusivePmTarget;
/**
* 备注
*/
private String remark;
/**
* 费用id
*/
private Long actualId;
/**
* 本月费用(含税)
*/
private BigDecimal taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
private BigDecimal taxExclusiveExpense;
/**
* 截至本月费用(含税)
*/
private BigDecimal taxInclusiveExpenseTotal;
/**
* 截至本月费用(不含税)
*/
private BigDecimal taxExclusiveExpenseTotal;
/**
* 费用日期
*/
private String expenseDate;
/**
* 是否锁定(0否,1是)
*/
private Integer lockStatus;
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;
import java.math.BigDecimal;
/**
* 成本汇总(CbSummary)-成本科目汇总导出Vo
*
* @author cyf
* @since 2024-02-06
*/
@Data
@NoArgsConstructor
public class CbSummaryCostAccountExportVo implements Serializable {
private static final long serialVersionUID = -20126964599875841L;
/**
* 序号
*/
@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;
/**
* 本月费用(含税)
*/
@ExcelProperty(value = "本月费用(含税)")
private BigDecimal taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
@ExcelProperty(value = "本月费用(不含税)")
private BigDecimal taxExclusiveExpense;
/**
* 截至本月费用(含税)
*/
@ExcelProperty(value = "截至本月费用(含税)")
private BigDecimal taxInclusiveExpenseTotal;
/**
* 截至本月费用(不含税)
*/
@ExcelProperty(value = "截至本月费用(不含税)")
private BigDecimal taxExclusiveExpenseTotal;
}
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 成本汇总(CbSummary)-项目汇总导出Vo
*
* @author cyf
* @since 2024-02-06
*/
@Data
@NoArgsConstructor
public class CbSummaryProjectExportVo implements Serializable {
private static final long serialVersionUID = -20126964599875841L;
/**
* 序号
*/
@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;
/**
* 本月费用(含税)
*/
@ExcelProperty(value = "本月费用(含税)")
private BigDecimal taxInclusiveExpense;
/**
* 本月费用(不含税)
*/
@ExcelProperty(value = "本月费用(不含税)")
private BigDecimal taxExclusiveExpense;
/**
* 截至本月费用(含税)
*/
@ExcelProperty(value = "截至本月费用(含税)")
private BigDecimal taxInclusiveExpenseTotal;
/**
* 截至本月费用(不含税)
*/
@ExcelProperty(value = "截至本月费用(不含税)")
private BigDecimal taxExclusiveExpenseTotal;
}
package com.dsk.cscec.domain.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* 成本汇总(CbSummary)-项目汇总导入Vo
*
* @author cyf
* @since 2024-02-06
*/
@Data
@NoArgsConstructor
public class CbSummaryProjectImportVo implements Serializable {
private static final long serialVersionUID = -20126964599875841L;
/**
* 序号
*/
@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;
import lombok.Data;
import java.util.Date;
/**
* @author sxk
* @date 2024.02.18
* @time 15:18
*/
@Data
public class ProjectRecordDataVo {
/**
* 项目文件状态(1:解析中、2:解析成功、3:解析失败)
*/
private Integer projectFileStatus;
/**
* 成本阶段(0:标前成本、1:标后成本、2:转固成本)
*/
private Integer cbStage;
/**
* 更新者
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
}
package com.dsk.cscec.domain.vo;
import lombok.Data;
import java.util.List;
/**
* @author sxk
* @date 2024.02.18
* @time 15:08
*/
@Data
public class ProjectRecordSearchVo {
/**
* 项目ID
*/
private Long id;
/**
* 项目名称
*/
private String projectName;
/**
* IPM项目编码
*/
private String ipmProjectNo;
/**
* 文件名称
*/
private String projectFileName;
/**
* 项目数据
*/
private List<ProjectRecordDataVo> dataVoList;
}
package com.dsk.cscec.domain.vo;
import com.dsk.cscec.domain.CbProjectFile;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author sxk
* @date 2024.02.08
* @time 10:24
*/
@Data
public class QueryProjectFileUploadDetailVo {
/**
* 项目ID
*/
private Long projectId;
/**
* 直接费成本
*/
private List<CbProjectFile> directExpense = new ArrayList<>();
/**
* 工料汇总
*/
private List<CbProjectFile> quantitySummary = new ArrayList<>();
/**
* 措施项目
*/
private List<CbProjectFile> measureProject = new ArrayList<>();
/**
* 其他项目
*/
private List<CbProjectFile> otherProject = new ArrayList<>();
/**
* 现场经费
*/
private List<CbProjectFile> sceneExpense = new ArrayList<>();
/**
* 成本汇总
*/
private List<CbProjectFile> cbSummary = new ArrayList<>();
}
//package com.dsk.cscec.listener;
//
//import cn.dev33.satoken.secure.BCrypt;
//import cn.hutool.core.bean.BeanUtil;
//import cn.hutool.core.util.ObjectUtil;
//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.common.helper.LoginHelper;
//import com.dsk.common.utils.ValidatorUtils;
//import com.dsk.common.utils.spring.SpringUtils;
//import com.dsk.cscec.domain.vo.ProjectMeasuresImportVo;
//import com.dsk.system.domain.SysUser;
//import com.dsk.system.domain.vo.SysUserImportVo;
//import com.dsk.system.service.ISysConfigService;
//import com.dsk.system.service.ISysUserService;
//import lombok.extern.slf4j.Slf4j;
//
//import java.util.List;
//
///**
// * 系统用户自定义导入
// *
// * @author Lion Li
// */
//@Slf4j
//public class ProjectCostMeasureImportListener extends AnalysisEventListener<ProjectMeasuresImportVo> implements ExcelListener<ProjectMeasuresImportVo> {
//
//// private final ISysUserService userService;
//
//// private final String password;
//
// private final Boolean isUpdateSupport;
//
package com.dsk.cscec.listener;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dsk.common.excel.ExcelListener;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.spring.SpringUtils;
import com.dsk.cscec.domain.CbCostMeasure;
import com.dsk.cscec.domain.vo.CbCostMeasuresImportVo;
import com.dsk.cscec.service.impl.CbCostMeasureServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 系统用户自定义导入
*
* @author Lion Li
*/
@Slf4j
public class ProjectCostMeasureImportListener extends AnalysisEventListener<CbCostMeasuresImportVo> implements ExcelListener<CbCostMeasuresImportVo> {
private final CbCostMeasureServiceImpl cbCostMeasureService;
//
// private final String password;
private final Long projectId;
private final Integer cbStage;
private List<CbCostMeasuresImportVo> dataList = new ArrayList<>();
// private final String operName;
//
// private int successNum = 0;
// private int failureNum = 0;
// private final StringBuilder successMsg = new StringBuilder();
// private final StringBuilder failureMsg = new StringBuilder();
//
// public ProjectCostMeasureImportListener(Boolean isUpdateSupport) {
//// String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
//// this.userService = SpringUtils.getBean(ISysUserService.class);
//// this.password = BCrypt.hashpw(initPassword);
// this.isUpdateSupport = isUpdateSupport;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public ProjectCostMeasureImportListener(Long projectId, Integer cbStage) {
// String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
this.cbCostMeasureService = SpringUtils.getBean(CbCostMeasureServiceImpl.class);
this.cbStage = cbStage;
this.projectId = projectId;
// this.operName = LoginHelper.getUsername();
}
@Override
public void invoke(CbCostMeasuresImportVo importVo, AnalysisContext context) {
Integer rowIndex = context.readRowHolder().getRowIndex();
if (StrUtil.isEmpty(importVo.getItemContent())) {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:清单内容不能为空");
}
String number = importVo.getNumber();
if (StrUtil.isEmpty(number)) {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:序号不能为空");
}
Boolean numberMatch = false;
String regex = "[\\((]*[一|二|三|四|五|六|七|八|九|十]+[\\))]*";
Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)*$");
Pattern pattern3 = Pattern.compile("^([1-9][0-9]*|0)$");
if (ReUtil.isMatch(regex, number) || ReUtil.isMatch(pattern, number)||ReUtil.isMatch(pattern3, number)) {
numberMatch = true;
} else {
failureNum++;
failureMsg.append("<br/>" + rowIndex + "行 解析失败:序号格式错误");
}
if(numberMatch){
if (ReUtil.isMatch(regex, number)){
String replace = number.replaceAll("[\\\\((]|[\\\\))]", "");
int no = Convert.chineseToNumber(replace);
importVo.setNo(String.valueOf(no));
}else{
importVo.setNo(importVo.getNumber());
}
dataList.add(importVo);
}
// JSONConfig jsonConfig=new JSONConfig();
// jsonConfig.setIgnoreNullValue(false);
// System.out.println(JSONUtil.toJsonStr(importVo,jsonConfig));
//
//
// Integer parentId=null;
//
//保存sheet为一级节点
// ReadSheetHolder readSheetHolder = context.readSheetHolder();
// CbCostMeasure rootCbCostMeasure=new CbCostMeasure();
// rootCbCostMeasure.setItemContent(readSheetHolder.getSheetName());
// rootCbCostMeasure.setLevel(0);
// rootCbCostMeasure.setCbProjectId(projectId);
// rootCbCostMeasure.setCbStage(cbStage);
// LambdaQueryWrapper<CbCostMeasure> tWrapper = Wrappers.lambdaQuery(rootCbCostMeasure);
// CbCostMeasure rootMeasure = cbCostMeasureService.getOne(tWrapper);
// if(ObjectUtil.isEmpty(rootMeasure)){
// cbCostMeasureService.save(rootCbCostMeasure);
// }
//
// @Override
// public void invoke(ProjectMeasuresImportVo userVo, AnalysisContext context) {
//// SysUser user = this.userService.selectUserByUserName(userVo.getUserName());
//// try {
//// // 验证是否存在这个用户
//// if (ObjectUtil.isNull(user)) {
//// user = BeanUtil.toBean(userVo, SysUser.class);
//// ValidatorUtils.validate(user);
//// user.setPassword(password);
//// user.setCreateBy(operName);
//// userService.insertUser(user);
//// successNum++;
//// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 导入成功");
//// } else if (isUpdateSupport) {
//// Long userId = user.getUserId();
//// user = BeanUtil.toBean(userVo, SysUser.class);
//// user.setUserId(userId);
//// ValidatorUtils.validate(user);
//// userService.checkUserAllowed(user);
//// userService.checkUserDataScope(user.getUserId());
//// user.setUpdateBy(operName);
//// userService.updateUser(user);
//// successNum++;
//// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 更新成功");
//// } else {
//// failureNum++;
//// 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);
//// }
// //保存下级节点
// String itemContent = importVo.getItemContent();
// String number = importVo.getNumber();
//
//
// //判断是否二级节点
// String regex = "[\\((][一|二|三|四|五|六|七|八|九|十]+[\\))]";
// if(StrUtil.isNotEmpty(itemContent)&& ReUtil.isMatch(regex,itemContent)&&StrUtil.isEmpty(importVo.getTaxType())){
// CbCostMeasure firstCbCostMeasure=new CbCostMeasure();
// firstCbCostMeasure.setItemContent(itemContent);
// firstCbCostMeasure.setLevel(1);
// firstCbCostMeasure.setProjectId(projectId);
// firstCbCostMeasure.setCbStage(cbStage);
// LambdaQueryWrapper<CbCostMeasure> firstWrapper = Wrappers.lambdaQuery(firstCbCostMeasure);
// CbCostMeasure firstMeasure = cbCostMeasureService.getOne(firstWrapper);
// if(ObjectUtil.isEmpty(firstMeasure)){
// cbCostMeasureService.save(firstMeasure);
// parentId=rootCbCostMeasure.getId();
// }
//
// @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());
// cbCostMeasureService.save();
// SysUser user = this.userService.selectUserByUserName(userVo.getUserName());
// try {
// // 验证是否存在这个用户
// if (ObjectUtil.isNull(user)) {
// user = BeanUtil.toBean(userVo, SysUser.class);
// ValidatorUtils.validate(user);
// user.setPassword(password);
// user.setCreateBy(operName);
// userService.insertUser(user);
// successNum++;
// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 导入成功");
// } else if (isUpdateSupport) {
// Long userId = user.getUserId();
// user = BeanUtil.toBean(userVo, SysUser.class);
// user.setUserId(userId);
// ValidatorUtils.validate(user);
// userService.checkUserAllowed(user);
// userService.checkUserDataScope(user.getUserId());
// user.setUpdateBy(operName);
// userService.updateUser(user);
// successNum++;
// successMsg.append("<br/>").append(successNum).append("、账号 ").append(user.getUserName()).append(" 更新成功");
// } else {
// successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
// }
// return successMsg.toString();
// }
//
// @Override
// public List<ProjectMeasuresImportVo> getList() {
// return null;
// }
//
// @Override
// public List<String> getErrorList() {
// return null;
// failureNum++;
// 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<CbCostMeasuresImportVo> getExcelResult() {
return new ExcelResult<CbCostMeasuresImportVo>() {
@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<CbCostMeasuresImportVo> getList() {
return dataList;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
package com.dsk.cscec.listener;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.dsk.common.excel.ExcelListener;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.spring.SpringUtils;
import com.dsk.cscec.domain.CbProjectExpenseSummary;
import com.dsk.cscec.domain.vo.CbCostMeasuresImportVo;
import com.dsk.cscec.domain.vo.CbProjectExpenseSummaryImportVo;
import com.dsk.cscec.service.CbProjectExpenseSummaryService;
import com.dsk.cscec.service.impl.CbCostMeasureServiceImpl;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* 系统用户自定义导入
*
* @author Lion Li
*/
@Slf4j
public class ProjectCostMeasureSummaryImportListener extends AnalysisEventListener<CbProjectExpenseSummaryImportVo> implements ExcelListener<CbProjectExpenseSummaryImportVo> {
private final CbProjectExpenseSummaryService cbProjectExpenseSummaryService;
//
// private final String password;
private final Long projectId;
private final Integer cbStage;
private final Integer dataType;
private List<CbProjectExpenseSummaryImportVo> dataList = new ArrayList<>();
// private final String operName;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public ProjectCostMeasureSummaryImportListener(Long projectId, Integer cbStage,Integer dataType) {
this.cbProjectExpenseSummaryService = SpringUtils.getBean(CbProjectExpenseSummaryService.class);
this.cbStage = cbStage;
this.projectId = projectId;
this.dataType=dataType;
}
@Override
public void invoke(CbProjectExpenseSummaryImportVo importVo, AnalysisContext context) {
CbProjectExpenseSummary cbProjectExpenseSummary=new CbProjectExpenseSummary();
BeanUtil.copyProperties(importVo,cbProjectExpenseSummary);
cbProjectExpenseSummary.setProjectId(projectId);
cbProjectExpenseSummary.setCbStage(cbStage);
cbProjectExpenseSummary.setDataType(dataType);
cbProjectExpenseSummary.setCreateBy(LoginHelper.getUsername());
cbProjectExpenseSummaryService.save(cbProjectExpenseSummary);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<CbProjectExpenseSummaryImportVo> getExcelResult() {
return new ExcelResult<CbProjectExpenseSummaryImportVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<CbProjectExpenseSummaryImportVo> getList() {
return dataList;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbCostMeasureActual;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import java.util.List;
public interface CbCostMeasureActualMapper extends BaseMapper<CbCostMeasureActual> {
int insertSelective(CbCostMeasureActual record);
int updateByPrimaryKeySelective(CbCostMeasureActual record);
List<CbCostMeasureActualVo> selectDataList(CbCostMeasureActualBo costMeasureActualBo);
}
\ No newline at end of file
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsk.common.core.domain.entity.SysDictData;
import com.dsk.cscec.domain.CbCostMeasure;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import java.util.List;
public interface CbCostMeasureMapper extends BaseMapper<CbCostMeasure> {
List<CbCostMeasureActualVo> selectListByProjectAndNo(CbCostMeasureActualBo cbCostMeasure);
}
\ No newline at end of file
......@@ -11,6 +11,5 @@ import com.dsk.cscec.domain.CbProjectFile;
*/
public interface CbProjectFileMapper extends BaseMapper<CbProjectFile> {
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.vo.ProjectRecordSearchVo;
/**
* 项目台账表(CbProjectRecord)表数据库访问层
......@@ -10,6 +13,10 @@ import com.dsk.cscec.domain.CbProjectRecord;
* @since 2024-02-05 11:37:49
*/
public interface CbProjectRecordMapper extends BaseMapper<CbProjectRecord> {
/**
* 获取项目台账列表
*/
Page<ProjectRecordSearchVo> selectPageProjectRecordList(Page<ProjectRecordSearchVo> build, QueryWrapper<CbProjectRecord> wrapper);
}
package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.common.core.mapper.BaseMapperPlus;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo;
import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
......@@ -15,12 +18,16 @@ import java.util.Map;
* @author lcl
* @since 2024-02-05 11:06:56
*/
public interface CbQuantitySummaryMapper extends BaseMapper<CbQuantitySummary> {
public interface CbQuantitySummaryMapper extends BaseMapperPlus<CbQuantitySummaryMapper,CbQuantitySummary,CbQuantitySummary> {
List<Map<String, Object>> selectSubject(CbProjectBaseBo bo);
int selectOtherSubjectCount(CbProjectBaseBo bo);
List<String> selectMonthList(CbQuantitySummaryListBo bo);
List<CbQuantitySummaryListVo> selectListBySubject(CbQuantitySummaryListBo bo);
}
......@@ -2,6 +2,9 @@ package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSummaryActual;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 成本汇总-每月费用(CbSummaryActual)表数据库访问层
......@@ -10,5 +13,12 @@ import com.dsk.cscec.domain.CbSummaryActual;
* @since 2024-02-06
*/
public interface CbSummaryActualMapper extends BaseMapper<CbSummaryActual> {
/**
* 批量新增或按主键更新数据(MyBatis原生foreach方法)
*
* @param entities List<CbSummaryActual> 实例对象列表
* @return 影响行数
*/
int insertOrUpdateBatch(@Param("entities") List<CbSummaryActual> entities);
}
......@@ -2,6 +2,14 @@ package com.dsk.cscec.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbGainLossAnalysisListVo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 成本汇总(CbSummary)表数据库访问层
......@@ -11,4 +19,46 @@ import com.dsk.cscec.domain.CbSummary;
*/
public interface CbSummaryMapper extends BaseMapper<CbSummary> {
List<CbSummaryActualListVo> getByParentId(@Param("parentId") Long parentId, @Param("expenseDate") String expenseDate);
CbSummaryActualListVo getById(@Param("id") Long id, @Param("expenseDate") String expenseDate);
/**
* 根据月份获取所有项目汇总数据
*
* @param bo
* @return
*/
List<CbSummaryActualListVo> getProjectAll(@Param("bo") CbSummaryActualListBo bo);
/**
* 根据月份获取所有成本科目汇总数据
*
* @param bo
* @return
*/
List<CbSummaryActualListVo> getCostAccountAll(@Param("bo") CbSummaryActualListBo bo);
/**
* 获取已添加成本月份
*
* @param bo
* @return
*/
List<String> getExpenseDateList(@Param("bo") CbSummaryBo bo);
/**
* 根据level获取名称/成本科目
*
* @param bo
* @return
*/
List<Map<String, Object>> selectByLevel(@Param("bo") CbSummaryBo bo);
CbGainLossAnalysisListVo getGainLossAnalysisById(@Param("id") Long id, @Param("expenseDate") String expenseDate);
List<CbGainLossAnalysisListVo> getGainLossAnalysisByParentId(@Param("id") Long parentId, @Param("expenseDate") String expenseDate);
}
......@@ -2,6 +2,9 @@ package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.bo.AddProjectFileUploadBo;
import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo;
import com.dsk.system.domain.vo.SysOssVo;
/**
* 项目成本文件表(CbProjectFile)表服务接口
......@@ -10,5 +13,29 @@ import com.dsk.cscec.domain.CbProjectFile;
* @since 2024-02-05 14:01:06
*/
public interface CbProjectFileService extends IService<CbProjectFile> {
/**
* 添加项目上传文件记录
*
* @param fileUploadBo 上传信息
* @param oss oss信息
* @return 文件实体
*/
CbProjectFile addProjectFile(AddProjectFileUploadBo fileUploadBo, SysOssVo oss);
/**
* 逻辑删除项目上传文件记录
*
* @param fileId 文件ID
* @return 删除结果
*/
Integer deleteProjectFile(Long fileId);
/**
* 获取项目文件上传详情
*
* @param projectId 项目ID
* @return 文件列表
*/
QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId);
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.AddCbProjectBo;
import com.dsk.cscec.domain.bo.AddNewCbProjectBo;
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;
/**
* 项目台账表(CbProjectRecord)表服务接口
......@@ -10,6 +19,66 @@ import com.dsk.cscec.domain.CbProjectRecord;
* @since 2024-02-05 11:37:53
*/
public interface CbProjectRecordService extends IService<CbProjectRecord> {
/**
* 新增项目
*
* @param addCbProjectBo 新增对象
* @return 新增结果
*/
CbProjectRecord addProject(AddCbProjectBo addCbProjectBo);
/**
* 根据项目文件导入数据
*
* @param projectId 项目ID
*/
void importData(Long projectId) throws Exception;
/**
* 获取项目台账列表
*
* @param searchBo 查询条件
* @param pageQuery 分页对象
* @return 分页数据
*/
TableDataInfo<ProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery);
/**
* 修改项目信息
*
* @param editBo 修改对象
* @return 修改结果
*/
Integer editProjectInfo(EditProjectInfoBo editBo);
/**
* 获取新阶段项目可选成本阶段
*
* @param relatedId 关联ID
* @return 可选成本阶段
*/
List<Integer> getProjectAvailableCbStage(Long relatedId);
/**
* 新增新阶段项目
*
* @param newProjectBo 新增对象
* @return 新增结果
*/
CbProjectRecord addNewStageProject(AddNewCbProjectBo newProjectBo);
/**
* 获取草稿弹窗列表
*
* @return 草稿弹窗列表
*/
List<CbProjectRecord> getDraftDialogList();
/**
* 删除草稿
*
* @param projectId 项目ID
* @return 删除结果
*/
Integer deleteDraft(Long projectId);
}
......@@ -2,6 +2,13 @@ package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.domain.bo.CbSummaryActualBo;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import java.util.List;
import java.util.Map;
/**
......@@ -12,4 +19,45 @@ import com.dsk.cscec.domain.CbSummary;
*/
public interface CbSummaryService extends IService<CbSummary> {
//项目汇总导入 todo
void importCbProject(Long projectId, Integer cbStage);
/**
* 获取一级名称/成本科目列表
*
* @param bo
* @return
*/
List<Map<String, Object>> getCbNameList(CbSummaryBo bo);
/**
* 根据父级id获取子级数据
*
* @param bo
* @return
*/
List<CbSummaryActualListVo> getActualList(CbSummaryActualListBo bo);
/**
* 获取已添加成本月份
*
* @param bo
* @return
*/
List<String> getExpenseDateList(CbSummaryBo bo);
/**
* 新增/更新每月费用
*
* @param boList
* @return
*/
boolean insertOrUpdateActual(List<CbSummaryActualBo> boList);
/**
* 导出列表获取
* @param bo
* @return
*/
List<CbSummaryActualListVo> getAll(CbSummaryActualListBo bo);
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbCostMeasure;
import com.dsk.cscec.domain.CbCostMeasureActual;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
/**
* 成本-工料汇总基本表(CbQuantitySummary)表服务接口
*
* @author lcl
* @since 2024-02-05 11:06:56
*/
public interface ICbCostMeasureActualService extends IService<CbCostMeasureActual> {
}
package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.entity.SysDictData;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.cscec.domain.CbCostMeasure;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualPushBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import com.dsk.cscec.domain.vo.CbCostMeasuresItemVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
/**
* 成本-工料汇总基本表(CbQuantitySummary)表服务接口
*
* @author lcl
* @since 2024-02-05 11:06:56
*/
public interface ICbCostMeasureService extends IService<CbCostMeasure> {
void importExcelData(MultipartFile file, Long projectId);
List<Map<String, Object>> listByLevel(Long projectId, int i);
List<CbCostMeasureActualVo> selectDataList(CbCostMeasureActualBo cbCostMeasure);
void saveBatchCostMeasureActual(List<CbCostMeasureActualSaveBo> boList);
void pushCostMeasureActual(CbCostMeasureActualPushBo pushBo);
void importExcelSummaryData(MultipartFile file, Long projectId,Integer dataType);
}
package com.dsk.cscec.service;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.vo.CbGainLossAnalysisListVo;
import java.util.List;
public interface ICbGainLossAnalysisService {
List<CbGainLossAnalysisListVo> getList(CbSummaryActualListBo bo);
}
......@@ -2,7 +2,10 @@ package com.dsk.cscec.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.CbQuantitySummaryActual;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo;
import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo;
import java.util.List;
import java.util.Map;
......@@ -17,7 +20,13 @@ public interface ICbQuantitySummaryService extends IService<CbQuantitySummary> {
Map<String, Object> subjectTree(CbProjectBaseBo bo);
List<String> monthList(CbProjectBaseBo bo);
List<String> monthList(CbQuantitySummaryListBo bo);
List<CbQuantitySummaryListVo> subjectList(CbQuantitySummaryListBo bo);
void updateActual(List<CbQuantitySummaryActual> list);
void pushData(CbQuantitySummaryActual bo);
}
......@@ -52,5 +52,13 @@ public interface IDProjectService extends IService<DProject> {
* @return 项目详情
*/
ProjectDetailVo queryProjectDetail(ProjectDetailBo projectDetailBo);
/**
* 校验项目编码是否存在
*
* @param projectCode 项目编码
* @return 校验结果
*/
Boolean checkProjectCodeExist(String projectCode);
}
package com.dsk.cscec.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.entity.SysDictData;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.excel.ExcelResult;
import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.JsonUtils;
import com.dsk.common.utils.StringUtils;
import com.dsk.common.utils.poi.ExcelUtil;
import com.dsk.cscec.domain.CbCostMeasureActual;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.DCustomer;
import com.dsk.cscec.domain.bo.CbCostMeasureActualBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualPushBo;
import com.dsk.cscec.domain.bo.CbCostMeasureActualSaveBo;
import com.dsk.cscec.domain.vo.CbCostMeasureActualVo;
import com.dsk.cscec.domain.vo.CbCostMeasuresImportVo;
import com.dsk.cscec.domain.vo.CbCostMeasuresItemVo;
import com.dsk.cscec.domain.vo.CbProjectExpenseSummaryImportVo;
import com.dsk.cscec.listener.ProjectCostMeasureImportListener;
import com.dsk.cscec.listener.ProjectCostMeasureSummaryImportListener;
import com.dsk.cscec.mapper.CbCostMeasureActualMapper;
import com.dsk.cscec.service.CbProjectRecordService;
import com.dsk.cscec.service.ICbCostMeasureActualService;
import com.dsk.cscec.service.ICbCostMeasureService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dsk.cscec.mapper.CbCostMeasureMapper;
import com.dsk.cscec.domain.CbCostMeasure;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@Slf4j
@Service
public class CbCostMeasureServiceImpl extends ServiceImpl<CbCostMeasureMapper, CbCostMeasure> implements ICbCostMeasureService {
private final String firstPattern = "[\\((]*[一|二|三|四|五|六|七|八|九|十]+[\\))]*";
private final Pattern secondPattern = Pattern.compile("^\\d+(\\.\\d+)*$");
private final Pattern pattern3 = Pattern.compile("^([1-9][0-9]*|0)$");
@Autowired
private CbProjectRecordService cbProjectRecordService;
@Autowired
private ICbCostMeasureActualService cbCostMeasureActualService;
@SneakyThrows
@Override
public void importExcelData(MultipartFile file, Long projectId) {
String name = file.getOriginalFilename();
name = FileNameUtil.getPrefix(name);
CbProjectRecord byId = cbProjectRecordService.getById(projectId);
Assert.notNull(byId, "项目信息不能为空");
Integer cbStage = byId.getCbStage();
ProjectCostMeasureImportListener importListener = new ProjectCostMeasureImportListener(projectId, cbStage);
EasyExcel.read(file.getInputStream(), CbCostMeasuresImportVo.class, importListener).sheet().doRead();
ExcelResult<CbCostMeasuresImportVo> result = importListener.getExcelResult();
String analysis = result.getAnalysis();
List<CbCostMeasuresImportVo> list = result.getList();
if (CollectionUtil.isEmpty(list)) {
//解析失败
log.debug(">>>>解析失败" + list.size());
//todo 解析失败更新文件备注
return;
}
log.debug(">>>>" + list.size());
CbCostMeasure rootCbCostMeasure = new CbCostMeasure();
rootCbCostMeasure.setItemContent(name);
rootCbCostMeasure.setLevel(0);
rootCbCostMeasure.setParentId(0L);
rootCbCostMeasure.setProjectId(projectId);
rootCbCostMeasure.setCbStage(cbStage);
LambdaQueryWrapper<CbCostMeasure> tWrapper = Wrappers.lambdaQuery(rootCbCostMeasure);
CbCostMeasure rootMeasure = this.getOne(tWrapper);
if (ObjectUtil.isEmpty(rootMeasure)) {
this.save(rootCbCostMeasure);
rootCbCostMeasure.setNo(String.valueOf(rootCbCostMeasure.getId()));
this.updateById(rootCbCostMeasure);
}
Long rootMeasuresId = rootCbCostMeasure.getId();
if (CollectionUtil.isNotEmpty(list)) {
for (CbCostMeasuresImportVo importVo : list) {
String number = importVo.getNumber();
CbCostMeasure cbCostMeasure = new CbCostMeasure();
cbCostMeasure.setProjectId(projectId);
cbCostMeasure.setCbStage(cbStage);
//保存一级节点
if (ReUtil.isMatch(firstPattern, number) || ReUtil.isMatch(pattern3, number)) {
BeanUtil.copyProperties(importVo, cbCostMeasure);
cbCostMeasure.setParentId(rootMeasuresId);
cbCostMeasure.setLevel(1);
} else if (ReUtil.isMatch(secondPattern, number)) {
BeanUtil.copyProperties(importVo, cbCostMeasure);
// 根据no查询父级节点
CbCostMeasure parentCbCostMeasure = getCbCostMeasure(rootMeasuresId, number, projectId, cbStage);
String[] split = number.split("\\.");
cbCostMeasure.setLevel(split.length);
cbCostMeasure.setParentId(parentCbCostMeasure.getId());
}
String newNo = String.valueOf(rootMeasuresId).concat(".").concat(cbCostMeasure.getNo());
cbCostMeasure.setNo(newNo);
this.save(cbCostMeasure);
}
}
}
@Override
public List<Map<String, Object>> listByLevel(Long projectId, int i) {
CbProjectRecord byId = cbProjectRecordService.getById(projectId);
Assert.notNull(byId, "项目信息不能为空");
CbCostMeasure rootCbCostMeasure = new CbCostMeasure();
rootCbCostMeasure.setParentId(0L);
rootCbCostMeasure.setProjectId(projectId);
rootCbCostMeasure.setCbStage(byId.getCbStage());
QueryWrapper<CbCostMeasure> tWrapper = Wrappers.query(rootCbCostMeasure);
tWrapper.select("id","item_content as itemContent");
tWrapper.orderByAsc("id");
List<Map<String, Object>> mapList = this.listMaps(tWrapper);
return mapList;
}
@Override
public List<CbCostMeasureActualVo> selectDataList(CbCostMeasureActualBo costMeasureActualBo) {
List<CbCostMeasureActualVo> dataList = new ArrayList<>();
Assert.notNull(costMeasureActualBo.getProjectId(), "项目ID不能为空");
CbProjectRecord byId = cbProjectRecordService.getById(costMeasureActualBo.getProjectId());
Assert.notNull(byId, "项目信息不能为空");
costMeasureActualBo.setCbStage(byId.getCbStage());
//查询项目某项措施费所有计划成本
dataList = baseMapper.selectListByProjectAndNo(costMeasureActualBo);
// if (CollectionUtil.isEmpty(dataList)) {
// return dataList;
// }
// // 查询项目某项措施费某月所有实际成本
// List<CbCostMeasureActualVo> actualVoList= cbCostMeasureActualMapper.selectDataList(costMeasureActualBo);
// if (CollectionUtil.isEmpty(actualVoList)) {
// return dataList;
// }
// for (CbCostMeasureActualVo cbCostMeasureActualVo : actualVoList) {
//
// }
return dataList;
}
@Override
public void saveBatchCostMeasureActual(List<CbCostMeasureActualSaveBo> boList) {
List<CbCostMeasureActual> saveList=new ArrayList<>();
for (CbCostMeasureActualSaveBo cbCostMeasureActualSaveBo : boList) {
CbCostMeasureActual cbCostMeasureActual =new CbCostMeasureActual();
BeanUtil.copyProperties(cbCostMeasureActualSaveBo,cbCostMeasureActual);
cbCostMeasureActual.setDelFlag(0);
cbCostMeasureActual.setUpdateId(LoginHelper.getUserId());
cbCostMeasureActual.setUpdateUser(LoginHelper.getUsername());
saveList.add(cbCostMeasureActual);
}
cbCostMeasureActualService.saveOrUpdateBatch(saveList);
}
@Override
public void pushCostMeasureActual(CbCostMeasureActualPushBo pushBo) {
//todo 推送到Ipm系统
CbCostMeasureActual cbCostMeasureActual =new CbCostMeasureActual();
cbCostMeasureActual.setId(pushBo.getId());
cbCostMeasureActual.setPushTime(new Date());
cbCostMeasureActual.setPushDataJson(JsonUtils.toJsonString(pushBo));
cbCostMeasureActualService.updateById(cbCostMeasureActual);
}
@SneakyThrows
@Override
public void importExcelSummaryData(MultipartFile file, Long projectId,Integer dataType) {
CbProjectRecord byId = cbProjectRecordService.getById(projectId);
Assert.notNull(byId, "项目信息不能为空");
Integer cbStage = byId.getCbStage();
ExcelUtil.importExcel(file.getInputStream(), CbProjectExpenseSummaryImportVo.class,new ProjectCostMeasureSummaryImportListener(projectId,cbStage,dataType));
}
/**
* 根据当前序号、项目id、成本阶段查询父级信息
*
* @param number
* @param projectId
* @param cbStage
* @return
*/
public CbCostMeasure getCbCostMeasure(Long rootMeasuresId, String number, Long projectId, Integer cbStage) {
String parentNo = number.substring(0, number.lastIndexOf('.'));
parentNo = String.valueOf(rootMeasuresId).concat(".").concat(parentNo);
CbCostMeasure rootCbCostMeasure = new CbCostMeasure();
rootCbCostMeasure.setNo(parentNo);
rootCbCostMeasure.setProjectId(projectId);
rootCbCostMeasure.setCbStage(cbStage);
LambdaQueryWrapper<CbCostMeasure> tWrapper = Wrappers.lambdaQuery(rootCbCostMeasure);
CbCostMeasure rootMeasure = this.getOne(tWrapper);
return rootMeasure;
}
}
package com.dsk.cscec.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.dsk.cscec.domain.CbSummary;
import com.dsk.cscec.domain.bo.CbSummaryActualListBo;
import com.dsk.cscec.domain.vo.CbGainLossAnalysisListVo;
import com.dsk.cscec.mapper.CbSummaryMapper;
import com.dsk.cscec.service.ICbGainLossAnalysisService;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Author lcl
* @Data 2024/2/18 14:03
*/
@Slf4j
@Service
public class CbGainLossAnalysisServiceImpl implements ICbGainLossAnalysisService {
@Resource
private CbSummaryMapper cbSummaryMapper;
@Override
public List<CbGainLossAnalysisListVo> getList(CbSummaryActualListBo bo) {
Assert.notNull(bo.getId(),"id不能为空");
List<CbGainLossAnalysisListVo> resultList = new ArrayList<>();
if (StringUtil.isBlank(bo.getExpenseDate())) {
//默认当前月
bo.setExpenseDate(DatePattern.SIMPLE_MONTH_FORMAT.format(new Date()));
}
CbSummary cbSummary = cbSummaryMapper.selectById(bo.getId());
if (ObjectUtil.isEmpty(cbSummary)) {
return resultList;
}
List<CbGainLossAnalysisListVo> childrenList = cbSummaryMapper.getGainLossAnalysisByParentId(bo.getId(), bo.getExpenseDate());
if (0 == cbSummary.getLevel()) {
resultList = childrenList;
}else {
childrenList = getProjectSumList(bo);
CbGainLossAnalysisListVo cbGainLossAnalysisListVo = cbSummaryMapper.getGainLossAnalysisById(bo.getId(),bo.getExpenseDate());
cbGainLossAnalysisListVo.setChildren(childrenList);
resultList.add(cbGainLossAnalysisListVo);
}
return resultList;
}
/**
* 盈亏对比分析列表
*
*/
private List<CbGainLossAnalysisListVo> getProjectSumList(CbSummaryActualListBo bo) {
List<CbGainLossAnalysisListVo> childrenList = cbSummaryMapper.getGainLossAnalysisByParentId(bo.getId(), bo.getExpenseDate());
childrenList.forEach(children -> {
CbSummaryActualListBo childBo = new CbSummaryActualListBo();
childBo.setId(children.getId());
childBo.setExpenseDate(bo.getExpenseDate());
children.setChildren(getProjectSumList(childBo));
});
return childrenList;
}
}
package com.dsk.cscec.service.impl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.domain.CbProjectExpenseSummary;
import com.dsk.cscec.mapper.CbProjectExpenseSummaryMapper;
import com.dsk.cscec.service.CbProjectExpenseSummaryService;
@Service
public class CbProjectExpenseSummaryServiceImpl extends ServiceImpl<CbProjectExpenseSummaryMapper, CbProjectExpenseSummary> implements CbProjectExpenseSummaryService{
}
package com.dsk.cscec.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.AddProjectFileUploadBo;
import com.dsk.cscec.domain.vo.QueryProjectFileUploadDetailVo;
import com.dsk.cscec.mapper.CbProjectFileMapper;
import com.dsk.cscec.mapper.CbProjectRecordMapper;
import com.dsk.cscec.service.CbProjectFileService;
import com.dsk.system.domain.vo.SysOssVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
/**
* 项目成本文件表(CbProjectFile)表服务实现类
......@@ -18,5 +30,106 @@ import javax.annotation.Resource;
public class CbProjectFileServiceImpl extends ServiceImpl<CbProjectFileMapper, CbProjectFile> implements CbProjectFileService {
@Resource
private CbProjectFileMapper baseMapper;
@Resource
private CbProjectRecordMapper projectRecordMapper;
/**
* 添加项目上传文件记录
*
* @param fileUploadBo 上传信息
* @param oss oss信息
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public CbProjectFile addProjectFile(AddProjectFileUploadBo fileUploadBo, SysOssVo oss) {
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(fileUploadBo.getProjectId());
CbProjectFile projectFile = BeanUtil.toBean(fileUploadBo, CbProjectFile.class);
projectFile.setCbStage(projectRecord.getCbStage());
projectFile.setFileName(oss.getOriginalName());
projectFile.setFileOssId(oss.getOssId());
projectFile.setFileOssUrl(oss.getUrl());
//项目文件状态:准备中
projectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING);
baseMapper.insert(projectFile);
return projectFile;
}
/**
* 逻辑删除项目上传文件记录
*
* @param fileId 文件ID
* @return 删除结果
*/
@Override
public Integer deleteProjectFile(Long fileId) {
CbProjectFile projectFile = baseMapper.selectById(fileId);
Assert.notNull(projectFile, "该文件不存在");
return baseMapper.deleteById(projectFile);
}
/**
* 获取项目文件上传详情
*
* @param projectId 项目ID
* @return 文件列表
*/
@Override
public QueryProjectFileUploadDetailVo getProjectFileUploadDetail(Long projectId) {
//校验项目是否存在
this.checkProjectExist(projectId);
List<CbProjectFile> projectFileList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId)
//成本阶段
//.eq(CbProjectFile::getCbStage, uploadDetailBo.getCbStage())
//删除状态:否
.eq(CbProjectFile::getDelFlag, CbProjectConstants.DELETE_FLAG_EXIST));
QueryProjectFileUploadDetailVo draftDetailVo = new QueryProjectFileUploadDetailVo();
draftDetailVo.setProjectId(projectId);
if (projectFileList.isEmpty()) {
return draftDetailVo;
}
//按照成本类型分类填充
projectFileList.forEach(fileList -> {
//TODO:此写法太丑陋,待优化
if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_DIRECT_EXPENSE)) {
//直接费成本
draftDetailVo.getDirectExpense().add(fileList);
} else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY)) {
//工料汇总
draftDetailVo.getQuantitySummary().add(fileList);
} else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_MEASURE_PROJECT)) {
//措施项目
draftDetailVo.getMeasureProject().add(fileList);
} else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_OTHER_PROJECT)) {
//其他项目
draftDetailVo.getOtherProject().add(fileList);
} else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_SCENE_EXPENSE)) {
//现场经费
draftDetailVo.getSceneExpense().add(fileList);
} else if (Objects.equals(fileList.getCbType(), CbProjectConstants.CB_TYPE_SUMMARY)) {
//成本汇总
draftDetailVo.getCbSummary().add(fileList);
}
});
return draftDetailVo;
}
/**
* 校验项目是否存在
*
* @param projectId 项目ID
* @return 项目实体
*/
private CbProjectRecord checkProjectExist(Long projectId) {
//校验项目是否存在
CbProjectRecord projectRecord = projectRecordMapper.selectById(projectId);
Assert.notNull(projectRecord, "该项目不存在");
return projectRecord;
}
}
package com.dsk.cscec.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.utils.StringUtils;
import com.dsk.component.DataAnalysisComponent;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.bo.*;
import com.dsk.cscec.domain.vo.ProjectRecordSearchVo;
import com.dsk.cscec.mapper.CbProjectFileMapper;
import com.dsk.cscec.mapper.CbProjectRecordMapper;
import com.dsk.cscec.service.CbProjectRecordService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 项目台账表(CbProjectRecord)表服务实现类
......@@ -18,5 +37,253 @@ import javax.annotation.Resource;
public class CbProjectRecordServiceImpl extends ServiceImpl<CbProjectRecordMapper, CbProjectRecord> implements CbProjectRecordService {
@Resource
private CbProjectRecordMapper baseMapper;
@Resource
private CbProjectFileMapper projectFileMapper;
@Resource
private DataAnalysisComponent dataAnalysisComponent;
/**
* 新增项目
*
* @param addCbProjectBo 新增对象
* @return 新增结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public CbProjectRecord addProject(AddCbProjectBo addCbProjectBo) {
CbProjectRecord projectRecord = BeanUtil.toBean(addCbProjectBo, CbProjectRecord.class);
//生成唯一关联ID
boolean idFlag = true;
long relatedId = -1;
while (idFlag) {
relatedId = IdUtil.getSnowflakeNextId();
idFlag = baseMapper.exists(new LambdaQueryWrapper<CbProjectRecord>()
.eq(CbProjectRecord::getRelatedId, relatedId));
}
projectRecord.setRelatedId(relatedId);
//项目文件状态:准备中
projectRecord.setProjectFileStatus(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING);
//删除状态:否
projectRecord.setDelFlag(CbProjectConstants.DELETE_FLAG_EXIST);
if (baseMapper.insert(projectRecord) > 0) {
return projectRecord;
}
return null;
}
/**
* 根据项目文件导入数据
*
* @param projectId 项目ID
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void importData(Long projectId) throws Exception {
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(projectId);
//校验各个成本类型是否至少有1个文件
//直接费成本
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_DIRECT_EXPENSE, CbProjectConstants.CB_TYPE_DIRECT_EXPENSE_NAME);
//工料汇总
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY_NAME);
//措施项目
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_MEASURE_PROJECT, CbProjectConstants.CB_TYPE_MEASURE_PROJECT_NAME);
//其他项目
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_OTHER_PROJECT, CbProjectConstants.CB_TYPE_OTHER_PROJECT_NAME);
//现场经费
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_SCENE_EXPENSE, CbProjectConstants.CB_TYPE_SCENE_EXPENSE_NAME);
//成本汇总
this.checkCbTypeExistFile(projectId, CbProjectConstants.CB_TYPE_SUMMARY, CbProjectConstants.CB_TYPE_SUMMARY_NAME);
//修改项目文件状态:解析中
projectRecord.setProjectFileStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSING);
//TODO:调各个成本类型的解析文件方法
//直接费成本
//工料汇总
CbProjectBaseBo projectBaseBo = new CbProjectBaseBo();
projectBaseBo.setProjectId(projectId);
projectBaseBo.setCbStage(projectRecord.getCbStage());
dataAnalysisComponent.quantitySummaryDataAnalysis(projectBaseBo);
//措施项目
//其他项目
//现场经费
//成本汇总
}
/**
* 校验各个成本类型是否至少有1个文件
*
* @param projectId 项目ID
* @param cbType 成本类型字典(0:直接费成本、1:工料汇总、2:措施项目、3:其他项目、4:现场经费、5:成本汇总)
* @param cbTypeName 成本类型名称
*/
private void checkCbTypeExistFile(Long projectId, Integer cbType, String cbTypeName) {
boolean isExist = projectFileMapper.exists(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId)
.eq(CbProjectFile::getCbType, cbType)
//项目文件状态:解析中
.eq(CbProjectFile::getFileParseStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING));
Assert.isTrue(isExist, cbTypeName + "至少需要上传1个文件");
}
/**
* 获取项目台账列表
*
* @param searchBo 查询条件
* @param pageQuery 分页对象
* @return 分页数据
*/
@Override
public TableDataInfo<ProjectRecordSearchVo> getProjectList(CbProjectSearchBo searchBo, PageQuery pageQuery) {
QueryWrapper<CbProjectRecord> wrapper = Wrappers.query();
wrapper
.like(StringUtils.isNotBlank(searchBo.getProjectName()), "project_name", searchBo.getProjectName())
.like(StringUtils.isNotBlank(searchBo.getIpmProjectNo()), "ipm_project_no", searchBo.getIpmProjectNo());
//TODO:成本阶段、文件解析状态筛选
Integer cbStage = searchBo.getCbStage();
Integer projectFileStatus = searchBo.getProjectFileStatus();
Page<ProjectRecordSearchVo> page = baseMapper.selectPageProjectRecordList(pageQuery.build(), wrapper);
for (ProjectRecordSearchVo searchVo : page.getRecords()) {
Long projectId = searchVo.getId();
//page.
}
return TableDataInfo.build(page);
}
/**
* 修改项目信息
*
* @param editBo 修改对象
* @return 修改结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Integer editProjectInfo(EditProjectInfoBo editBo) {
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(editBo.getProjectId());
for (CbProjectRecord record : baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>()
.eq(CbProjectRecord::getRelatedId, projectRecord.getRelatedId()))) {
record.setProjectName(editBo.getProjectName());
record.setIpmProjectNo(editBo.getIpmProjectNo());
record.setIsGetProjectDetail(editBo.getIsGetProjectDetail());
record.setProjectFileName(editBo.getProjectFileName());
Assert.isTrue(baseMapper.updateById(record) > 0, "修改失败,请联系系统管理员");
}
return 1;
}
/**
* 获取新阶段项目可选成本阶段
*
* @param relatedId 关联ID
* @return 可选成本阶段
*/
@Override
public List<Integer> getProjectAvailableCbStage(Long relatedId) {
//通过关联ID校验项目是否存在
List<CbProjectRecord> projectRecordList = this.checkRelatedIdExist(relatedId);
ArrayList<Integer> cbStageList = new ArrayList<>();
cbStageList.add(CbProjectConstants.CB_STAGE_BEFORE_BID);
cbStageList.add(CbProjectConstants.CB_STAGE_AFTER_BID);
cbStageList.add(CbProjectConstants.CB_STAGE_TO_SOLID);
projectRecordList.forEach(projectRecord -> {
cbStageList.remove(projectRecord.getCbStage());
});
return cbStageList;
}
/**
* 新增新阶段项目
*
* @param newProjectBo 新增对象
* @return 新增结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public CbProjectRecord addNewStageProject(AddNewCbProjectBo newProjectBo) {
//修改基础信息
this.editProjectInfo(BeanUtil.toBean(newProjectBo, EditProjectInfoBo.class));
//通过关联ID校验项目是否存在
List<CbProjectRecord> projectRecordList = this.checkRelatedIdExist(newProjectBo.getRelatedId());
//校验待新增的阶段是否已存在
projectRecordList.forEach(record -> {
Assert.isFalse(record.getCbStage().equals(newProjectBo.getCbStage()), "当前项目在该阶段已存在记录,请检查草稿箱或项目台账列表");
});
//新增该项目的新阶段
CbProjectRecord projectRecord = BeanUtil.toBean(newProjectBo, CbProjectRecord.class);
//项目文件状态:准备中
projectRecord.setProjectFileStatus(CbProjectConstants.PROJECT_FILE_STATUS_PREPARING);
//删除状态:否
projectRecord.setDelFlag(CbProjectConstants.DELETE_FLAG_EXIST);
if (baseMapper.insert(projectRecord) > 0) {
return projectRecord;
}
return null;
}
/**
* 通过关联ID校验项目是否存在
*
* @return 该关联ID下的所有项目记录
*/
private List<CbProjectRecord> checkRelatedIdExist(Long relatedId) {
List<CbProjectRecord> projectRecordList = baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>().eq(CbProjectRecord::getRelatedId, relatedId));
Assert.isFalse(projectRecordList.isEmpty(), "关联ID无效");
return projectRecordList;
}
/**
* 获取草稿弹窗列表
*
* @return 草稿弹窗列表
*/
@Override
public List<CbProjectRecord> getDraftDialogList() {
return baseMapper.selectList(new LambdaQueryWrapper<CbProjectRecord>()
.eq(CbProjectRecord::getProjectFileStatus, CbProjectConstants.PROJECT_FILE_STATUS_PREPARING));
}
/**
* 删除草稿
*
* @param projectId 项目ID
* @return 删除结果
*/
@Override
public Integer deleteDraft(Long projectId) {
//校验项目是否存在
CbProjectRecord projectRecord = this.checkProjectExist(projectId);
//删除该项目下已上传的文件
List<CbProjectFile> idList = projectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId));
if (!idList.isEmpty()) {
projectFileMapper.deleteBatchIds(idList);
}
//删除项目记录
return baseMapper.deleteById(projectRecord);
}
/**
* 校验项目是否存在
*
* @param projectId 项目ID
* @return 项目实体
*/
private CbProjectRecord checkProjectExist(Long projectId) {
CbProjectRecord projectRecord = baseMapper.selectById(projectId);
Assert.notNull(projectRecord, "该项目不存在");
return projectRecord;
}
}
package com.dsk.cscec.service.impl;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.CbQuantitySummaryActual;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo;
import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo;
import com.dsk.cscec.mapper.CbQuantitySummaryMapper;
import com.dsk.cscec.service.ICbQuantitySummaryActualService;
import com.dsk.cscec.service.ICbQuantitySummaryService;
import jodd.bean.BeanException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
......@@ -19,15 +30,20 @@ import java.util.stream.Collectors;
* @author lcl
* @since 2024-02-05 11:06:56
*/
@Slf4j
@Service
public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryMapper, CbQuantitySummary> implements ICbQuantitySummaryService {
@Autowired
private ICbQuantitySummaryActualService baseActualService;
@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(
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()))));
......@@ -41,8 +57,48 @@ public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryM
}
@Override
public List<String> monthList(CbProjectBaseBo bo) {
return null;
public List<String> monthList(CbQuantitySummaryListBo bo) {
return baseMapper.selectMonthList(bo);
}
@Override
public List<CbQuantitySummaryListVo> subjectList(CbQuantitySummaryListBo bo) {
return baseMapper.selectListBySubject(bo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateActual(List<CbQuantitySummaryActual> list) {
if (ObjectUtils.isEmpty(list)) throw new BeanException("数据不能为空");
for (CbQuantitySummaryActual actual : list) {
if (ObjectUtils.isEmpty(actual.getCbQuantitySummaryId())) throw new BeanException("基础数据id不能为空!");
if (ObjectUtils.isEmpty(actual.getQuantities())) throw new BeanException("工程量(本月用料)不能为空!");
if (ObjectUtils.isEmpty(actual.getRecordDate())) throw new BeanException("填写月份不能为空!");
actual.setId(ObjectUtils.isEmpty(actual.getId()) ? SecureUtil.md5(actual.getCbQuantitySummaryId() + actual.getRecordDate()) : actual.getId());
boolean b = baseActualService.saveOrUpdate(actual);
if (!b) {
log.error("CbQuantitySummaryServiceImpl.updateActual() data insert error! data:" + JSONUtil.toJsonStr(actual));
throw new ServiceException("数据添加错误!");
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void pushData(CbQuantitySummaryActual bo) {
//数据记录
if (ObjectUtils.isEmpty(bo.getId())) throw new BeanException("id不能为空!");
if (ObjectUtils.isEmpty(bo.getPushQuantities())) throw new BeanException("推送工程量不能为空!");
if (ObjectUtils.isEmpty(bo.getIpmProjectCode())) throw new BeanException("IPM项目编码不能为空!");
if (ObjectUtils.isEmpty(bo.getIpmContractCode())) throw new BeanException("IPM合同编码不能为空!");
if (ObjectUtils.isEmpty(bo.getIpmBizCode())) throw new BeanException("IPM作业编码不能为空!");
boolean update = baseActualService.updateById(bo);
if (!update) {
log.error("CbQuantitySummaryServiceImpl.pushData() data update error! data:" + JSONUtil.toJsonStr(bo));
throw new ServiceException("数据添加错误!");
}
//TODO 推送数据
}
}
package com.dsk.cscec.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.mapper.CbSummaryMapper;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
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.CbSummaryActualListBo;
import com.dsk.cscec.domain.bo.CbSummaryBo;
import com.dsk.cscec.domain.vo.CbSummaryActualListVo;
import com.dsk.cscec.mapper.CbProjectFileMapper;
import com.dsk.cscec.mapper.CbProjectRecordMapper;
import com.dsk.cscec.mapper.CbSummaryActualMapper;
import com.dsk.cscec.mapper.CbSummaryMapper;
import com.dsk.cscec.service.CbSummaryService;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 成本汇总(CbSummary)表服务实现类
......@@ -14,5 +41,162 @@ import org.springframework.stereotype.Service;
*/
@Service
public class CbSummaryServiceImpl extends ServiceImpl<CbSummaryMapper, CbSummary> implements CbSummaryService {
@Autowired
private CbProjectFileMapper cbProjectFileMapper;
@Autowired
private CbSummaryActualMapper cbSummaryActualMapper;
@Autowired
private CbProjectRecordMapper cbProjectRecordMapper;
@Override
public void importCbProject(Long projectId, Integer cbStage) {
//获取文件信息
List<CbProjectFile> cbProjectFiles = cbProjectFileMapper.selectList(new LambdaQueryWrapper<CbProjectFile>()
.eq(CbProjectFile::getProjectId, projectId)
.eq(CbProjectFile::getCbStage, cbStage)
.eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_SUMMARY)
);
//解析数据
cbProjectFiles.forEach(cbProjectFile -> {
MultipartFile file = null;//todo
if (cbProjectFile.getFileName().contains("项目")) {
} else if (cbProjectFile.getFileName().contains("项目")) {
} else {
//修改文件状态
cbProjectFile.setFileParseStatus(CbProjectConstants.PROJECT_FILE_STATUS_PARSE_FAIL);
cbProjectFile.setFailRemark("文件名错误!");
cbProjectFileMapper.updateById(cbProjectFile);
}
});
}
@Override
public List<Map<String, Object>> getCbNameList(CbSummaryBo bo) {
Assert.notNull(bo.getProjectId(), "项目id不能为空");
Assert.notNull(bo.getCbStage(), "成本阶段不能为空");
Assert.notNull(bo.getCbType(), "成本类型不能为空");
List<Map<String, Object>> resultList = new ArrayList<>();
bo.setLevel(0);
List<Map<String, Object>> cbNameTop = baseMapper.selectByLevel(bo);
bo.setLevel(1);
List<Map<String, Object>> cbNames = baseMapper.selectByLevel(bo);
resultList.addAll(cbNameTop);
resultList.addAll(cbNames);
return resultList;
}
@Override
public List<CbSummaryActualListVo> getActualList(CbSummaryActualListBo bo) {
Assert.notNull(bo.getId(),"id不能为空");
Assert.notNull(bo.getCbType(),"成本类型不能为空");
if (StringUtil.isBlank(bo.getExpenseDate())) {
//默认当前月
bo.setExpenseDate(DatePattern.SIMPLE_MONTH_FORMAT.format(new Date()));
}
CbSummary cbSummary = baseMapper.selectById(bo.getId());
if (ObjectUtil.isEmpty(cbSummary)) {
return null;
}
List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate());
if (0 == cbSummary.getLevel() && 1 == bo.getCbType()) {
//项目汇总
return childrenList;
}else if(0 == cbSummary.getLevel() && 2 == bo.getCbType()) {
//成本科目汇总
CbSummaryActualListVo cbSummaryActualListVo = baseMapper.getById(bo.getId(), bo.getExpenseDate());
cbSummaryActualListVo.setChildren(childrenList);
List<CbSummaryActualListVo> list = new ArrayList<>();
list.add(cbSummaryActualListVo);
return list;
}else {
childrenList = getProjectSumList(bo);
CbSummaryActualListVo cbSummaryActualListVo = baseMapper.getById(bo.getId(),bo.getExpenseDate());
cbSummaryActualListVo.setChildren(childrenList);
List<CbSummaryActualListVo> list = new ArrayList<>();
list.add(cbSummaryActualListVo);
return list;
}
}
/**
* 成本汇总列表
*
* @param bo
* @return
*/
private List<CbSummaryActualListVo> getProjectSumList(CbSummaryActualListBo bo) {
List<CbSummaryActualListVo> childrenList = baseMapper.getByParentId(bo.getId(), bo.getExpenseDate());
childrenList.forEach(children -> {
CbSummaryActualListBo childBo = new CbSummaryActualListBo();
childBo.setId(children.getId());
childBo.setExpenseDate(bo.getExpenseDate());
children.setChildren(getProjectSumList(childBo));
});
return childrenList;
}
@Override
public List<String> getExpenseDateList(CbSummaryBo bo) {
Assert.notNull(bo.getProjectId(),"项目id不能为空");
Assert.notNull(bo.getCbStage(),"成本阶段不能为空");
Assert.notNull(bo.getCbType(),"成本类型不能为空");
return baseMapper.getExpenseDateList(bo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean insertOrUpdateActual(List<CbSummaryActualBo> boList) {
if (CollectionUtil.isEmpty(boList)) {
return false;
}
boList.forEach(bo->{
Assert.notNull(bo.getCbSummaryId(),"成本汇总id不能为空");
Assert.notNull(bo.getExpenseDate(),"费用日期不能为空");
});
List<CbSummaryActual> actualList = BeanUtil.copyToList(boList, CbSummaryActual.class);
//todo
// throw new ServiceException("当前成本已锁定,不允许编辑!");
return cbSummaryActualMapper.insertOrUpdateBatch(actualList) > 0;
}
@Override
public List<CbSummaryActualListVo> getAll(CbSummaryActualListBo bo) {
Assert.notNull(bo.getId(), "项目id不能为空");
Assert.notNull(bo.getCbType(), "成本类型不能为空");
Assert.notNull(bo.getExpenseDate(), "费用日期不能为空");
//获取项目成本阶段
CbProjectRecord cbProjectRecord = cbProjectRecordMapper.selectById(bo.getId());
if (ObjectUtil.isNull(cbProjectRecord)) {
throw new ServiceException("当前项目不存在");
}
bo.setCbStage(cbProjectRecord.getCbStage());
if (bo.getCbType() == 1) {
return baseMapper.getProjectAll(bo);
} else {
return baseMapper.getCostAccountAll(bo);
}
//todo 截至本月费用汇总
}
}
package com.dsk.cscec.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.cscec.domain.CbCostMeasure;
import com.dsk.cscec.domain.CbCostMeasureActual;
import com.dsk.cscec.mapper.CbCostMeasureActualMapper;
import com.dsk.cscec.mapper.CbCostMeasureMapper;
import com.dsk.cscec.service.ICbCostMeasureActualService;
import org.springframework.stereotype.Service;
/**
* @author tanyang
* @create 2024-02-07 9:38
**/
@Service
public class ICbCostMeasureActualServiceImpl extends ServiceImpl<CbCostMeasureActualMapper, CbCostMeasureActual> implements ICbCostMeasureActualService {
}
......@@ -11,7 +11,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.StringUtils;
import com.dsk.cscec.constant.AdvisoryBodyManageQueryConstants;
import com.dsk.cscec.domain.AdvisoryBody;
......@@ -20,7 +19,6 @@ import com.dsk.cscec.domain.DProject;
import com.dsk.cscec.domain.bo.CooperateProjectDetailSearchBo;
import com.dsk.cscec.domain.bo.ProjectDetailBo;
import com.dsk.cscec.domain.bo.ProjectSearchBo;
import com.dsk.cscec.domain.vo.AdvisoryBodyExistVo;
import com.dsk.cscec.domain.vo.CooperateProjectDetailSearchVo;
import com.dsk.cscec.domain.vo.ProjectDetailVo;
import com.dsk.cscec.domain.vo.ProjectSearchVo;
......@@ -248,5 +246,17 @@ public class IDProjectServiceImpl extends ServiceImpl<DProjectMapper, DProject>
}
return projectDetailVo;
}
/**
* 校验项目编码是否存在
*
* @param projectCode 项目编码
* @return 校验结果
*/
@Override
public Boolean checkProjectCodeExist(String projectCode) {
return baseMapper.exists(new LambdaQueryWrapper<DProject>()
.eq(DProject::getProjectCode, projectCode));
}
}
<?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.CbCostMeasureActualMapper">
<resultMap id="BaseResultMap" type="com.dsk.cscec.domain.CbCostMeasureActual">
<!--@mbg.generated-->
<!--@Table cb_cost_measure_actual-->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="plan_measure_id" jdbcType="BIGINT" property="planMeasureId" />
<result column="month_cost_rate" jdbcType="DECIMAL" property="monthCostRate" />
<result column="cost_effective" jdbcType="DECIMAL" property="costEffective" />
<result column="current_project_volume" jdbcType="DECIMAL" property="currentProjectVolume" />
<result column="submit_project_volume" jdbcType="DECIMAL" property="submitProjectVolume" />
<result column="month" jdbcType="VARCHAR" property="month" />
<result column="push_time" jdbcType="TIMESTAMP" property="pushTime" />
<result column="push_data_json" jdbcType="LONGVARCHAR" property="pushDataJson" />
<result column="del_flag" jdbcType="INTEGER" property="delFlag" />
<result column="update_user" jdbcType="VARCHAR" property="updateUser" />
<result column="update_id" jdbcType="VARCHAR" property="updateId" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, plan_measure_id, month_cost_rate, cost_effective, current_project_volume, submit_project_volume,
`month`, push_time, push_data_json, del_flag, update_user, update_id, create_time,
update_time
</sql>
<insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.dsk.cscec.domain.CbCostMeasureActual" useGeneratedKeys="true">
<!--@mbg.generated-->
insert into cb_cost_measure_actual
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="planMeasureId != null">
plan_measure_id,
</if>
<if test="monthCostRate != null">
month_cost_rate,
</if>
<if test="costEffective != null">
cost_effective,
</if>
<if test="currentProjectVolume != null">
current_project_volume,
</if>
<if test="submitProjectVolume != null">
submit_project_volume,
</if>
<if test="month != null">
`month`,
</if>
<if test="pushTime != null">
push_time,
</if>
<if test="pushDataJson != null">
push_data_json,
</if>
<if test="delFlag != null">
del_flag,
</if>
<if test="updateUser != null">
update_user,
</if>
<if test="updateId != null">
update_id,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="updateTime != null">
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="planMeasureId != null">
#{planMeasureId,jdbcType=BIGINT},
</if>
<if test="monthCostRate != null">
#{monthCostRate,jdbcType=DECIMAL},
</if>
<if test="costEffective != null">
#{costEffective,jdbcType=DECIMAL},
</if>
<if test="currentProjectVolume != null">
#{currentProjectVolume,jdbcType=DECIMAL},
</if>
<if test="submitProjectVolume != null">
#{submitProjectVolume,jdbcType=DECIMAL},
</if>
<if test="month != null">
#{month,jdbcType=VARCHAR},
</if>
<if test="pushTime != null">
#{pushTime,jdbcType=TIMESTAMP},
</if>
<if test="pushDataJson != null">
#{pushDataJson,jdbcType=LONGVARCHAR},
</if>
<if test="delFlag != null">
#{delFlag,jdbcType=INTEGER},
</if>
<if test="updateUser != null">
#{updateUser,jdbcType=VARCHAR},
</if>
<if test="updateId != null">
#{updateId,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
#{updateTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.dsk.cscec.domain.CbCostMeasureActual">
<!--@mbg.generated-->
update cb_cost_measure_actual
<set>
<if test="planMeasureId != null">
plan_measure_id = #{planMeasureId,jdbcType=BIGINT},
</if>
<if test="monthCostRate != null">
month_cost_rate = #{monthCostRate,jdbcType=DECIMAL},
</if>
<if test="costEffective != null">
cost_effective = #{costEffective,jdbcType=DECIMAL},
</if>
<if test="currentProjectVolume != null">
current_project_volume = #{currentProjectVolume,jdbcType=DECIMAL},
</if>
<if test="submitProjectVolume != null">
submit_project_volume = #{submitProjectVolume,jdbcType=DECIMAL},
</if>
<if test="month != null">
`month` = #{month,jdbcType=VARCHAR},
</if>
<if test="pushTime != null">
push_time = #{pushTime,jdbcType=TIMESTAMP},
</if>
<if test="pushDataJson != null">
push_data_json = #{pushDataJson,jdbcType=LONGVARCHAR},
</if>
<if test="delFlag != null">
del_flag = #{delFlag,jdbcType=INTEGER},
</if>
<if test="updateUser != null">
update_user = #{updateUser,jdbcType=VARCHAR},
</if>
<if test="updateId != null">
update_id = #{updateId,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
update_time = #{updateTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<select id="selectDataList" resultType="com.dsk.cscec.domain.vo.CbCostMeasureActualVo">
SELECT t1.plan_measure_id,
t1.month_cost_rate,
t1.cost_effective,
t1.month_cost_rate,
t1.current_project_volume,
t1.submit_project_volume,
t1.`month`,
t1.push_time
FROM cb_cost_measure t
inner JOIN cb_cost_measure_actual t1 ON t1.plan_measure_id=t.id
WHERE
t.project_id=#{projectId}
AND t.cb_stage=#{cbStage}
AND t1.`month`=#{month}
</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.CbCostMeasureMapper">
<resultMap id="BaseResultMap" type="com.dsk.cscec.domain.CbCostMeasure">
<!--@mbg.generated-->
<!--@Table cb_cost_measure-->
<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="parent_id" jdbcType="BIGINT" property="parentId" />
<result column="level" jdbcType="INTEGER" property="level" />
<result column="number" jdbcType="VARCHAR" property="number" />
<result column="no" jdbcType="VARCHAR" property="no" />
<result column="item_content" jdbcType="VARCHAR" property="itemContent" />
<result column="work_content" jdbcType="VARCHAR" property="workContent" />
<result column="unit" jdbcType="VARCHAR" property="unit" />
<result column="quantity" jdbcType="DECIMAL" property="quantity" />
<result column="unit_price_excluding_tax" jdbcType="VARCHAR" property="unitPriceExcludingTax" />
<result column="usage_time" jdbcType="VARCHAR" property="usageTime" />
<result column="amount_excluding_tax" jdbcType="VARCHAR" property="amountExcludingTax" />
<result column="tax_rate" jdbcType="VARCHAR" property="taxRate" />
<result column="amount_including_tax" jdbcType="VARCHAR" property="amountIncludingTax" />
<result column="amortization_ratio" jdbcType="VARCHAR" property="amortizationRatio" />
<result column="amount_exclude_tax_amortized" jdbcType="VARCHAR" property="amountExcludeTaxAmortized" />
<result column="amount_include_tax_amortized" jdbcType="VARCHAR" property="amountIncludeTaxAmortized" />
<result column="tax_amount" jdbcType="VARCHAR" property="taxAmount" />
<result column="remarks" jdbcType="VARCHAR" property="remarks" />
<result column="cost_subject" jdbcType="VARCHAR" property="costSubject" />
<result column="tax_type" jdbcType="VARCHAR" property="taxType" />
<result column="data_source" jdbcType="INTEGER" property="dataSource" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
id, project_id, cb_stage, parent_id, `level`, `number`, `no`,item_content, work_content,
unit, quantity, unit_price_excluding_tax, usage_time, amount_excluding_tax, tax_rate,
amount_including_tax, amortization_ratio, amount_exclude_tax_amortized, amount_include_tax_amortized,
tax_amount, remarks, cost_subject, tax_type, create_time, update_time
</sql>
<select id="selectListByProjectAndNo" resultType="com.dsk.cscec.domain.vo.CbCostMeasureActualVo">
SELECT t.*,t1.plan_measure_id,t1.month_cost_rate, t1.cost_effective, t1.current_project_volume,t1.submit_project_volume,t1.`month`,t1.push_time FROM cb_cost_measure t
left JOIN (
SELECT t1.plan_measure_id,t1.month_cost_rate, t1.cost_effective, t1.current_project_volume,t1.submit_project_volume,t1.`month`,t1.push_time FROM cb_cost_measure t
inner JOIN cb_cost_measure_actual t1 ON t1.plan_measure_id=t.id
WHERE
t.project_id=#{projectId}
AND t.cb_stage=#{cbStage}
AND t1.`month`=#{month}) t1 ON t1.plan_measure_id=t.id
WHERE
t.project_id=#{projectId}
AND t.cb_stage=#{cbStage}
AND t.`level`!=0
AND t.`no` like concat(#{id},'.%')
ORDER BY id ASC
</select>
</mapper>
\ No newline at end of file
......@@ -2,6 +2,5 @@
<!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>
<?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.CbProjectRecordMapper">
<!--获取项目台账列表-->
<select id="selectPageProjectRecordList" resultType="com.dsk.cscec.domain.vo.ProjectRecordSearchVo">
select cpr.id,
cpr.project_name,
cpr.ipm_project_no,
cpr.project_file_name
from cb_project_record cpr
${ew.getCustomSqlSegment};
</select>
</mapper>
\ No newline at end of file
......@@ -8,7 +8,7 @@
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})
join cb_quantity_summary cqs on (cqs.cb_subject_name = cs3.cb_subject_name and cqs.del_falg = 0 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>
......@@ -18,7 +18,35 @@
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
where cqs.del_falg = 0 and cqs.project_id = #{projectId} and cqs.cb_stage = #{cbStage} and cs1.id is null
</select>
<select id="selectMonthList" resultType="java.lang.String">
select
cqsa.record_date
from cb_quantity_summary cqs
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}
group by cqsa.record_date
order by cqsa.record_date
</select>
<select id="selectListBySubject" resultType="com.dsk.cscec.domain.vo.CbQuantitySummaryListVo">
select a.*, ifnull(sum(a.quantities),0) totalQuantities from (
select
cqs.id, cqs.cb_subject_name, cqs.company_no, cqs.org_no, cqs.cb_name, cqs.job_content, cqs.calculation_rule,
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,
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
from cb_quantity_summary cqs
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}
<if test="recordDate != null and recordDate != ''"> and cqsa.record_date &lt;= #{recordDate} </if>
order by cqsa.record_date desc
) a
group by a.id
order by a.`number` asc
</select>
</mapper>
\ No newline at end of file
......@@ -17,5 +17,15 @@
id, cb_summary_id, tax_inclusive_expense, tax_exclusive_expense, expense_date, lock_status, create_time, del_flag
</sql>
<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into cb_summary_actual(id,cb_summary_id, tax_inclusive_expense, tax_exclusive_expense,expense_date)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.id}, #{entity.cbSummaryId}, #{entity.taxInclusiveExpense}, #{entity.taxExclusiveExpense}, #{entity.expenseDate})
</foreach>
on duplicate key update
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)
</insert>
</mapper>
......@@ -24,9 +24,114 @@
</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
csu.id, csu.parent_id, csu.level, csu.sort, csu.project_id, csu.cb_stage, csu.cb_project_file_id, csu.number, csu.cb_name, csu.tax_exclusive_total,
csu.cb_taxes_total, csu.tax_inclusive_total, csu.cb_proportion, csu.tax_inclusive_pm_target, csu.remark, csu.create_time, csu.del_flag,
csu.cb_type
</sql>
<select id="getByParentId" 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 and csa.expense_date = #{expenseDate} AND csa.del_flag = 0
<where>
csu.parent_id = #{parentId}
and csu.del_flag = 0
</where>
order by csu.sort
</select>
<select id="getById" 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 and csa.expense_date = #{expenseDate} AND csa.del_flag = 0
<where>
csu.id = #{id}
and csu.del_flag = 0
</where>
</select>
<select id="getProjectAll" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select
<include refid="baseColumn"></include>,
csa.tax_inclusive_expense,csa.tax_exclusive_expense
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
<where>
csu.project_id = #{bo.id}
and csu.cb_stage = #{bo.cbStage}
and csu.cb_type = #{bo.cbType}
and csu.del_flag = 0
and csu.level != 0
</where>
order by csu.sort
</select>
<select id="getCostAccountAll" resultType="com.dsk.cscec.domain.vo.CbSummaryActualListVo">
select
<include refid="baseColumn"></include>,
csa.tax_inclusive_expense,csa.tax_exclusive_expense
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
<where>
csu.project_id = #{bo.projectId}
and csu.cb_stage = #{bo.cbStage}
and csu.cb_type = #{bo.cbType}
and csu.del_flag = 0
</where>
order by csu.sort
</select>
<select id="getExpenseDateList" resultType="string">
select csa.expense_date
from cb_summary_actual csa
left join cb_summary csu on csu.id = csa.cb_summary_id
where
csu.project_id = #{bo.projectId}
and csu.cb_stage = #{bo.cbStage}
and csu.cb_type = #{bo.cbType}
and csu.del_flag = 0
and csa.del_flag = 0
group by csa.expense_date
order by csa.expense_date asc
</select>
<select id="selectByLevel" resultType="map">
select csu.id,csu.cb_name as cbName
from cb_summary csu
where
csu.del_flag = 0
and csu.project_id = #{bo.projectId}
and csu.cb_stage = #{bo.cbStage}
and csu.cb_type = #{bo.cbType}
and csu.level = #{bo.level}
order by csu.sort
</select>
<select id="getGainLossAnalysisById" resultType="com.dsk.cscec.domain.vo.CbGainLossAnalysisListVo">
select csu.id, csu.cb_name, csu.tax_exclusive_total, csu.cb_taxes_total, csu.tax_inclusive_total, csa.tax_inclusive_expense, csa.tax_exclusive_expense,
sum(cde.tender_control_sum_price) tenderSumPrice, sum(cde.exclude_tax_cb_sum_price) taxExcludeTenderSumPrice, sum(cde.include_tax_cb_sum_price) taxIncludeTenderSumPrice,
sum(csa1.tax_inclusive_expense) sumTaxInclusiveExpense, sum(csa1.tax_exclusive_expense) sumTaxExclusiveExpense
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 csa1 on (csu.id = csa1.cb_summary_id and csa1.expense_date &lt;= #{expenseDate} AND csa1.del_flag = 0)
left join cb_direct_expense cde on (csu.project_id = cde.project_id and csu.cb_stage = cde.cb_stage and cde.del_flag = 0)
where csu.id = #{id} and csu.del_flag = 0
group by csu.id
order by csu.sort
</select>
<select id="getGainLossAnalysisByParentId" resultType="com.dsk.cscec.domain.vo.CbGainLossAnalysisListVo">
select csu.id, csu.cb_name, csu.tax_exclusive_total, csu.cb_taxes_total, csu.tax_inclusive_total, csa.tax_inclusive_expense, csa.tax_exclusive_expense,
sum(cde.tender_control_sum_price) tenderSumPrice, sum(cde.exclude_tax_cb_sum_price) taxExcludeTenderSumPrice, sum(cde.include_tax_cb_sum_price) taxIncludeTenderSumPrice,
sum(csa1.tax_inclusive_expense) sumTaxInclusiveExpense, sum(csa1.tax_exclusive_expense) sumTaxExclusiveExpense
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 csa1 on (csu.id = csa1.cb_summary_id and csa1.expense_date &lt;= #{expenseDate} AND csa1.del_flag = 0)
left join cb_direct_expense cde on (csu.project_id = cde.project_id and csu.cb_stage = cde.cb_stage and cde.del_flag = 0)
where csu.parent_id = #{parentId} and csu.del_flag = 0
group by csu.id
order by csu.sort
</select>
</mapper>
import request from '@/utils/request'
//校验项目编码是否存在
export function checkProjectCodeExist (data) {
return request({
url: '/cbProjectRecord/checkProjectCodeExist/'+data,
method: 'get',
})
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="12" height="12" viewBox="0 0 12 12"><g><g><path d="M2,6C2,3.79085,3.79085,2,6,2C8.209150000000001,2,10,3.79085,10,6C10,8.209150000000001,8.209150000000001,10,6,10C3.79085,10,2,8.209150000000001,2,6C2,6,2,6,2,6ZM6,1C3.23857,1,1,3.23857,1,6C1,8.76143,3.23857,11,6,11C8.76143,11,11,8.76143,11,6C11,3.23857,8.76143,1,6,1C6,1,6,1,6,1ZM5.15,4.99465C5.15,4.99465,5.15,4.8793500000000005,5.15,4.8793500000000005C5.1506,4.742179999999999,5.19968,4.59,5.30912,4.4756C5.41022,4.369949999999999,5.60728,4.25,5.99713,4.25C6.36322,4.25,6.61783,4.424799999999999,6.74765,4.6232500000000005C6.8863,4.8351500000000005,6.85897,5.01298,6.79318,5.10183C6.7111,5.21263,6.6092,5.31495,6.48607,5.4258C6.4486,5.45953,6.40242,5.49972,6.3529,5.5428C6.3529,5.5428,6.3529,5.54283,6.3529,5.54283C6.26435,5.61985,6.16515,5.70617,6.08605,5.78145C5.80517,6.0487,5.5001,6.4217,5.5001,7C5.5001,7,5.50173,7.2532,5.50173,7.2532C5.50173,7.2532,6.5017,7.2468,6.5017,7.2468C6.5017,7.2468,6.5001,6.99862,6.5001,6.99862C6.50047,6.82762,6.57058,6.70078,6.77537,6.5059C6.84422,6.4404,6.9061,6.38685,6.9769,6.3256C6.9769,6.3256,6.97692,6.32557,6.97692,6.32557C7.0293,6.28027,7.08655,6.23075,7.15513,6.16902C7.2977,6.04065,7.45638,5.88653,7.59675,5.69702C7.9758,5.1853,7.88715,4.5384,7.58448,4.07575C7.27297,3.59963,6.7062,3.25,5.99713,3.25C5.3835,3.25,4.90777,3.44858,4.58658,3.78428C4.27393,4.1110500000000005,4.1511499999999995,4.5227699999999995,4.15,4.87683C4.15,4.87683,4.15,4.99465,4.15,4.99465C4.15,4.99465,5.15,4.99465,5.15,4.99465C5.15,4.99465,5.15,4.99465,5.15,4.99465ZM5.5017,7.75C5.5017,7.75,5.5017,8.75195,5.5017,8.75195C5.5017,8.75195,6.5017,8.75195,6.5017,8.75195C6.5017,8.75195,6.5017,7.75,6.5017,7.75C6.5017,7.75,5.5017,7.75,5.5017,7.75C5.5017,7.75,5.5017,7.75,5.5017,7.75Z" fill-rule="evenodd" fill="#FFAB44" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014428"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014428)"><g><path d="M11.015985625,1.8333282470703125L10.332685625,1.8333282470703125Q10.283435625,1.8333282470703125,10.235135625,1.8429352470703124Q10.186835625,1.8525432470703125,10.141345625,1.8713882470703125Q10.095845624999999,1.8902342470703126,10.054895625,1.9175932470703125Q10.013955625000001,1.9449532470703126,9.979125625,1.9797752470703125Q9.944305625,2.0145972470703124,9.916945625,2.0555432470703123Q9.889585624999999,2.0964892470703127,9.870745625,2.1419862470703124Q9.851895625000001,2.1874832470703125,9.842285624999999,2.2357831470703124Q9.832685625,2.2840825470703123,9.832685625,2.3333282470703125Q9.832685625,2.3825739470703127,9.842285624999999,2.4308733470703126Q9.851895625000001,2.4791732470703125,9.870745625,2.5246702470703126Q9.889585624999999,2.5701672470703123,9.916945625,2.6111132470703127Q9.944305625,2.6520592470703126,9.979125625,2.6868812470703123Q10.013955625000001,2.7217032470703124,10.054895625,2.7490632470703127Q10.095845624999999,2.7764222470703124,10.141345625,2.7952682470703127Q10.186835625,2.8141132470703125,10.235135625,2.8237212470703126Q10.283435625,2.8333282470703125,10.332685625,2.8333282470703125L12.666015625,2.8333282470703125Q12.832715625,2.8333282470703125,12.832715625,2.9999952470703124L12.832715625,14.000028247070313Q12.832715625,14.166628247070312,12.666015625,14.166628247070312L3.332682625,14.166628247070312Q3.2636436250000003,14.166628247070312,3.214829625,14.117828247070312Q3.166015625,14.069028247070312,3.166015625,14.000028247070313L3.166015625,2.9999952470703124Q3.166015625,2.8333282470703125,3.332682625,2.8333282470703125L5.332685625,2.8333282470703125L5.666015625,2.8333282470703125Q5.715265625,2.8333282470703125,5.763555625,2.8237212470703126Q5.811855625,2.8141132470703125,5.857355625,2.7952682470703127Q5.902855625,2.7764222470703124,5.943795625,2.7490632470703127Q5.984745625,2.7217032470703124,6.019565625,2.6868812470703123Q6.054385625,2.6520592470703126,6.081745625,2.6111132470703127Q6.109105625,2.5701672470703123,6.127955625,2.5246702470703126Q6.146795625,2.4791732470703125,6.156405625,2.4308733470703126Q6.166015625,2.3825739470703127,6.166015625,2.3333282470703125Q6.166015625,2.2840825470703123,6.156405625,2.2357831470703124Q6.146795625,2.1874832470703125,6.127955625,2.1419862470703124Q6.109105625,2.0964892470703127,6.081745625,2.0555432470703123Q6.054385625,2.0145972470703124,6.019565625,1.9797752470703125Q5.984745625,1.9449532470703126,5.943795625,1.9175932470703125Q5.902855625,1.8902342470703126,5.857355625,1.8713882470703125Q5.811855625,1.8525432470703125,5.763555625,1.8429352470703124Q5.715265625,1.8333282470703125,5.666015625,1.8333282470703125L5.332685625,1.8333282470703125L3.332682625,1.8333282470703125Q2.849432625,1.8333282470703125,2.507724625,2.1750372470703123Q2.166015625,2.5167452470703124,2.166015625,2.9999952470703124L2.166015625,14.000028247070313Q2.166015625,14.483228247070313,2.507725625,14.824928247070313Q2.849433625,15.166628247070312,3.332682625,15.166628247070312L12.666015625,15.166628247070312Q13.149315625,15.166628247070312,13.491015625,14.824928247070313Q13.832715625,14.483228247070313,13.832715625,14.000028247070313L13.832715625,2.9999952470703124Q13.832715625,2.5167452470703124,13.491015625,2.1750392470703126Q13.149315625,1.8333282470703125,12.666015625,1.8333282470703125L11.015985625,1.8333282470703125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M5.166015625,3.3333282470703125L5.166015625,1.3333282470703125Q5.166015625,1.2840825470703126,5.175622625,1.2357831470703124Q5.185230625,1.1874832470703125,5.204075625,1.1419862470703124Q5.222921625,1.0964892470703125,5.250280625,1.0555432470703126Q5.277640625,1.0145972470703124,5.312462625,0.9797752470703125Q5.347284625,0.9449532470703125,5.388230625,0.9175932470703125Q5.429176625,0.8902342470703125,5.474673625,0.8713882470703125Q5.520170625,0.8525432470703125,5.568470525,0.8429352470703124Q5.616769925,0.8333282470703125,5.666015625,0.8333282470703125L10.332685625,0.8333282470703125Q10.381925625000001,0.8333282470703125,10.430225625,0.8429352470703124Q10.478525625,0.8525432470703125,10.524025625,0.8713882470703125Q10.569525625,0.8902342470703125,10.610465625,0.9175932470703125Q10.651415625,0.9449532470703125,10.686235625,0.9797752470703125Q10.721055625,1.0145972470703124,10.748415625,1.0555432470703126Q10.775775625,1.0964892470703125,10.794625625,1.1419862470703124Q10.813465625,1.1874832470703125,10.823075625000001,1.2357831470703124Q10.832685625,1.2840825470703126,10.832685625,1.3333282470703125L10.832685625,3.3333282470703125Q10.832685625,3.3825782470703123,10.823075625000001,3.4308682470703125Q10.813465625,3.4791682470703127,10.794625625,3.5246682470703123Q10.775775625,3.5701682470703124,10.748415625,3.6111082470703124Q10.721055625,3.6520582470703125,10.686235625,3.6868782470703123Q10.651415625,3.7217082470703127,10.610465625,3.7490582470703124Q10.569525625,3.7764182470703127,10.524025625,3.7952682470703123Q10.478525625,3.8141082470703127,10.430225625,3.8237182470703126Q10.381925625000001,3.8333282470703125,10.332685625,3.8333282470703125L5.666015625,3.8333282470703125Q5.616769925,3.8333282470703125,5.568470525,3.8237182470703126Q5.520170625,3.8141082470703127,5.474673625,3.7952682470703123Q5.429176625,3.7764182470703127,5.388230625,3.7490582470703124Q5.347284625,3.7217082470703127,5.312462625,3.6868782470703123Q5.277640625,3.6520582470703125,5.250280625,3.6111182470703125Q5.222921625,3.5701682470703124,5.204075625,3.5246682470703123Q5.185230625,3.4791682470703127,5.175622625,3.4308682470703125Q5.166015625,3.3825782470703123,5.166015625,3.3333282470703125ZM6.166015625,1.8333282470703125L6.166015625,2.8333282470703125L9.832685625,2.8333282470703125L9.832685625,1.8333282470703125L6.166015625,1.8333282470703125Z" fill="#232323" fill-opacity="1"/></g><g><path d="M6,10.5L10,10.5Q10.04925,10.5,10.09755,10.490393Q10.14584,10.480785000000001,10.19134,10.46194Q10.23684,10.443094,10.27778,10.415735Q10.31873,10.388375,10.35355,10.353553Q10.38837,10.318731,10.41573,10.277785Q10.44309,10.236839,10.46194,10.191342Q10.48078,10.145845,10.49039,10.0975451Q10.5,10.0492457,10.5,10Q10.5,9.9507543,10.49039,9.9024549Q10.48078,9.854155,10.46194,9.808658Q10.44309,9.763161,10.41573,9.722215Q10.38837,9.681269,10.35355,9.646447Q10.31873,9.611625,10.27778,9.584265Q10.23684,9.556906,10.19134,9.53806Q10.14584,9.519214999999999,10.09755,9.509607Q10.04925,9.5,10,9.5L6,9.5Q5.9507543,9.5,5.9024549,9.509607Q5.854155,9.519214999999999,5.808658,9.53806Q5.763161,9.556906,5.722215,9.584265Q5.681269,9.611625,5.646447,9.646447Q5.611625,9.681269,5.584265,9.722215Q5.556906,9.763161,5.53806,9.808658Q5.519215,9.854155,5.509607,9.9024549Q5.5,9.9507543,5.5,10Q5.5,10.0492457,5.509607,10.0975451Q5.519215,10.145845,5.53806,10.191342Q5.556906,10.236839,5.584265,10.277785Q5.611625,10.318731,5.646447,10.353553Q5.681269,10.388375,5.722215,10.415735Q5.763161,10.443094,5.808658,10.46194Q5.854155,10.480785000000001,5.9024549,10.490393Q5.9507543,10.5,6,10.5Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6,8.5L10,8.5Q10.04925,8.5,10.09755,8.490393Q10.14584,8.480785000000001,10.19134,8.46194Q10.23684,8.443094,10.27778,8.415735Q10.31873,8.388375,10.35355,8.353553Q10.38837,8.318731,10.41573,8.277785Q10.44309,8.236839,10.46194,8.191342Q10.48078,8.145845,10.49039,8.0975451Q10.5,8.0492457,10.5,8Q10.5,7.9507543,10.49039,7.9024549Q10.48078,7.854155,10.46194,7.808658Q10.44309,7.763161,10.41573,7.722215Q10.38837,7.681269,10.35355,7.646447Q10.31873,7.611625,10.27778,7.584265Q10.23684,7.556906,10.19134,7.53806Q10.14584,7.519215,10.09755,7.509607Q10.04925,7.5,10,7.5L6,7.5Q5.9507543,7.5,5.9024549,7.509607Q5.854155,7.519215,5.808658,7.53806Q5.763161,7.556906,5.722215,7.584265Q5.681269,7.611625,5.646447,7.646447Q5.611625,7.681269,5.584265,7.722215Q5.556906,7.763161,5.53806,7.808658Q5.519215,7.854155,5.509607,7.9024549Q5.5,7.9507543,5.5,8Q5.5,8.0492457,5.509607,8.0975451Q5.519215,8.145845,5.53806,8.191342Q5.556906,8.236839,5.584265,8.277785Q5.611625,8.318731,5.646447,8.353553Q5.681269,8.388375,5.722215,8.415735Q5.763161,8.443094,5.808658,8.46194Q5.854155,8.480785000000001,5.9024549,8.490393Q5.9507543,8.5,6,8.5Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014462"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014462)"><g><path d="M3.1666717529296875,4.666581953125L3.1666717529296875,14.666551953125Q3.1666717529296875,14.715851953125,3.1762787529296874,14.764151953125Q3.1858867529296875,14.812451953125,3.2047317529296873,14.857951953125Q3.2235777529296876,14.903451953125,3.2509367529296873,14.944351953125Q3.2782967529296876,14.985351953125,3.3131187529296877,15.020151953125Q3.3479407529296874,15.054951953125,3.3888867529296873,15.082351953125Q3.4298327529296877,15.109651953125,3.4753297529296874,15.128551953125Q3.5208267529296875,15.147351953125,3.5691266529296874,15.156951953125Q3.6174260529296873,15.166551953125,3.6666717529296875,15.166551953125L8.333341752929687,15.166551953125Q8.382581752929688,15.166551953125,8.430881752929688,15.156951953125Q8.479181752929687,15.147351953125,8.524681752929688,15.128551953125Q8.570181752929688,15.109651953125,8.611121752929687,15.082351953125Q8.652071752929688,15.054951953125,8.686891752929688,15.020151953125Q8.721711752929687,14.985351953125,8.749071752929687,14.944351953125Q8.776431752929687,14.903451953125,8.795281752929688,14.857951953125Q8.814121752929687,14.812451953125,8.823731752929689,14.764151953125Q8.833341752929687,14.715851953125,8.833341752929687,14.666551953125L8.833341752929687,1.333251953125Q8.833341752929687,1.173018953125,8.740201752929687,1.042632953125Q8.682401752929687,0.961701953125,8.598021752929688,0.9090539531249999Q8.513641752929686,0.856405953125,8.415541752929688,0.840054953125Q8.317431752929688,0.823704953125,8.220541752929687,0.8461409531249999Q8.123651752929687,0.868577953125,8.042721752929687,0.926384953125L3.3760527529296875,4.259721953125Q3.2775037529296873,4.330111953125,3.2220877529296876,4.437791953125Q3.1666717529296875,4.545481953125,3.1666717529296875,4.666581953125ZM4.1666717529296875,14.166551953125L7.833341752929687,14.166551953125L7.833341752929687,2.3048469531249998L4.1666717529296875,4.9238919531250005L4.1666717529296875,14.166551953125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M12.499998247070312,7.9238919531250005L12.499998247070312,14.666551953125Q12.499998247070312,14.715851953125,12.509598247070311,14.764151953125Q12.519208247070313,14.812451953125,12.538058247070312,14.857951953125Q12.556898247070311,14.903451953125,12.584258247070313,14.944351953125Q12.611618247070313,14.985351953125,12.646438247070312,15.020151953125Q12.681258247070312,15.054951953125,12.722208247070313,15.082351953125Q12.763158247070312,15.109651953125,12.808648247070312,15.128551953125Q12.854148247070313,15.147351953125,12.902448247070312,15.156951953125Q12.950748247070312,15.166551953125,12.999998247070312,15.166551953125Q13.049238247070313,15.166551953125,13.097538247070313,15.156951953125Q13.145838247070312,15.147351953125,13.191338247070313,15.128551953125Q13.236838247070313,15.109651953125,13.277778247070312,15.082351953125Q13.318728247070313,15.054951953125,13.353548247070313,15.020151953125Q13.388368247070312,14.985351953125,13.415728247070312,14.944351953125Q13.443088247070312,14.903451953125,13.461938247070313,14.857951953125Q13.480778247070312,14.812451953125,13.490388247070314,14.764151953125Q13.499998247070312,14.715851953125,13.499998247070312,14.666551953125L13.499998247070312,7.666581953125Q13.499998247070312,7.545481953125,13.444578247070313,7.437791953125Q13.389158247070313,7.330111953125,13.290618247070313,7.259721953125L8.623947247070312,3.926384953125Q8.493560247070313,3.833251953125,8.333328171970212,3.833251953125Q8.317901447070312,3.833251953125,8.302503947070312,3.834202953125Q8.189746247070312,3.841167953125,8.090936247070312,3.895934953125Q7.9921262470703125,3.950702953125,7.926461247070312,4.042632953125Q7.8333282470703125,4.173018953125,7.8333282470703125,4.333251953125Q7.8333282470703125,4.348678753125,7.834279247070312,4.364076253125Q7.841244247070312,4.476833953125,7.896011247070312,4.575643953125Q7.9507792470703125,4.674453953125,8.042709247070313,4.740118953125L12.499998247070312,7.9238919531250005Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M1.3333282470703125,15.166748046875L14.666628247070312,15.166748046875Q14.715928247070313,15.166748046875,14.764228247070312,15.157141046875Q14.812528247070313,15.147533046875001,14.858028247070312,15.128688046875Q14.903528247070312,15.109842046875,14.944428247070313,15.082483046875Q14.985428247070313,15.055123046875,15.020228247070312,15.020301046875Q15.055028247070313,14.985479046875,15.082428247070313,14.944533046875Q15.109728247070313,14.903587046875,15.128628247070312,14.858090046875Q15.147428247070312,14.812593046875,15.157028247070313,14.764293146875Q15.166628247070312,14.715993746875,15.166628247070312,14.666748046875Q15.166628247070312,14.617502346875,15.157028247070313,14.569202946875Q15.147428247070312,14.520903046875,15.128628247070312,14.475406046875Q15.109728247070313,14.429909046875,15.082428247070313,14.388963046875Q15.055028247070313,14.348017046875,15.020228247070312,14.313195046875Q14.985428247070313,14.278373046875,14.944428247070313,14.251013046875Q14.903528247070312,14.223654046875,14.858028247070312,14.204808046875Q14.812528247070313,14.185963046874999,14.764228247070312,14.176355046875Q14.715928247070313,14.166748046875,14.666628247070312,14.166748046875L1.3333282470703125,14.166748046875Q1.2840825470703126,14.166748046875,1.2357831470703124,14.176355046875Q1.1874832470703125,14.185963046874999,1.1419862470703124,14.204808046875Q1.0964892470703125,14.223654046875,1.0555432470703126,14.251013046875Q1.0145972470703124,14.278373046875,0.9797752470703125,14.313195046875Q0.9449532470703125,14.348017046875,0.9175932470703125,14.388963046875Q0.8902342470703125,14.429909046875,0.8713882470703125,14.475406046875Q0.8525432470703125,14.520903046875,0.8429352470703124,14.569202946875Q0.8333282470703125,14.617502346875,0.8333282470703125,14.666748046875Q0.8333282470703125,14.715993746875,0.8429352470703124,14.764293146875Q0.8525432470703125,14.812593046875,0.8713882470703125,14.858090046875Q0.8902342470703125,14.903587046875,0.9175932470703125,14.944533046875Q0.9449532470703125,14.985479046875,0.9797752470703125,15.020301046875Q1.0145972470703124,15.055123046875,1.0555432470703126,15.082483046875Q1.0964892470703125,15.109842046875,1.1419862470703124,15.128688046875Q1.1874832470703125,15.147533046875001,1.2357831470703124,15.157141046875Q1.2840825470703126,15.166748046875,1.3333282470703125,15.166748046875Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014467"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014467)"><g><path d="M7.16667,6L7.16667,2.666667Q7.16667,2.183417,6.82496,1.841711Q6.48326,1.5,6,1.5L2.666667,1.5Q2.183417,1.5,1.841709,1.841709Q1.5,2.183417,1.5,2.666667L1.5,6Q1.5,6.48326,1.841711,6.82496Q2.183417,7.16667,2.666667,7.16667L6,7.16667Q6.48326,7.16667,6.82496,6.82496Q7.16667,6.48326,7.16667,6ZM6,2.5Q6.16667,2.5,6.16667,2.666667L6.16667,6Q6.16667,6.16667,6,6.16667L2.666667,6.16667Q2.5,6.16667,2.5,6L2.5,2.666667Q2.5,2.5,2.666667,2.5L6,2.5Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M7.16667,13.333251953125L7.16667,9.999918953125Q7.16667,9.516661953125,6.82496,9.174956953125Q6.48326,8.833251953125,6,8.833251953125L2.666667,8.833251953125Q2.183417,8.833251953125,1.841711,9.174954953125Q1.5,9.516661953125,1.5,9.999918953125L1.5,13.333251953125Q1.5,13.816511953125,1.84171,14.158211953125Q2.183417,14.499921953125,2.666667,14.499921953125L6,14.499921953125Q6.48326,14.499921953125,6.82496,14.158211953125Q7.16667,13.816511953125,7.16667,13.333251953125ZM6,9.833251953125Q6.16667,9.833251953125,6.16667,9.999918953125L6.16667,13.333251953125Q6.16667,13.499921953125,6,13.499921953125L2.666667,13.499921953125Q2.5,13.499921953125,2.5,13.333251953125L2.5,9.999918953125Q2.5,9.833251953125,2.666667,9.833251953125L6,9.833251953125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M14.499998247070312,6L14.499998247070312,2.666667Q14.499998247070312,2.183417,14.158288247070313,1.84171Q13.816588247070312,1.5,13.333328247070312,1.5L9.999995247070313,1.5Q9.516738247070313,1.5,9.175031247070313,1.841711Q8.833328247070312,2.183417,8.833328247070312,2.666667L8.833328247070312,6Q8.833328247070312,6.48326,9.175033247070312,6.82496Q9.516738247070313,7.16667,9.999995247070313,7.16667L13.333328247070312,7.16667Q13.816588247070312,7.16667,14.158288247070313,6.82496Q14.499998247070312,6.48326,14.499998247070312,6ZM13.333328247070312,2.5Q13.499998247070312,2.5,13.499998247070312,2.666667L13.499998247070312,6Q13.499998247070312,6.16667,13.333328247070312,6.16667L9.999995247070313,6.16667Q9.833328247070312,6.16667,9.833328247070312,6L9.833328247070312,2.666667Q9.833328247070312,2.5,9.999995247070313,2.5L13.333328247070312,2.5Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M14.499998247070312,13.333251953125L14.499998247070312,9.999918953125Q14.499998247070312,9.516660953125,14.158288247070313,9.174956953125Q13.816588247070312,8.833251953125,13.333328247070312,8.833251953125L9.999995247070313,8.833251953125Q9.516738247070313,8.833251953125,9.175033247070312,9.174956953125Q8.833328247070312,9.516661953125,8.833328247070312,9.999918953125L8.833328247070312,13.333251953125Q8.833328247070312,13.816511953125,9.175033247070312,14.158211953125Q9.516737247070312,14.499921953125,9.999995247070313,14.499921953125L13.333328247070312,14.499921953125Q13.816588247070312,14.499921953125,14.158288247070313,14.158211953125Q14.499998247070312,13.816511953125,14.499998247070312,13.333251953125ZM13.333328247070312,9.833251953125Q13.499998247070312,9.833251953125,13.499998247070312,9.999918953125L13.499998247070312,13.333251953125Q13.499998247070312,13.499921953125,13.333328247070312,13.499921953125L9.999995247070313,13.499921953125Q9.833328247070312,13.499921953125,9.833328247070312,13.333251953125L9.833328247070312,9.999918953125Q9.833328247070312,9.833251953125,9.999995247070313,9.833251953125L13.333328247070312,9.833251953125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014473"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014473)"><g><path d="M0.83331298828125,12.66679609375L0.83331298828125,3.33349609375Q0.83331298828125,2.71217609375,1.27265278828125,2.27283589375Q1.7119929882812501,1.83349609375,2.33331298828125,1.83349609375L13.66661298828125,1.83349609375Q14.28801298828125,1.83349609375,14.72731298828125,2.27283589375Q15.16661298828125,2.71217509375,15.16661298828125,3.33349609375L15.16661298828125,12.66679609375Q15.16661298828125,13.28819609375,14.72731298828125,13.72749609375Q14.28801298828125,14.16679609375,13.66661298828125,14.16679609375L2.33331298828125,14.16679609375Q1.7119929882812501,14.16679609375,1.27265278828125,13.72749609375Q0.83331298828125,13.28819609375,0.83331298828125,12.66679609375ZM1.83331298828125,12.66679609375Q1.83331298828125,12.87389609375,1.97975998828125,13.02039609375Q2.12620798828125,13.16679609375,2.33331298828125,13.16679609375L13.66661298828125,13.16679609375Q13.87371298828125,13.16679609375,14.02021298828125,13.02039609375Q14.16661298828125,12.87389609375,14.16661298828125,12.66679609375L14.16661298828125,3.33349609375Q14.16661298828125,3.12639009375,14.02021298828125,2.97994309375Q13.87371298828125,2.83349609375,13.66661298828125,2.83349609375L2.33331298828125,2.83349609375Q2.12620598828125,2.83349609375,1.97975998828125,2.97994309375Q1.83331298828125,3.12638909375,1.83331298828125,3.33349609375L1.83331298828125,12.66679609375Z" fill="#232323" fill-opacity="1"/></g><g><path d="M10.35330896484375,5.353741L10.35348896484375,5.353553Q10.42381896484375,5.283227,10.46187896484375,5.191342Q10.49993896484375,5.0994562,10.49993896484375,5Q10.49993896484375,4.9005438,10.46187896484375,4.808658Q10.42381896484375,4.716773,10.35348896484375,4.646447Q10.28316896484375,4.57612,10.19127896484375,4.53806Q10.09939896484375,4.5,9.99993896484375,4.5Q9.90047896484375,4.5,9.80859896484375,4.53806Q9.71670896484375,4.57612,9.64638896484375,4.646447L9.64619896484375,4.646634L7.99993896484375,6.29289L6.35349196484375,4.646447Q6.28316596484375,4.57612,6.19128096484375,4.53806Q6.09939516484375,4.5,5.99993896484375,4.5Q5.90048276484375,4.5,5.80859696484375,4.53806Q5.71671196484375,4.57612,5.64638596484375,4.646447Q5.57605896484375,4.716773,5.53799896484375,4.808658Q5.49993896484375,4.9005438,5.49993896484375,5Q5.49993896484375,5.0994562,5.53799896484375,5.191342Q5.57605896484375,5.283227,5.64638596484375,5.353553L7.64638896484375,7.35355Q7.71670896484375,7.4238800000000005,7.80859896484375,7.46194Q7.9004789648437495,7.5,7.99993896484375,7.5Q8.09939896484375,7.5,8.19127896484375,7.46194Q8.28316896484375,7.4238800000000005,8.35348896484375,7.35355L10.35330896484375,5.353741Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M5.6666259765625,8.16650390625L10.3332959765625,8.16650390625Q10.3825459765625,8.16650390625,10.4308459765625,8.15689690625Q10.4791459765625,8.147288906250001,10.5246459765625,8.12844390625Q10.5701359765625,8.10959790625,10.6110859765625,8.08223890625Q10.6520259765625,8.05487890625,10.6868559765625,8.02005690625Q10.7216759765625,7.98523490625,10.7490359765625,7.94428890625Q10.776395976562501,7.90334290625,10.7952359765625,7.85784590625Q10.814085976562499,7.81234890625,10.823695976562501,7.76404900625Q10.8332959765625,7.71574960625,10.8332959765625,7.66650390625Q10.8332959765625,7.61725820625,10.823695976562501,7.56895880625Q10.814085976562499,7.52065890625,10.7952359765625,7.47516190625Q10.776395976562501,7.42966490625,10.7490359765625,7.38871890625Q10.7216759765625,7.34777290625,10.6868559765625,7.31295090625Q10.6520259765625,7.27812890625,10.6110859765625,7.25076890625Q10.5701359765625,7.22340990625,10.5246459765625,7.20456390625Q10.4791459765625,7.18571890625,10.4308459765625,7.17611090625Q10.3825459765625,7.16650390625,10.3332959765625,7.16650390625L5.6666259765625,7.16650390625Q5.6173802765625,7.16650390625,5.5690808765625,7.17611090625Q5.5207809765625,7.18571890625,5.4752839765625,7.20456390625Q5.4297869765625,7.22340990625,5.3888409765625,7.25076890625Q5.3478949765625,7.27812890625,5.3130729765625,7.31295090625Q5.2782509765625,7.34777290625,5.2508909765625,7.38871890625Q5.2235319765625,7.42966490625,5.2046859765625,7.47516190625Q5.1858409765625,7.52065890625,5.1762329765625,7.56895880625Q5.1666259765625,7.61725820625,5.1666259765625,7.66650390625Q5.1666259765625,7.71574960625,5.1762329765625,7.76404900625Q5.1858409765625,7.81234890625,5.2046859765625,7.85784590625Q5.2235319765625,7.90334290625,5.2508909765625,7.94428890625Q5.2782509765625,7.98523490625,5.3130729765625,8.02005690625Q5.3478949765625,8.05487890625,5.3888409765625,8.08223890625Q5.4297869765625,8.10959790625,5.4752839765625,8.12844390625Q5.5207809765625,8.147288906250001,5.5690808765625,8.15689690625Q5.6173802765625,8.16650390625,5.6666259765625,8.16650390625Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M5.6666259765625,10.16650390625L10.3332959765625,10.16650390625Q10.3825459765625,10.16650390625,10.4308459765625,10.15689690625Q10.4791459765625,10.147288906250001,10.5246459765625,10.12844390625Q10.5701359765625,10.10959790625,10.6110859765625,10.08223890625Q10.6520259765625,10.05487890625,10.6868559765625,10.02005690625Q10.7216759765625,9.98523490625,10.7490359765625,9.94428890625Q10.776395976562501,9.90334290625,10.7952359765625,9.85784590625Q10.814085976562499,9.81234890625,10.823695976562501,9.76404900625Q10.8332959765625,9.71574960625,10.8332959765625,9.66650390625Q10.8332959765625,9.61725820625,10.823695976562501,9.56895880625Q10.814085976562499,9.52065890625,10.7952359765625,9.47516190625Q10.776395976562501,9.42966490625,10.7490359765625,9.38871890625Q10.7216759765625,9.34777290625,10.6868559765625,9.31295090625Q10.6520259765625,9.27812890625,10.6110859765625,9.25076890625Q10.5701359765625,9.22340990625,10.5246459765625,9.20456390625Q10.4791459765625,9.185718906249999,10.4308459765625,9.17611090625Q10.3825459765625,9.16650390625,10.3332959765625,9.16650390625L5.6666259765625,9.16650390625Q5.6173802765625,9.16650390625,5.5690808765625,9.17611090625Q5.5207809765625,9.185718906249999,5.4752839765625,9.20456390625Q5.4297869765625,9.22340990625,5.3888409765625,9.25076890625Q5.3478949765625,9.27812890625,5.3130729765625,9.31295090625Q5.2782509765625,9.34777290625,5.2508909765625,9.38871890625Q5.2235319765625,9.42966490625,5.2046859765625,9.47516190625Q5.1858409765625,9.52065890625,5.1762329765625,9.56895880625Q5.1666259765625,9.61725820625,5.1666259765625,9.66650390625Q5.1666259765625,9.71574960625,5.1762329765625,9.76404900625Q5.1858409765625,9.81234890625,5.2046859765625,9.85784590625Q5.2235319765625,9.90334290625,5.2508909765625,9.94428890625Q5.2782509765625,9.98523490625,5.3130729765625,10.02005690625Q5.3478949765625,10.05487890625,5.3888409765625,10.08223890625Q5.4297869765625,10.10959790625,5.4752839765625,10.12844390625Q5.5207809765625,10.147288906250001,5.5690808765625,10.15689690625Q5.6173802765625,10.16650390625,5.6666259765625,10.16650390625Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M7.49993896484375,7.66650390625L7.49993896484375,11.33317390625Q7.49993896484375,11.37904390625,7.50828596484375,11.42415390625Q7.51619796484375,11.46690390625,7.5313699648437495,11.507653906249999Q7.54654196484375,11.54839390625,7.56851896484375,11.58591390625Q7.59049696484375,11.62342390625,7.61861896484375,11.656583906249999Q7.64674196484375,11.689743906250001,7.68016596484375,11.71754390625Q7.71358996484375,11.74535390625,7.75131196484375,11.76697390625Q7.78903396484375,11.78859390625,7.82992196484375,11.80337390625Q7.87080896484375,11.81816390625,7.91363496484375,11.82566390625Q7.95646066484375,11.83317390625,7.99993896484375,11.83317390625Q8.04918466484375,11.83317390625,8.09748406484375,11.823563906250001Q8.14578396484375,11.81395390625,8.19128096484375,11.79511390625Q8.23677796484375,11.77626390625,8.27772396484375,11.74890390625Q8.31866996484375,11.72154390625,8.35349196484375,11.68672390625Q8.38831396484375,11.65190390625,8.41567396484375,11.61095390625Q8.44303296484375,11.57001390625,8.46187896484375,11.52451390625Q8.480723964843751,11.47901390625,8.49033196484375,11.43071390625Q8.49993896484375,11.382413906250001,8.49993896484375,11.33317390625L8.49993896484375,7.66650390625Q8.49993896484375,7.61725820625,8.49033196484375,7.56895880625Q8.480723964843751,7.52065890625,8.46187896484375,7.47516190625Q8.44303296484375,7.42966490625,8.41567396484375,7.38871890625Q8.38831396484375,7.34777290625,8.35349196484375,7.31295090625Q8.31866996484375,7.27812890625,8.27772396484375,7.25076890625Q8.23677796484375,7.22340990625,8.19128096484375,7.20456390625Q8.14578396484375,7.18571890625,8.09748406484375,7.17611090625Q8.04918466484375,7.16650390625,7.99993896484375,7.16650390625Q7.95069326484375,7.16650390625,7.90239386484375,7.17611090625Q7.85409396484375,7.18571890625,7.80859696484375,7.20456390625Q7.76309996484375,7.22340990625,7.72215396484375,7.25076890625Q7.68120796484375,7.27812890625,7.64638596484375,7.31295090625Q7.61156396484375,7.34777290625,7.58420396484375,7.38871890625Q7.55684496484375,7.42966490625,7.53799896484375,7.47516190625Q7.51915396484375,7.52065890625,7.50954596484375,7.56895880625Q7.49993896484375,7.61725820625,7.49993896484375,7.66650390625Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014480"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014480)"><g><path d="M4.620431088867187,4.469460875Q2.6462310888671876,6.771891875,1.2734680888671874,10.645161875Q0.6654160888671875,12.360771875000001,1.7718480888671875,13.783021875Q2.8483010888671876,15.166721875,4.673231088867187,15.166721875L11.311131088867187,15.166721875Q13.140041088867187,15.166721875,14.217941088867187,13.777651875Q15.325341088867187,12.350631875000001,14.714341088867187,10.631761874999999Q13.335341088867187,6.752011875,11.379691088867187,4.469594875Q11.329021088867188,4.410460875,11.262771088867188,4.369536875Q11.196521088867188,4.328611875,11.120961088867187,4.309773875Q11.045401088867187,4.290934875,10.967691088867188,4.295966875Q10.889981088867188,4.300998875,10.817481088867188,4.329423875Q9.532151088867188,4.833388675,8.002771088867188,4.833388675Q6.469541088867188,4.833388775,5.182311088867188,4.329342875Q5.109851088867187,4.300968875,5.0321910888671875,4.295958875Q4.954531088867188,4.290949875,4.879021088867187,4.309778875Q4.803511088867188,4.3286088750000005,4.737301088867188,4.369496875Q4.671081088867187,4.410383875,4.620431088867187,4.469460875ZM2.5611350888671875,13.168991875Q1.7908470888671875,12.178841875,2.2160190888671876,10.979221875Q3.4479610888671877,7.503301875,5.159181088867188,5.385220875Q6.479671088867187,5.833391875,8.002771088867188,5.833391875Q9.522231088867187,5.833391875,10.840701088867187,5.385410875Q12.534941088867187,7.4861618750000005,13.772141088867187,10.966681874999999Q14.199741088867187,12.169911875,13.427941088867188,13.164591875Q12.650241088867187,14.166721875,11.311131088867187,14.166721875L4.673231088867187,14.166721875Q3.3373110888671875,14.166721875,2.5611350888671875,13.168991875Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6,9.83349609375L10,9.83349609375Q10.04925,9.83349609375,10.09755,9.82388909375Q10.14584,9.814281093750001,10.19134,9.79543609375Q10.23684,9.77659009375,10.27778,9.74923109375Q10.31873,9.72187109375,10.35355,9.68704909375Q10.38837,9.65222709375,10.41573,9.61128109375Q10.44309,9.57033509375,10.46194,9.52483809375Q10.48078,9.47934109375,10.49039,9.43104119375Q10.5,9.38274179375,10.5,9.33349609375Q10.5,9.28425039375,10.49039,9.23595099375Q10.48078,9.18765109375,10.46194,9.14215409375Q10.44309,9.09665709375,10.41573,9.05571109375Q10.38837,9.01476509375,10.35355,8.97994309375Q10.31873,8.94512109375,10.27778,8.91776109375Q10.23684,8.89040209375,10.19134,8.87155609375Q10.14584,8.852711093749999,10.09755,8.84310309375Q10.04925,8.83349609375,10,8.83349609375L6,8.83349609375Q5.9507543,8.83349609375,5.9024549,8.84310309375Q5.854155,8.852711093749999,5.808658,8.87155609375Q5.763161,8.89040209375,5.722215,8.91776109375Q5.681269,8.94512109375,5.646447,8.97994309375Q5.611625,9.01476509375,5.584265,9.05571109375Q5.556906,9.09665709375,5.53806,9.14215409375Q5.519215,9.18765109375,5.509607,9.23595099375Q5.5,9.28425039375,5.5,9.33349609375Q5.5,9.38274179375,5.509607,9.43104119375Q5.519215,9.47934109375,5.53806,9.52483809375Q5.556906,9.57033509375,5.584265,9.61128109375Q5.611625,9.65222709375,5.646447,9.68704909375Q5.681269,9.72187109375,5.722215,9.74923109375Q5.763161,9.77659009375,5.808658,9.79543609375Q5.854155,9.814281093750001,5.9024549,9.82388909375Q5.9507543,9.83349609375,6,9.83349609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6,11.83349609375L10,11.83349609375Q10.04925,11.83349609375,10.09755,11.82388909375Q10.14584,11.814281093750001,10.19134,11.79543609375Q10.23684,11.77659009375,10.27778,11.74923109375Q10.31873,11.72187109375,10.35355,11.68704909375Q10.38837,11.65222709375,10.41573,11.61128109375Q10.44309,11.57033509375,10.46194,11.52483809375Q10.48078,11.47934109375,10.49039,11.43104119375Q10.5,11.38274179375,10.5,11.33349609375Q10.5,11.28425039375,10.49039,11.23595099375Q10.48078,11.18765109375,10.46194,11.14215409375Q10.44309,11.09665709375,10.41573,11.05571109375Q10.38837,11.01476509375,10.35355,10.97994309375Q10.31873,10.94512109375,10.27778,10.91776109375Q10.23684,10.89040209375,10.19134,10.87155609375Q10.14584,10.852711093749999,10.09755,10.84310309375Q10.04925,10.83349609375,10,10.83349609375L6,10.83349609375Q5.9507543,10.83349609375,5.9024549,10.84310309375Q5.854155,10.852711093749999,5.808658,10.87155609375Q5.763161,10.89040209375,5.722215,10.91776109375Q5.681269,10.94512109375,5.646447,10.97994309375Q5.611625,11.01476509375,5.584265,11.05571109375Q5.556906,11.09665709375,5.53806,11.14215409375Q5.519215,11.18765109375,5.509607,11.23595099375Q5.5,11.28425039375,5.5,11.33349609375Q5.5,11.38274179375,5.509607,11.43104119375Q5.519215,11.47934109375,5.53806,11.52483809375Q5.556906,11.57033509375,5.584265,11.61128109375Q5.611625,11.65222709375,5.646447,11.68704909375Q5.681269,11.72187109375,5.722215,11.74923109375Q5.763161,11.77659009375,5.808658,11.79543609375Q5.854155,11.814281093750001,5.9024549,11.82388909375Q5.9507543,11.83349609375,6,11.83349609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M7.5027618408203125,9.33349609375L7.5027618408203125,12.66682609375Q7.5027618408203125,12.71607609375,7.512368840820312,12.76437609375Q7.5219768408203125,12.81267609375,7.540821840820312,12.85816609375Q7.559667840820312,12.903666093750001,7.587026840820313,12.94461609375Q7.614386840820313,12.98555609375,7.649208840820313,13.02038609375Q7.684030840820313,13.05520609375,7.724976840820313,13.08256609375Q7.765922840820313,13.10992609375,7.811419840820313,13.12876609375Q7.856916840820313,13.147616093749999,7.905216740820313,13.15722609375Q7.953516140820312,13.16682609375,8.002761840820312,13.16682609375Q8.052007540820313,13.16682609375,8.100306940820312,13.15722609375Q8.148606840820312,13.147616093749999,8.194103840820313,13.12876609375Q8.239600840820312,13.10992609375,8.280546840820312,13.08256609375Q8.321492840820312,13.05520609375,8.356314840820312,13.02038609375Q8.391136840820312,12.98555609375,8.418496840820312,12.94461609375Q8.445855840820313,12.903666093750001,8.464701840820313,12.85816609375Q8.483546840820313,12.81267609375,8.493154840820312,12.76437609375Q8.502761840820312,12.71607609375,8.502761840820312,12.66682609375L8.502761840820312,9.33349609375Q8.502761840820312,9.28425039375,8.493154840820312,9.23595099375Q8.483546840820313,9.18765109375,8.464701840820313,9.14215409375Q8.445855840820313,9.09665709375,8.418496840820312,9.05571109375Q8.391136840820312,9.01476509375,8.356314840820312,8.97994309375Q8.321492840820312,8.94512109375,8.280546840820312,8.91776109375Q8.239600840820312,8.89040209375,8.194103840820313,8.87155609375Q8.148606840820312,8.852711093749999,8.100306940820312,8.84310309375Q8.052007540820313,8.83349609375,8.002761840820312,8.83349609375Q7.953516140820312,8.83349609375,7.905216740820313,8.84310309375Q7.856916840820313,8.852711093749999,7.811419840820313,8.87155609375Q7.765922840820313,8.89040209375,7.724976840820313,8.91776109375Q7.684030840820313,8.94512109375,7.649208840820313,8.97994309375Q7.614386840820313,9.01476509375,7.587026840820313,9.05571109375Q7.559667840820312,9.09665709375,7.540821840820312,9.14215409375Q7.5219768408203125,9.18765109375,7.512368840820312,9.23595099375Q7.5027618408203125,9.28425039375,7.5027618408203125,9.33349609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6.353613,6.9800020937500005L6.353553,6.97994309375Q6.283227,6.90961609375,6.191342,6.87155609375Q6.0994562,6.83349609375,6,6.83349609375Q5.9005438,6.83349609375,5.808658,6.87155609375Q5.716773,6.90961609375,5.646447,6.97994309375Q5.57612,7.05026909375,5.53806,7.14215409375Q5.5,7.23403989375,5.5,7.33349609375Q5.5,7.43295229375,5.53806,7.52483809375Q5.57612,7.61672309375,5.646447,7.68704909375L7.64645,9.68704609375Q7.71677,9.75737609375,7.80866,9.79543609375Q7.9005399999999995,9.83349609375,8,9.83349609375Q8.09946,9.83349609375,8.19134,9.79543609375Q8.28323,9.75737609375,8.35355,9.68704609375L10.35337,7.68723709375L10.35355,7.68704909375Q10.42388,7.61672309375,10.46194,7.52483809375Q10.5,7.43295229375,10.5,7.33349609375Q10.5,7.23403989375,10.46194,7.14215409375Q10.42388,7.05026909375,10.35355,6.97994309375Q10.28323,6.90961609375,10.19134,6.87155609375Q10.09946,6.83349609375,10,6.83349609375Q9.90054,6.83349609375,9.80866,6.87155609375Q9.71677,6.90961609375,9.64645,6.97994309375L9.64626,6.98013009375L8,8.62638609375L6.353613,6.9800020937500005Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M4.726351752929688,1.46530309375Q3.1666717529296875,2.18515209375,3.1666717529296875,3.33349609375Q3.1666717529296875,4.48183609375,4.726341752929687,5.20168609375Q6.095261752929687,5.83349609375,8.000001752929688,5.83349609375Q9.904741752929688,5.83349609375,11.273661752929687,5.20168609375Q12.833341752929687,4.48183609375,12.833341752929687,3.33349609375Q12.833341752929687,2.18515309375,11.273661752929687,1.46530209375Q9.904751752929688,0.83349609375,8.000001752929688,0.83349609375Q6.095261752929687,0.83349609375,4.726351752929688,1.46530309375ZM5.145401752929688,4.29372609375Q4.1666717529296875,3.84200609375,4.1666717529296875,3.33349609375Q4.1666717529296875,2.8249860937499998,5.145401752929688,2.37326609375Q6.314901752929687,1.83349609375,8.000001752929688,1.83349609375Q9.685111752929688,1.83349609375,10.854601752929687,2.37326609375Q11.833341752929687,2.8249860937499998,11.833341752929687,3.33349609375Q11.833341752929687,3.84200609375,10.854601752929687,4.29372609375Q9.685111752929688,4.83349609375,8.000001752929688,4.83349609375Q6.314901752929687,4.83349609375,5.145401752929688,4.29372609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014488"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014488)"><g><path d="M2.932413505859375,2.93256609375Q0.833343505859375,5.03162609375,0.833343505859375,8.00016609375Q0.833343505859375,10.96869609375,2.932413505859375,13.06779609375Q5.031473505859375,15.16679609375,8.000013505859375,15.16679609375Q10.968543505859374,15.16679609375,13.067643505859374,13.06779609375Q15.166643505859374,10.96869609375,15.166643505859374,8.00016609375Q15.166643505859374,5.03162609375,13.067643505859374,2.93256609375Q10.968543505859374,0.83349609375,8.000013505859375,0.83349609375Q5.031483505859375,0.83349609375,2.932413505859375,2.93256609375ZM3.639513505859375,12.36069609375Q1.833343505859375,10.55447609375,1.833343505859375,8.00016609375Q1.833342505859375,5.44584609375,3.639513505859375,3.63966609375Q5.445693505859375,1.83349609375,8.000013505859375,1.83349609375Q10.554323505859376,1.83349609375,12.360543505859376,3.63966609375Q14.166643505859374,5.44584609375,14.166643505859374,8.00016609375Q14.166643505859374,10.55448609375,12.360543505859376,12.36069609375Q10.554323505859376,14.16679609375,8.000013505859375,14.16679609375Q5.445693505859375,14.16679609375,3.639513505859375,12.36069609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6,7.83349609375L10,7.83349609375Q10.04925,7.83349609375,10.09755,7.82388909375Q10.14584,7.81428109375,10.19134,7.79543609375Q10.23684,7.77659009375,10.27778,7.74923109375Q10.31873,7.72187109375,10.35355,7.68704909375Q10.38837,7.65222709375,10.41573,7.61128109375Q10.44309,7.57033509375,10.46194,7.52483809375Q10.48078,7.47934109375,10.49039,7.43104119375Q10.5,7.38274179375,10.5,7.33349609375Q10.5,7.28425039375,10.49039,7.23595099375Q10.48078,7.18765109375,10.46194,7.14215409375Q10.44309,7.09665709375,10.41573,7.05571109375Q10.38837,7.01476509375,10.35355,6.97994309375Q10.31873,6.94512109375,10.27778,6.91776109375Q10.23684,6.89040209375,10.19134,6.87155609375Q10.14584,6.85271109375,10.09755,6.84310309375Q10.04925,6.83349609375,10,6.83349609375L6,6.83349609375Q5.9507543,6.83349609375,5.9024549,6.84310309375Q5.854155,6.85271109375,5.808658,6.87155609375Q5.763161,6.89040209375,5.722215,6.91776109375Q5.681269,6.94512109375,5.646447,6.97994309375Q5.611625,7.01476509375,5.584265,7.05571109375Q5.556906,7.09665709375,5.53806,7.14215409375Q5.519215,7.18765109375,5.509607,7.23595099375Q5.5,7.28425039375,5.5,7.33349609375Q5.5,7.38274179375,5.509607,7.43104119375Q5.519215,7.47934109375,5.53806,7.52483809375Q5.556906,7.57033509375,5.584265,7.61128109375Q5.611625,7.65222709375,5.646447,7.68704909375Q5.681269,7.72187109375,5.722215,7.74923109375Q5.763161,7.77659009375,5.808658,7.79543609375Q5.854155,7.81428109375,5.9024549,7.82388909375Q5.9507543,7.83349609375,6,7.83349609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6,9.83349609375L10,9.83349609375Q10.04925,9.83349609375,10.09755,9.82388909375Q10.14584,9.814281093750001,10.19134,9.79543609375Q10.23684,9.77659009375,10.27778,9.74923109375Q10.31873,9.72187109375,10.35355,9.68704909375Q10.38837,9.65222709375,10.41573,9.61128109375Q10.44309,9.57033509375,10.46194,9.52483809375Q10.48078,9.47934109375,10.49039,9.43104119375Q10.5,9.38274179375,10.5,9.33349609375Q10.5,9.28425039375,10.49039,9.23595099375Q10.48078,9.18765109375,10.46194,9.14215409375Q10.44309,9.09665709375,10.41573,9.05571109375Q10.38837,9.01476509375,10.35355,8.97994309375Q10.31873,8.94512109375,10.27778,8.91776109375Q10.23684,8.89040209375,10.19134,8.87155609375Q10.14584,8.852711093749999,10.09755,8.84310309375Q10.04925,8.83349609375,10,8.83349609375L6,8.83349609375Q5.9507543,8.83349609375,5.9024549,8.84310309375Q5.854155,8.852711093749999,5.808658,8.87155609375Q5.763161,8.89040209375,5.722215,8.91776109375Q5.681269,8.94512109375,5.646447,8.97994309375Q5.611625,9.01476509375,5.584265,9.05571109375Q5.556906,9.09665709375,5.53806,9.14215409375Q5.519215,9.18765109375,5.509607,9.23595099375Q5.5,9.28425039375,5.5,9.33349609375Q5.5,9.38274179375,5.509607,9.43104119375Q5.519215,9.47934109375,5.53806,9.52483809375Q5.556906,9.57033509375,5.584265,9.61128109375Q5.611625,9.65222709375,5.646447,9.68704909375Q5.681269,9.72187109375,5.722215,9.74923109375Q5.763161,9.77659009375,5.808658,9.79543609375Q5.854155,9.814281093750001,5.9024549,9.82388909375Q5.9507543,9.83349609375,6,9.83349609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M7.502777099609375,7.33349609375L7.502777099609375,11.33349609375Q7.502777099609375,11.38274609375,7.512384099609375,11.43104609375Q7.521992099609375,11.47933609375,7.540837099609375,11.52483609375Q7.559683099609375,11.57033609375,7.587042099609375,11.61127609375Q7.614402099609375,11.65222609375,7.649224099609375,11.68704609375Q7.684046099609375,11.72186609375,7.724992099609375,11.74922609375Q7.765938099609375,11.77658609375,7.811435099609375,11.79543609375Q7.856932099609375,11.81427609375,7.905231999609375,11.82388609375Q7.953531399609375,11.83349609375,8.002777099609375,11.83349609375Q8.052022799609375,11.83349609375,8.100322199609375,11.82388609375Q8.148622099609375,11.81427609375,8.194119099609376,11.79543609375Q8.239616099609375,11.77658609375,8.280562099609375,11.74922609375Q8.321508099609375,11.72186609375,8.356330099609375,11.68704609375Q8.391152099609375,11.65222609375,8.418512099609375,11.61127609375Q8.445871099609375,11.57033609375,8.464717099609375,11.52483609375Q8.483562099609376,11.47933609375,8.493170099609374,11.43104609375Q8.502777099609375,11.38274609375,8.502777099609375,11.33349609375L8.502777099609375,7.33349609375Q8.502777099609375,7.28425039375,8.493170099609374,7.23595099375Q8.483562099609376,7.18765109375,8.464717099609375,7.14215409375Q8.445871099609375,7.09665709375,8.418512099609375,7.05571109375Q8.391152099609375,7.01476509375,8.356330099609375,6.97994309375Q8.321508099609375,6.94512109375,8.280562099609375,6.91776109375Q8.239616099609375,6.89040209375,8.194119099609376,6.87155609375Q8.148622099609375,6.85271109375,8.100322199609375,6.84310309375Q8.052022799609375,6.83349609375,8.002777099609375,6.83349609375Q7.953531399609375,6.83349609375,7.905231999609375,6.84310309375Q7.856932099609375,6.85271109375,7.811435099609375,6.87155609375Q7.765938099609375,6.89040209375,7.724992099609375,6.91776109375Q7.684046099609375,6.94512109375,7.649224099609375,6.97994309375Q7.614402099609375,7.01476509375,7.587042099609375,7.05571109375Q7.559683099609375,7.09665709375,7.540837099609375,7.14215409375Q7.521992099609375,7.18765109375,7.512384099609375,7.23595099375Q7.502777099609375,7.28425039375,7.502777099609375,7.33349609375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M6.353613,4.6465060000000005L6.353553,4.646447Q6.283227,4.57612,6.191342,4.53806Q6.0994562,4.5,6,4.5Q5.9005438,4.5,5.808658,4.53806Q5.716773,4.57612,5.646447,4.646447Q5.57612,4.716773,5.53806,4.808658Q5.5,4.9005438,5.5,5Q5.5,5.0994562,5.53806,5.191342Q5.57612,5.283227,5.646447,5.353553L7.64645,7.35355Q7.71677,7.4238800000000005,7.80866,7.46194Q7.9005399999999995,7.5,8,7.5Q8.09946,7.5,8.19134,7.46194Q8.28323,7.4238800000000005,8.35355,7.35355L10.35337,5.353741L10.35355,5.353553Q10.42388,5.283227,10.46194,5.191342Q10.5,5.0994562,10.5,5Q10.5,4.9005438,10.46194,4.808658Q10.42388,4.716773,10.35355,4.646447Q10.28323,4.57612,10.19134,4.53806Q10.09946,4.5,10,4.5Q9.90054,4.5,9.80866,4.53806Q9.71677,4.57612,9.64645,4.646447L9.64626,4.646634L8,6.29289L6.353613,4.6465060000000005Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014495"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014495)"><g><path d="M14.000156494140626,9.166673505859375L13.000196494140624,9.166353505859375L13.000026494140625,9.166353505859375Q12.954236494140625,9.166353505859375,12.909206494140625,9.174673505859374Q12.866456494140625,9.182563505859374,12.825706494140626,9.197723505859376Q12.784956494140625,9.212883505859375,12.747426494140624,9.234853505859375Q12.709906494140625,9.256813505859375,12.676746494140625,9.284923505859375Q12.643576494140625,9.313043505859376,12.615756494140625,9.346453505859376Q12.587936494140624,9.379873505859376,12.566306494140626,9.417583505859376Q12.544676494140624,9.455303505859375,12.529876494140625,9.496183505859374Q12.515076494140626,9.537063505859376,12.507566494140626,9.579893505859374Q12.500046494140625,9.622713505859375,12.500026494140625,9.666193505859376L12.500026494140625,9.666353505859375Q12.500026494140625,9.712143505859375,12.508346494140625,9.757173505859374Q12.516246494140624,9.799933505859375,12.531406494140626,9.840683505859374Q12.546566494140624,9.881433505859375,12.568526494140624,9.918953505859374Q12.590496494140625,9.956473505859375,12.618606494140625,9.989643505859375Q12.646716494140625,10.022803505859375,12.680136494140624,10.050623505859374Q12.713546494140624,10.078443505859376,12.751266494140625,10.100073505859374Q12.788976494140625,10.121703505859376,12.829866494140624,10.136503505859375Q12.870746494140626,10.151303505859374,12.913566494140625,10.158823505859374Q12.956386494140625,10.166333505859374,12.999866494140624,10.166353505859375L13.000026494140625,10.166353505859375L13.999826494140626,10.166673505859375Q14.483246494140625,10.166673505859375,14.824956494140626,9.824973505859376Q15.166656494140625,9.483263505859375,15.166656494140625,9.000003505859375L15.166656494140625,3.000010505859375Q15.166656494140625,2.516759505859375,14.824956494140626,2.175054505859375Q14.483246494140625,1.833343505859375,13.999986494140625,1.833343505859375L5.333323494140625,1.833343505859375Q4.850066494140625,1.833343505859375,4.508359494140625,2.175053505859375Q4.166656494140625,2.516760505859375,4.166656494140625,3.000010505859375L4.166656494140625,5.000333505859375Q4.166656494140625,5.049583505859375,4.176263494140625,5.097883505859375Q4.185871494140625,5.146183505859375,4.204716494140625,5.1916735058593755Q4.223562494140625,5.237173505859375,4.250921494140625,5.278123505859375Q4.278281494140625,5.319063505859376,4.313103494140625,5.353893505859375Q4.347925494140625,5.388713505859375,4.388871494140625,5.416073505859375Q4.429817494140625,5.443433505859375,4.475314494140625,5.462273505859375Q4.520811494140625,5.481123505859375,4.569111394140625,5.490723505859375Q4.617410794140625,5.500333505859375,4.666656494140625,5.500333505859375Q4.715902194140625,5.500333505859375,4.764201594140625,5.490723505859375Q4.812501494140625,5.481123505859375,4.857998494140625,5.462273505859375Q4.903495494140625,5.443433505859375,4.944441494140625,5.416073505859375Q4.985387494140625,5.388713505859375,5.020209494140625,5.353893505859375Q5.055031494140625,5.319063505859376,5.082391494140625,5.278123505859375Q5.109750494140625,5.237173505859375,5.128596494140625,5.1916735058593755Q5.147441494140625,5.146183505859375,5.157049494140625,5.097883505859375Q5.166656494140625,5.049583505859375,5.166656494140625,5.000333505859375L5.166656494140625,3.000010505859375Q5.166656494140625,2.833343505859375,5.333323494140625,2.833343505859375L13.999986494140625,2.833343505859375Q14.166656494140625,2.833343505859375,14.166656494140625,3.000010505859375L14.166656494140625,9.000003505859375Q14.166656494140625,9.166673505859375,14.000156494140626,9.166673505859375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M0.833343505859375,13.166673505859375L0.833343505859375,6.833343505859375Q0.833343505859375,6.419130005859375,1.126236505859375,6.126236505859375Q1.419129905859375,5.833343505859375,1.833343505859375,5.833343505859375L10.833343505859375,5.833343505859375Q11.247553505859376,5.833343505859375,11.540443505859376,6.126236505859375Q11.833343505859375,6.419129805859375,11.833343505859375,6.833343505859375L11.833343505859375,13.166673505859375Q11.833343505859375,13.580893505859375,11.540443505859376,13.873783505859375Q11.247553505859376,14.166673505859375,10.833343505859375,14.166673505859375L1.833343505859375,14.166673505859375Q1.4191302058593749,14.166673505859375,1.126236505859375,13.873783505859375Q0.833343505859375,13.580893505859375,0.833343505859375,13.166673505859375ZM1.833343505859375,13.166673505859375L1.833343505859375,13.166673505859375L10.833343505859375,13.166673505859375L10.833343505859375,13.166673505859375L10.833343505859375,6.833343505859375L10.833343505859375,6.833343505859375L1.833343505859375,6.833343505859375L1.833343505859375,6.833343505859375L1.833343505859375,13.166673505859375Z" fill="#232323" fill-opacity="1"/></g><g><path d="M1.333343505859375,8.8330078125L11.333343505859375,8.8330078125Q11.382543505859376,8.8330078125,11.430843505859375,8.8234008125Q11.479143505859374,8.813792812500001,11.524643505859375,8.7949478125Q11.570143505859376,8.7761018125,11.611143505859374,8.7487428125Q11.652043505859375,8.7213828125,11.686943505859375,8.6865608125Q11.721743505859376,8.6517388125,11.749043505859374,8.6107928125Q11.776443505859374,8.5698468125,11.795243505859375,8.5243498125Q11.814143505859375,8.4788528125,11.823743505859374,8.4305529125Q11.833343505859375,8.3822535125,11.833343505859375,8.3330078125Q11.833343505859375,8.2837621125,11.823743505859374,8.2354627125Q11.814143505859375,8.1871628125,11.795243505859375,8.1416658125Q11.776443505859374,8.0961688125,11.749043505859374,8.0552228125Q11.721743505859376,8.0142768125,11.686943505859375,7.9794548125Q11.652043505859375,7.9446328125,11.611143505859374,7.9172728125Q11.570143505859376,7.8899138125,11.524643505859375,7.8710678125Q11.479143505859374,7.8522228125,11.430843505859375,7.8426148125Q11.382543505859376,7.8330078125,11.333343505859375,7.8330078125L1.333343505859375,7.8330078125Q1.284097805859375,7.8330078125,1.235798405859375,7.8426148125Q1.187498505859375,7.8522228125,1.1420015058593749,7.8710678125Q1.096504505859375,7.8899138125,1.055558505859375,7.9172728125Q1.014612505859375,7.9446328125,0.979790505859375,7.9794548125Q0.944968505859375,8.0142768125,0.917608505859375,8.0552228125Q0.890249505859375,8.0961688125,0.871403505859375,8.1416658125Q0.852558505859375,8.1871628125,0.8429505058593749,8.2354627125Q0.833343505859375,8.2837621125,0.833343505859375,8.3330078125Q0.833343505859375,8.3822535125,0.8429505058593749,8.4305529125Q0.852558505859375,8.4788528125,0.871403505859375,8.5243498125Q0.890249505859375,8.5698468125,0.917608505859375,8.6107928125Q0.944968505859375,8.6517388125,0.979790505859375,8.6865608125Q1.014612505859375,8.7213828125,1.055558505859375,8.7487428125Q1.096504505859375,8.7761018125,1.1420015058593749,8.7949478125Q1.187498505859375,8.813792812500001,1.235798405859375,8.8234008125Q1.284097805859375,8.8330078125,1.333343505859375,8.8330078125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M10.833343505859375,7.6666717529296875L10.833343505859375,11.666671752929688Q10.833343505859375,11.715921752929688,10.842950505859376,11.764221752929688Q10.852558505859374,11.812511752929687,10.871403505859375,11.858011752929688Q10.890249505859375,11.903511752929688,10.917608505859375,11.944451752929687Q10.944968505859375,11.985401752929688,10.979790505859375,12.020221752929688Q11.014612505859375,12.055041752929688,11.055558505859375,12.082401752929687Q11.096504505859375,12.109761752929687,11.142001505859374,12.128611752929688Q11.187498505859375,12.147451752929687,11.235798405859375,12.157061752929687Q11.284097805859375,12.166671752929688,11.333343505859375,12.166671752929688Q11.382589205859375,12.166671752929688,11.430888605859375,12.157061752929687Q11.479188505859375,12.147451752929687,11.524685505859376,12.128611752929688Q11.570182505859375,12.109761752929687,11.611128505859375,12.082401752929687Q11.652074505859375,12.055041752929688,11.686896505859375,12.020221752929688Q11.721718505859375,11.985401752929688,11.749078505859375,11.944451752929687Q11.776437505859375,11.903511752929688,11.795283505859375,11.858011752929688Q11.814128505859376,11.812511752929687,11.823736505859374,11.764221752929688Q11.833343505859375,11.715921752929688,11.833343505859375,11.666671752929688L11.833343505859375,7.6666717529296875Q11.833343505859375,7.617426052929687,11.823736505859374,7.569126652929688Q11.814128505859376,7.520826752929688,11.795283505859375,7.475329752929688Q11.776437505859375,7.429832752929688,11.749078505859375,7.388886752929688Q11.721718505859375,7.347940752929688,11.686896505859375,7.313118752929688Q11.652074505859375,7.278296752929688,11.611128505859375,7.250936752929688Q11.570182505859375,7.223577752929687,11.524685505859376,7.204731752929687Q11.479188505859375,7.1858867529296875,11.430888605859375,7.176278752929687Q11.382589205859375,7.1666717529296875,11.333343505859375,7.1666717529296875Q11.284097805859375,7.1666717529296875,11.235798405859375,7.176278752929687Q11.187498505859375,7.1858867529296875,11.142001505859374,7.204731752929687Q11.096504505859375,7.223577752929687,11.055558505859375,7.250936752929688Q11.014612505859375,7.278296752929688,10.979790505859375,7.313118752929688Q10.944968505859375,7.347940752929688,10.917608505859375,7.388886752929688Q10.890249505859375,7.429832752929688,10.871403505859375,7.475329752929688Q10.852558505859374,7.520826752929688,10.842950505859376,7.569126652929688Q10.833343505859375,7.617426052929687,10.833343505859375,7.6666717529296875Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M0.833343505859375,7.6666717529296875L0.833343505859375,11.666671752929688Q0.833343505859375,11.715921752929688,0.8429505058593749,11.764221752929688Q0.852558505859375,11.812511752929687,0.871403505859375,11.858011752929688Q0.890249505859375,11.903511752929688,0.917608505859375,11.944451752929687Q0.944968505859375,11.985401752929688,0.979790505859375,12.020221752929688Q1.014612505859375,12.055041752929688,1.055558505859375,12.082401752929687Q1.096504505859375,12.109761752929687,1.1420015058593749,12.128611752929688Q1.187498505859375,12.147451752929687,1.235798405859375,12.157061752929687Q1.284097805859375,12.166671752929688,1.333343505859375,12.166671752929688Q1.382589205859375,12.166671752929688,1.430888605859375,12.157061752929687Q1.479188505859375,12.147451752929687,1.5246855058593751,12.128611752929688Q1.570182505859375,12.109761752929687,1.611128505859375,12.082401752929687Q1.652074505859375,12.055041752929688,1.686896505859375,12.020221752929688Q1.721718505859375,11.985401752929688,1.749078505859375,11.944451752929687Q1.7764375058593749,11.903511752929688,1.795283505859375,11.858011752929688Q1.814128505859375,11.812511752929687,1.823736505859375,11.764221752929688Q1.833343505859375,11.715921752929688,1.833343505859375,11.666671752929688L1.833343505859375,7.6666717529296875Q1.833343505859375,7.617426052929687,1.823736505859375,7.569126652929688Q1.814128505859375,7.520826752929688,1.795283505859375,7.475329752929688Q1.7764375058593749,7.429832752929688,1.749078505859375,7.388886752929688Q1.721718505859375,7.347940752929688,1.686896505859375,7.313118752929688Q1.652074505859375,7.278296752929688,1.611128505859375,7.250936752929688Q1.570182505859375,7.223577752929687,1.5246855058593751,7.204731752929687Q1.479188505859375,7.1858867529296875,1.430888605859375,7.176278752929687Q1.382589205859375,7.1666717529296875,1.333343505859375,7.1666717529296875Q1.284097805859375,7.1666717529296875,1.235798405859375,7.176278752929687Q1.187498505859375,7.1858867529296875,1.1420015058593749,7.204731752929687Q1.096504505859375,7.223577752929687,1.055558505859375,7.250936752929688Q1.014612505859375,7.278296752929688,0.979790505859375,7.313118752929688Q0.944968505859375,7.347940752929688,0.917608505859375,7.388886752929688Q0.890249505859375,7.429832752929688,0.871403505859375,7.475329752929688Q0.852558505859375,7.520826752929688,0.8429505058593749,7.569126652929688Q0.833343505859375,7.617426052929687,0.833343505859375,7.6666717529296875Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M3.666656494140625,11.833343505859375L6.333326494140625,11.833343505859375Q6.382566494140625,11.833343505859375,6.430866494140625,11.823736505859374Q6.479166494140625,11.814128505859376,6.524666494140625,11.795283505859375Q6.570166494140625,11.776437505859375,6.611106494140625,11.749078505859375Q6.652056494140625,11.721718505859375,6.686876494140625,11.686896505859375Q6.721696494140625,11.652074505859375,6.749056494140625,11.611128505859375Q6.776416494140625,11.570182505859375,6.795266494140625,11.524685505859376Q6.814106494140625,11.479188505859375,6.8237164941406245,11.430888605859375Q6.833326494140625,11.382589205859375,6.833326494140625,11.333343505859375Q6.833326494140625,11.284097805859375,6.8237164941406245,11.235798405859375Q6.814106494140625,11.187498505859375,6.795266494140625,11.142001505859374Q6.776416494140625,11.096504505859375,6.749056494140625,11.055558505859375Q6.721696494140625,11.014612505859375,6.686876494140625,10.979790505859375Q6.652056494140625,10.944968505859375,6.611106494140625,10.917608505859375Q6.570166494140625,10.890249505859375,6.524666494140625,10.871403505859375Q6.479166494140625,10.852558505859374,6.430866494140625,10.842950505859376Q6.382566494140625,10.833343505859375,6.333326494140625,10.833343505859375L3.666656494140625,10.833343505859375Q3.617410794140625,10.833343505859375,3.569111394140625,10.842950505859376Q3.520811494140625,10.852558505859374,3.475314494140625,10.871403505859375Q3.429817494140625,10.890249505859375,3.388871494140625,10.917608505859375Q3.347925494140625,10.944968505859375,3.313103494140625,10.979790505859375Q3.278281494140625,11.014612505859375,3.250921494140625,11.055558505859375Q3.223562494140625,11.096504505859375,3.2047164941406248,11.142001505859374Q3.185871494140625,11.187498505859375,3.176263494140625,11.235798405859375Q3.166656494140625,11.284097805859375,3.166656494140625,11.333343505859375Q3.166656494140625,11.382589205859375,3.176263494140625,11.430888605859375Q3.185871494140625,11.479188505859375,3.2047164941406248,11.524685505859376Q3.223562494140625,11.570182505859375,3.250921494140625,11.611128505859375Q3.278281494140625,11.652074505859375,3.313103494140625,11.686896505859375Q3.347925494140625,11.721718505859375,3.388871494140625,11.749078505859375Q3.429817494140625,11.776437505859375,3.475314494140625,11.795283505859375Q3.520811494140625,11.814128505859376,3.569111394140625,11.823736505859374Q3.617410794140625,11.833343505859375,3.666656494140625,11.833343505859375Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_962_014504"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_962_014504)"><g><path d="M0.833343505859375,3.3333387529296874L0.833343505859375,12.666671752929688Q0.833343505859375,13.149971752929687,1.175054505859375,13.491671752929687Q1.516760505859375,13.833371752929688,2.000010505859375,13.833371752929688L14.000043505859376,13.833371752929688Q14.483243505859376,13.833371752929688,14.824943505859375,13.491671752929687Q15.166643505859374,13.149971752929687,15.166643505859374,12.666671752929688L15.166643505859374,3.3333387529296874Q15.166643505859374,2.8500897529296876,14.824943505859375,2.5083817529296875Q14.483243505859376,2.1666717529296875,14.000043505859376,2.1666717529296875L2.000010505859375,2.1666717529296875Q1.516760505859375,2.1666717529296875,1.175052505859375,2.5083807529296873Q0.833343505859375,2.8500887529296874,0.833343505859375,3.3333387529296874ZM2.000010505859375,12.833371752929688Q1.833343505859375,12.833371752929688,1.833343505859375,12.666671752929688L1.833343505859375,3.3333387529296874Q1.833343505859375,3.2643027529296873,1.882158505859375,3.2154867529296878Q1.930974505859375,3.1666717529296875,2.000010505859375,3.1666717529296875L14.000043505859376,3.1666717529296875Q14.166643505859374,3.1666717529296875,14.166643505859374,3.3333387529296874L14.166643505859374,12.666671752929688Q14.166643505859374,12.833371752929688,14.000043505859376,12.833371752929688L2.000010505859375,12.833371752929688Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M1.333343505859375,6.8333282470703125L14.666643505859374,6.8333282470703125Q14.715943505859375,6.8333282470703125,14.764243505859374,6.823721247070313Q14.812543505859376,6.8141132470703125,14.858043505859374,6.795268247070313Q14.903543505859375,6.776422247070313,14.944443505859375,6.749063247070312Q14.985443505859376,6.721703247070312,15.020243505859375,6.686881247070312Q15.055043505859375,6.652059247070312,15.082443505859375,6.611113247070312Q15.109743505859376,6.570167247070312,15.128643505859374,6.524670247070312Q15.147443505859375,6.479173247070312,15.157043505859376,6.430873347070312Q15.166643505859374,6.382573947070313,15.166643505859374,6.3333282470703125Q15.166643505859374,6.284082547070312,15.157043505859376,6.235783147070313Q15.147443505859375,6.187483247070313,15.128643505859374,6.141986247070313Q15.109743505859376,6.096489247070313,15.082443505859375,6.055543247070313Q15.055043505859375,6.014597247070313,15.020243505859375,5.979775247070313Q14.985443505859376,5.944953247070313,14.944443505859375,5.917593247070313Q14.903543505859375,5.890234247070312,14.858043505859374,5.871388247070312Q14.812543505859376,5.8525432470703125,14.764243505859374,5.842935247070312Q14.715943505859375,5.8333282470703125,14.666643505859374,5.8333282470703125L1.333343505859375,5.8333282470703125Q1.284097805859375,5.8333282470703125,1.235798405859375,5.842935247070312Q1.187498505859375,5.8525432470703125,1.1420015058593749,5.871388247070312Q1.096504505859375,5.890234247070312,1.055558505859375,5.917593247070313Q1.014612505859375,5.944953247070313,0.979790505859375,5.979775247070313Q0.944968505859375,6.014597247070313,0.917608505859375,6.055543247070313Q0.890249505859375,6.096489247070313,0.871403505859375,6.141986247070313Q0.852558505859375,6.187483247070313,0.8429505058593749,6.235783147070313Q0.833343505859375,6.284082547070312,0.833343505859375,6.3333282470703125Q0.833343505859375,6.382573947070313,0.8429505058593749,6.430873347070312Q0.852558505859375,6.479173247070312,0.871403505859375,6.524670247070312Q0.890249505859375,6.570167247070312,0.917608505859375,6.611113247070312Q0.944968505859375,6.652059247070312,0.979790505859375,6.686881247070312Q1.014612505859375,6.721703247070312,1.055558505859375,6.749063247070312Q1.096504505859375,6.776422247070313,1.1420015058593749,6.795268247070313Q1.187498505859375,6.8141132470703125,1.235798405859375,6.823721247070313Q1.284097805859375,6.8333282470703125,1.333343505859375,6.8333282470703125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M9,11.166656494140625L12,11.166656494140625Q12.04925,11.166656494140625,12.09754,11.157049494140624Q12.14584,11.147441494140626,12.19134,11.128596494140625Q12.23684,11.109750494140625,12.27778,11.082391494140625Q12.31873,11.055031494140625,12.35355,11.020209494140625Q12.38837,10.985387494140625,12.41573,10.944441494140625Q12.44309,10.903495494140625,12.46194,10.857998494140626Q12.48078,10.812501494140625,12.49039,10.764201594140625Q12.5,10.715902194140625,12.5,10.666656494140625Q12.5,10.617410794140625,12.49039,10.569111394140625Q12.48078,10.520811494140625,12.46194,10.475314494140624Q12.44309,10.429817494140625,12.41573,10.388871494140625Q12.38837,10.347925494140625,12.35355,10.313103494140625Q12.31873,10.278281494140625,12.27778,10.250921494140625Q12.23684,10.223562494140625,12.19134,10.204716494140625Q12.14584,10.185871494140624,12.09754,10.176263494140626Q12.04925,10.166656494140625,12,10.166656494140625L9,10.166656494140625Q8.9507543,10.166656494140625,8.9024549,10.176263494140626Q8.854155,10.185871494140624,8.808658,10.204716494140625Q8.763161,10.223562494140625,8.722215,10.250921494140625Q8.681269,10.278281494140625,8.646447,10.313103494140625Q8.611625,10.347925494140625,8.584265,10.388871494140625Q8.556906,10.429817494140625,8.53806,10.475314494140624Q8.519214999999999,10.520811494140625,8.509607,10.569111394140625Q8.5,10.617410794140625,8.5,10.666656494140625Q8.5,10.715902194140625,8.509607,10.764201594140625Q8.519214999999999,10.812501494140625,8.53806,10.857998494140626Q8.556906,10.903495494140625,8.584265,10.944441494140625Q8.611625,10.985387494140625,8.646447,11.020209494140625Q8.681269,11.055031494140625,8.722215,11.082391494140625Q8.763161,11.109750494140625,8.808658,11.128596494140625Q8.854155,11.147441494140626,8.9024549,11.157049494140624Q8.9507543,11.166656494140625,9,11.166656494140625Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M14.166656494140625,3.3333282470703125L14.166656494140625,8.666658247070313Q14.166656494140625,8.715908247070313,14.176263494140626,8.764208247070313Q14.185871494140624,8.812508247070312,14.204716494140625,8.857998247070313Q14.223562494140625,8.903498247070313,14.250921494140625,8.944448247070312Q14.278281494140625,8.985388247070311,14.313103494140625,9.020218247070313Q14.347925494140625,9.055038247070312,14.388871494140625,9.082398247070312Q14.429817494140625,9.109758247070314,14.475314494140624,9.128598247070313Q14.520811494140625,9.147448247070312,14.569111394140625,9.157058247070314Q14.617410794140625,9.166658247070313,14.666656494140625,9.166658247070313Q14.715902194140625,9.166658247070313,14.764201594140625,9.157058247070314Q14.812501494140625,9.147448247070312,14.857998494140626,9.128598247070313Q14.903495494140625,9.109758247070314,14.944441494140625,9.082398247070312Q14.985387494140625,9.055038247070312,15.020209494140625,9.020218247070313Q15.055031494140625,8.985388247070311,15.082391494140625,8.944448247070312Q15.109750494140625,8.903498247070313,15.128596494140625,8.857998247070313Q15.147441494140626,8.812508247070312,15.157049494140624,8.764208247070313Q15.166656494140625,8.715908247070313,15.166656494140625,8.666658247070313L15.166656494140625,3.3333282470703125Q15.166656494140625,3.2840825470703123,15.157049494140624,3.2357831470703124Q15.147441494140626,3.1874832470703125,15.128596494140625,3.1419862470703124Q15.109750494140625,3.0964892470703127,15.082391494140625,3.0555432470703123Q15.055031494140625,3.0145972470703124,15.020209494140625,2.9797752470703127Q14.985387494140625,2.9449532470703126,14.944441494140625,2.9175932470703123Q14.903495494140625,2.8902342470703126,14.857998494140626,2.8713882470703123Q14.812501494140625,2.8525432470703125,14.764201594140625,2.8429352470703124Q14.715902194140625,2.8333282470703125,14.666656494140625,2.8333282470703125Q14.617410794140625,2.8333282470703125,14.569111394140625,2.8429352470703124Q14.520811494140625,2.8525432470703125,14.475314494140624,2.8713882470703123Q14.429817494140625,2.8902342470703126,14.388871494140625,2.9175932470703123Q14.347925494140625,2.9449532470703126,14.313103494140625,2.9797752470703127Q14.278281494140625,3.0145972470703124,14.250921494140625,3.0555432470703123Q14.223562494140625,3.0964892470703127,14.204716494140625,3.1419862470703124Q14.185871494140624,3.1874832470703125,14.176263494140626,3.2357831470703124Q14.166656494140625,3.2840825470703123,14.166656494140625,3.3333282470703125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g><g><path d="M0.833343505859375,3.3333282470703125L0.833343505859375,8.666658247070313Q0.833343505859375,8.715908247070313,0.8429505058593749,8.764208247070313Q0.852558505859375,8.812508247070312,0.871403505859375,8.857998247070313Q0.890249505859375,8.903498247070313,0.917608505859375,8.944448247070312Q0.944968505859375,8.985388247070311,0.979790505859375,9.020218247070313Q1.014612505859375,9.055038247070312,1.055558505859375,9.082398247070312Q1.096504505859375,9.109758247070314,1.1420015058593749,9.128598247070313Q1.187498505859375,9.147448247070312,1.235798405859375,9.157058247070314Q1.284097805859375,9.166658247070313,1.333343505859375,9.166658247070313Q1.382589205859375,9.166658247070313,1.430888605859375,9.157058247070314Q1.479188505859375,9.147448247070312,1.5246855058593751,9.128598247070313Q1.570182505859375,9.109758247070314,1.611128505859375,9.082398247070312Q1.652074505859375,9.055038247070312,1.686896505859375,9.020218247070313Q1.721718505859375,8.985388247070311,1.749078505859375,8.944448247070312Q1.7764375058593749,8.903498247070313,1.795283505859375,8.857998247070313Q1.814128505859375,8.812508247070312,1.823736505859375,8.764208247070313Q1.833343505859375,8.715908247070313,1.833343505859375,8.666658247070313L1.833343505859375,3.3333282470703125Q1.833343505859375,3.2840825470703123,1.823736505859375,3.2357831470703124Q1.814128505859375,3.1874832470703125,1.795283505859375,3.1419862470703124Q1.7764375058593749,3.0964892470703127,1.749078505859375,3.0555432470703123Q1.721718505859375,3.0145972470703124,1.686896505859375,2.9797752470703127Q1.652074505859375,2.9449532470703126,1.611128505859375,2.9175932470703123Q1.570182505859375,2.8902342470703126,1.5246855058593751,2.8713882470703123Q1.479188505859375,2.8525432470703125,1.430888605859375,2.8429352470703124Q1.382589205859375,2.8333282470703125,1.333343505859375,2.8333282470703125Q1.284097805859375,2.8333282470703125,1.235798405859375,2.8429352470703124Q1.187498505859375,2.8525432470703125,1.1420015058593749,2.8713882470703123Q1.096504505859375,2.8902342470703126,1.055558505859375,2.9175932470703123Q1.014612505859375,2.9449532470703126,0.979790505859375,2.9797752470703127Q0.944968505859375,3.0145972470703124,0.917608505859375,3.0555432470703123Q0.890249505859375,3.0964892470703127,0.871403505859375,3.1419862470703124Q0.852558505859375,3.1874832470703125,0.8429505058593749,3.2357831470703124Q0.833343505859375,3.2840825470703123,0.833343505859375,3.3333282470703125Z" fill-rule="evenodd" fill="#232323" fill-opacity="1"/></g></g></svg>
\ No newline at end of file
......@@ -1055,3 +1055,42 @@ export function findAncestors(data, targetId, idKey = "id", childrenKey = "child
return null; // 如果遍历完所有节点都没有找到目标节点,则返回null
}
/**
* 给树形添加层级
* @param {Array<any> | object} tree
* @param {number} startLevel
*/
export function addTreeLevel(tree, startLevel = 1, removeEmptyChildren = true) {
if (tree instanceof Array && tree?.length) {
tree.forEach(node => {
addTreeLevel(node, startLevel, removeEmptyChildren);
});
} else if (Object.prototype.toString.call(tree) == "[object Object]") {
tree["level"] = startLevel;
if (tree?.children) {
addTreeLevel(tree.children, startLevel + 1, removeEmptyChildren);
removeEmptyChildren && !tree.children?.length ? delete tree.children : null;
}
}
}
/**
* 给树形节点添加父节点关联
* @param {Array<any> | object} tree
* @param {object} parent
*/
export function addNodeParent(tree, parent = null) {
if (tree instanceof Array && tree?.length) {
tree.forEach(node => {
addNodeParent(node, parent);
});
} else if (Object.prototype.toString.call(tree) == "[object Object]") {
tree["parent"] = parent;
if (tree?.children?.length) {
addNodeParent(tree.children, tree);
}
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
<div class="feed-summary-container">
<div class="feed-summary-inner">
<div class="left-side-menu">
<project-side-menu></project-side-menu>
<project-side-menu :menuTree="menuTreeList"></project-side-menu>
</div>
</div>
</div>
......@@ -16,7 +16,67 @@ export default {
},
data() {
return {
menuTreeList: []
menuTreeList: [
{
nodeName: "房建类成本科目",
id: "1",
children: [
{
nodeName: "劳务分包工程",
id: "1-1",
children: [
{
nodeName: "主体工程-结构劳务",
id: "1-1-1",
children: [
{
nodeName: "结构劳务分包",
id: "1-1-1-1",
}
]
},
{
nodeName: "二次结构及粗装修劳务",
id: "1-2-1",
children: [
{
nodeName: "二次机构及粗装修劳务",
id: "1-2-1",
}
]
},
{
nodeName: "拆除、修缮、清理、改造劳...",
id: "1-3-1",
children: [
{
nodeName: "拆除、修缮、清理、改造劳...",
id: "1-3-1",
}
]
}
]
},
{
nodeName: "专业分包工程",
id: "2",
},
{
nodeName: "实体工程材料(土建)",
id: "3",
},
{
nodeName: "其他直接费成本",
id: "4",
},
]
},
{
nodeName: "未归类项目",
id: "2",
children: []
}
]
};
},
//可访问data属性
......
......@@ -19,7 +19,6 @@ export default {
name: "projectBreadCrumb",
props: {
current: String,
indexText: String,
breadCrumbTree: {
type: Array,
default: () => []
......
<template>
<div class="project-side-menu-container">
<el-menu mode="vertical" class="project-side-menu-instance">
<project-menu-item></project-menu-item>
<template v-for="(item,index) of tempMenuTree">
<project-menu-item :menuItem="item" :key="item.nodeValue"></project-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
import ProjectMenuItem from "@/views/projectCostLedger/detail/components/ProjectSideMenu/ProjectMenuItem";
import { addTreeLevel, addNodeParent } from "@/utils";
export default {
name: "projectSideMenu",
components: {
......@@ -15,14 +18,43 @@ export default {
props: {
// 菜单树形结构对象
menuTree: {
type: Object,
type: Array,
required: false,
default: () => ({})
default: () => ([])
},
menuOptions: {
type: Object,
default: () => ({
nodeName: "nodeName",
nodeValue: "id",
children: "children",
icon: "icon",
suffixIcon: "suffixIcon"
})
}
},
watch: {
menuTree: {
handler(newValue) {
this.comMenuTree = newValue ? newValue : [];
this.initMenuTree(this.comMenuTree);
},
deep: true,
immediate: true
}
},
data() {
return {
defaultMenuOptions: {
nodeName: "nodeName",
nodeValue: "id",
children: "children",
icon: "icon",
suffixIcon: "suffixIcon"
},
tempMenuOptions: {},
tempMenuTree: [],
comMenuTree: this.menuTree
};
},
//可访问data属性
......@@ -32,12 +64,88 @@ export default {
//计算集
computed: {
allDisabled() {
return (!this.menuTree || !Object.keys(this.menuTree)?.length) ? true : false;
return (!this.menuTree || this.menuTree?.length) ? true : false;
}
},
//方法集
methods: {
// 初始化树形结构
initMenuTree(array = []) {
if (array?.length) {
// 合并默认配置
const _options = this.mergeMenuOptions(JSON.parse(JSON.stringify(this.menuOptions)));
this.tempMenuOptions = _options;
// 映射配置
const resultData = this.mapDataByMenuOptions(JSON.parse(JSON.stringify(this.comMenuTree)), _options);
console.log(resultData);
if (resultData) {
this.tempMenuTree = resultData;
}
}
},
mergeMenuOptions(options) {
// 默认配置
const defaultOptions = JSON.parse(JSON.stringify(this.defaultMenuOptions));
// 合并配置
options = options && Object.prototype.toString.call(options) == "[object Object]" ? { ...defaultOptions, ...options } : { ...defaultOptions };
return options;
},
mapDataByMenuOptions(menuList, options) {
// 分组源数据
const _groupData = this.groupData(menuList, options);
// 映射过后的树
const _mapedData = this.mapData(_groupData, options);
// 处理层级 以及删除空children
return this.buildTree(_mapedData);
},
groupData(data, options, originData = []) {
if (data?.length) {
const { children } = options;
const len = data.length;
for (let index = 0; index < len; index++) {
const _item = data[index];
const _newItem = JSON.parse(JSON.stringify(_item));
originData.push({
originData: _newItem
});
if (_item[children] instanceof Array && _item[children].length) {
_newItem[children] = this.groupData(_item[children], options);
} else {
delete _newItem[children];
}
}
}
return originData;
},
mapData(data = [], mapOptions) {
const keys = Object.keys(mapOptions);
if (data?.length) {
data.forEach(item => {
// 循环key映射到 树
keys.forEach(key => {
const _mapKey = mapOptions[key];
const _origin = item["originData"];
if (Object.hasOwnProperty.call(_origin, _mapKey)) {
item[key] = JSON.parse(JSON.stringify(_origin[_mapKey]));
}
});
if (item?.children instanceof Array && item.children.length) {
// 递归映射
this.mapData(item?.children, mapOptions);
}
});
}
return data;
},
buildTree(mapedData) {
if (mapedData?.length) {
// 添加层级
addTreeLevel(mapedData);
addNodeParent(mapedData);
return mapedData;
}
}
},
}
</script>
......
<template>
<div class="project-cost-ledger-container">
<div class="project-cost-ledger-inner">
<div class="project-cost-ledger-inner" v-if="!isupload">
<div class="title_wrap">
<div class="enterprise_title">
项目成本台账
</div>
</div>
<div class="content-project">
<el-form :model="formdata" label-width="82px" label-position="right" :inline="true" >
<el-row>
<el-form-item label="工程名称">
<el-input v-model="formdata.customerName" placeholder="请输入工程名称" clearable></el-input>
</el-form-item>
<el-form-item label="IPM项目编码" label-width="100px">
<el-input v-model="formdata.customerName" placeholder="请输入IPM项目编码" clearable></el-input>
</el-form-item>
<el-form-item label="成本阶段">
<el-select v-model="formdata.customerClass" multiple placeholder="请选择" :collapse-tags="true" clearable>
<el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目状态">
<el-select v-model="formdata.customerClass" multiple placeholder="请选择" :collapse-tags="true" clearable>
<el-option v-for="(item,index) in ztStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select>
</el-form-item>
</el-row>
<el-divider></el-divider>
<el-form-item label=" ">
<el-button type="primary" size="small" @click="getSearch">查询</el-button>
<el-button size="small" @click="clears">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="table-project">
<div class="table-item-jf1" v-if="total == 0 && !isSkeleton">
<img class="item-jf-img" src="@/assets/images/kong.png" alt="">
<div class="item-jf-titel">暂无数据,点击按钮导入项目成本数据</div>
<el-button type="primary" class="jf-btn" size="small" @click="addPro">新增项目</el-button>
</div>
<skeleton v-if="isSkeleton"></skeleton>
<div style='padding: 16px' v-if="!isSkeleton&&total>0">
<div class="total-title">
<div class="totals">{{total}}</div>
<div class="btns">
<div class="btn btn_primary h32" @click="addPro">导入项目</div>
<div class="btn btn_default h32" @click="getcgx">草稿箱 (0)</div>
</div>
</div>
<div class="table-item-jf table-item">
<el-table :data="tableData" :header-cell-style="{ background:'#f0f3fa',color: 'rgba(35,35,35,0.8)'}"
v-sticky-header.always="{offsetTop : '-16px',offsetBottom : '10px'}" class="table-item1 fixed-table" border highlight-current-row
:header-row-class-name="setHeaderRow" :cell-class-name="setCellClass" :row-class-name="setRowClass" :header-cell-class-name="setCellClass"
ref="theOwnerListTable" :row-key="'customerKey'">
<el-table-column type="index" label="序号" width="60" :resizable="false">
<template slot-scope="scope">
<span>{{(formdata.pageNum - 1) *formdata.pageSize + scope.$index + 1}}</span>
</template>
</el-table-column>
<el-table-column label="工程名称" width="416" :resizable="false">
<template slot-scope="scope">
<div style="display:flex;align-items:center">
<el-tooltip placement="top" v-if="scope.row.customerText.length>20">
<div slot="content">{{scope.row.customerText}}</div>
<div class="renling">
<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>
<span v-else v-html="scope.row.customerName"></span>
</div>
</el-tooltip>
<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"
class="wordprimary" v-html="scope.row.customerName"></router-link>
<span v-else v-html="scope.row.customerName"></span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="项目状态" prop="customerCode" width="90" :resizable="false">
</el-table-column>
<el-table-column label="IPM项目编码" min-width="136">
<template slot-scope="scope">
{{scope.row.recommendOrg||"--"}}
</template>
</el-table-column>
<el-table-column label="文件名称" min-width="286" :resizable="false">
<template slot-scope="scope">
{{scope.row.registerRegion||"--"}}
</template>
</el-table-column>
<el-table-column label="成本阶段" prop="customerCode" width="90" :resizable="false">
</el-table-column>
<el-table-column label="上传人" prop="customerCode" width="90" :resizable="false">
</el-table-column>
<el-table-column label="上传时间" min-width="180" :resizable="false">
<template slot-scope="scope">
{{scope.row.approveDate2||"--"}}
</template>
</el-table-column>
<el-table-column label="操作" min-width="256" :resizable="false" fixed="right">
<template slot-scope="scope">
<span class="wordprimary tabs" @click="goAccess(scope.row)">修改项目信息</span>
<span class="wordprimary tabs" @click="goAssessment(scope.row)">查看导入进度</span>
<span class="worddel tabs" @click="goDisposal(scope.row)">删除</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="pagination clearfix" v-show="total>formdata.pageSize">
<el-pagination background :page-size="formdata.pageSize" :current-page.sync="formdata.pageNum" @current-change="handleCurrentChange" layout="prev, pager, next"
:total="total">
</el-pagination>
</div>
</div>
<el-dialog
class="pro-news"
:visible.sync="dialogVisible"
width="480px">
<div class="poptitle">
<span>新建商机</span>
</div>
<el-form class="popform" label-width="97px" :model="queryParam" :rules="rules" ref="ruleForm">
<el-form-item label="项目名称" class="row">
<el-input type="text" v-model="queryParam.projectName" placeholder="请输入完整的项目名称"></el-input>
</el-form-item>
<el-form-item label="IPM项目编码" class="row">
<el-input type="text" placeholder="请输入IPM项目编码" v-model="queryParam.ipmProjectNo">
<template slot="append"><div class="pro-getbtn" @click="getipmProjectNo">获取数据</div></template>
</el-input>
</el-form-item>
<el-form-item label="文件名称" class="row">
<el-input type="text" placeholder="请输入文件名称" v-model="queryParam.projectFileName"></el-input>
</el-form-item>
<el-form-item label="成本阶段" class="row" prop="cbStage">
<el-select placeholder="请选择成本阶段" v-model="queryParam.cbStage">
<el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue" :key="index"></el-option>
</el-select>
</el-form-item>
</el-form >
<div class="popbot">
<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>
</el-dialog>
</div>
<proupload v-if="isupload"></proupload>
<el-dialog title="草稿箱" :visible.sync="cgxVisible" width="960px" custom-class='dialog-supplier'>
<el-divider></el-divider>
<div style="padding: 24px 20px;">
<skeleton v-if="cgxSkeleton"></skeleton>
<div class="table-item-jf table-item" v-if="!cgxSkeleton">
<el-table :data="tableData" :header-cell-style="{ background:'#f0f3fa',color: 'rgba(35,35,35,0.8)'}"
v-sticky-header.always="{offsetTop : '-16px',offsetBottom : '10px'}" class="table-item1 fixed-table"
border highlight-current-row>
<!--<el-table-column type="index" label="序号" width="60" :resizable="false">-->
<!--<template slot-scope="scope">-->
<!--<span>{{scope.$index + 1}}</span>-->
<!--</template>-->
<!--</el-table-column>-->
<el-table-column label="项目名称" width="451px" >
<template slot-scope="scope">
<span>{{scope.row.legalPerson||'--'}}</span>
</template>
</el-table-column>
<el-table-column label="成本阶段" width="105px">
<template slot-scope="scope">
<span>{{scope.row.legalPerson||'--'}}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" width="205px" :resizable="false">
<template slot-scope="scope">
<span>{{scope.row.legalPerson||'--'}}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<span class="wordprimary">继续编辑</span>
<span class="worddel">删除</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination clearfix" v-show="total>formdata.pageSize">
<el-pagination background :page-size="formdata.pageSize" :current-page.sync="formdata.pageNum"
@current-change="handleCurrentChange" layout="prev, pager, next"
:total="cgxtotal">
</el-pagination>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
import '@/assets/styles/public.scss'
import { checkProjectCodeExist } from '@/api/projectCostLedger/index'
import { getDicts } from '@/api/system/dict/data'
import proupload from '@/views/projectCostLedger/upload/index'
import skeleton from '@/views/project/projectList/component/skeleton'
export default {
name: "projectCostLedger",
components:{proupload,skeleton},
data() {
return {
formdata:{},
isSkeleton:false,
total:10,
dialogVisible:false,
cbStagelist:[],
ztStagelist:[],
//新建项目参数
queryParam:{
projectName:'',//项目名称
ipmProjectNo:'',// IPM项目编码
isGetProjectDetail:0,// 是否获取项目详情 0:否、1:是)
projectFileName:'',// 文件名称
cbStage:'',//成本阶段
},
rules:{
cbStage:[{ required: true, message: '请选择成本阶段!', trigger: 'blur' },],
},
isupload:false,
tableData:[],
cgxVisible:true,
cgxSkeleton:false,
cgxtotal:10,
};
},
//可访问data属性
created() {
// this.isupload = true
//成本阶段
getDicts('pro_cbstage').then(res=>{
this.cbStagelist = res.data
})
//项目文件状态
getDicts('pro_ztstage').then(res=>{
this.ztStagelist = res.data
})
},
//计算集
......@@ -23,20 +257,296 @@ export default {
},
//方法集
methods: {
addPro(){
this.dialogVisible = true
this.queryParam = {
projectName: '',//项目名称
ipmProjectNo: '',// IPM项目编码
isGetProjectDetail: 0,// 是否获取项目详情 0:否、1:是)
projectFileName: '',// 文件名称
cbStage: ''//成本阶段
}
},
getSearch(){
this.formdata.pageNum = 1
// this.customerAll()
},
getipmProjectNo(){
//点击且校验了当前编码有数据才获取
checkProjectCodeExist(this.queryParam.ipmProjectNo).then(res=>{
if(res.code == 200 && res.data == true){
this.queryParam.isGetProjectDetail = 1
}else{
this.queryParam.isGetProjectDetail = 0
}
})
},
clears(){
this.formdata={
customerName: '',
customerClass:[],
areas:[],
province:[],
city:[],
customerState:[],
creditLevel:[],
credential:[],
approveDateBegion:null,
approveDateEnd:null,
times:[],
pageSize:50,
pageNum:1,
}
// this.customerAll()
},
//添加项目
insertPro(){
let id = ''
this.isupload = true
},
handleCurrentChange(val){
this.formdata.pageNum = val
this.customerAll()
},
setHeaderRow() {
return "owner-table-list-header";
},
setCellClass({ row, column, rowIndex, columnIndex }) {
if (columnIndex == 1) {
return "enterprise-name-column";
}
},
setRowClass({ row, rowIndex }) {
return "enterprise-name-row";
},
getcgx(){
this.cgxVisible = true
},
},
}
</script>
<style lang="scss" scoped>
.project-cost-ledger-container {
.project-cost-ledger-container {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 16px 24px;
overflow: auto;
.project-cost-ledger-inner {
width: 100%;
height: 100%;
/*height: 100%;*/
}
.content-project {
background: #fff;
padding-top: 14px;
.el-form-item {
margin-bottom: 16px;
}
.el-divider {
margin-bottom: 16px;
}
}
.table-project {
background: #fff;
margin-top: 16px;
height: calc(100vh - 296px);
padding-top: 1px;
min-height: 350px;
.table-item-jf1 {
margin-top: calc(27vh - 90px);
.item-jf-img {
margin-bottom: 16px;
}
}
.item-jf-titel {
font-size: 14px;
color: #232323;
line-height: 22px;
margin-bottom: 16px;
}
.jf-btn {
display: block;
background: #0081ff;
margin: auto;
}
.btn{
width: auto;
padding: 0 12px;
}
.btn + .btn{
margin-left: 16px;
}
}
::v-deep .pro-news {
.el-dialog__body {
padding: 24px 0 0;
}
.el-dialog__headerbtn {
top: 20px;
right: 20px;
z-index: 3;
}
.poptitle {
line-height: 56px;
border-bottom: 1px solid #eee;
height: 56px;
position: absolute;
top: 0;
left: 0;
width: 100%;
> span {
padding-left: 20px;
font-weight: bold;
font-size: 16px;
color: #232323;
font-family: Microsoft YaHei-Bold, Microsoft YaHei;
width: 385px;
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.popform {
padding: 24px 20px 0;
.row {
margin-bottom: 16px;
position: relative;
.el-form-item__label {
font-weight: 400;
opacity: 0.8;
padding: 0;
font-size: 14px;
color: #232323;
padding-right: 16px;
}
.el-input,
.el-textarea,
.el-select {
display: inline-block;
width: 343px;
.el-input__inner,
.el-textarea__inner {
width: 100%;
height: 32px;
border-radius: 0px;
&:hover {
border-color: #0081ff;
}
}
.el-textarea__inner {
height: 90px;
font-family: inherit;
color: #000;
}
.el-input__suffix {
height: 32px;
}
.el-input__icon {
line-height: 32px;
}
}
.el-form-item__error {
padding-top: 2px;
}
}
.el-input-group--append{
position: relative;
.el-input-group__append{
position: absolute;
right: 0;
width: 76px;
top: 0;
border: 0;
background: none;
&:hover{
background: none !important;
}
.pro-getbtn{
border-left: 1px solid #DCDFE6;
height: 32px;
color: #0081FF;
line-height: 32px;
text-align: center;
}
}
}
}
.popbot {
border-top: 1px solid #EEEEEE;
text-align: right;
margin-top: 24px;
padding: 16px 20px;
.btn {
border-radius: 2px;
margin-left: 12px;
padding: 0 24px;
&.btn_disabled{
background: #8BD1FF;
}
}
}
}
.total-title{
height: 32px;
line-height: 32px;
.totals{
padding-left: 6px;
position: relative;
font-size: 12px;
color: #3D3D3D;
display: inline-block;
&::before{
content: ' ';
position: absolute;
width: 2px;
height: 2px;
background: rgba(35,35,35,0.4);
border-radius: 50%;
left: 0;
top: 12px;
}
}
margin-bottom: 16px;
.btns{
float: right;
display: inline-block;
width: 30%;
text-align: right;
}
}
}
::v-deep .dialog-supplier{
.el-dialog__body{
padding: 0;
}
}
.worddel{
color: #FA5351;
}
</style>
<template>
<div class="project-cost-ledger-inner">
<div class="pro-upload">
<div class="title_wrap i">
<div class="title-small"><span>项目成本台账 <i class="el-icon-arrow-right"></i> </span>导入项目</div>
<div class="enterprise_title">
项目信息
</div>
</div>
<div class="content-project">
<el-form :model="formdata" label-width="82px" :rules="rules" label-position="right" :inline="true">
<el-row>
<el-form-item label="项目名称">
<el-input v-model="formdata.customerName" disabled placeholder="请输入工程名称" clearable></el-input>
</el-form-item>
<el-form-item label="IPM项目编码" label-width="100px">
<el-input v-model="formdata.customerName" disabled placeholder="请输入IPM项目编码" clearable></el-input>
</el-form-item>
<el-form-item label="文件名称" label-width="100px">
<el-input v-model="formdata.customerName" disabled placeholder="请输入文件名称" clearable></el-input>
</el-form-item>
<el-form-item label="成本阶段" prop="cbStage">
<el-select v-model="formdata.cbStage" disabled multiple placeholder="请选择" :collapse-tags="true"
clearable>
<el-option v-for="(item,index) in cbStagelist" :label="item.dictLabel" :value="item.dictValue"
:key="index"></el-option>
</el-select>
</el-form-item>
</el-row>
</el-form>
</div>
<div class="title_wrap i">
<div class="enterprise_title">
导入文件 <div class="tips">操作指引 <img src="../../../assets/images/icon_tips_question.svg"/></div>
</div>
</div>
<div class="upload-project">
<el-form :model="uploaddata" label-width="200px" :rules="uprules" label-position="right" :inline="true">
<el-row>
<el-form-item label="直接费成本" prop="zjfcb">
<div class="filelist">
<div class="fileli">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)-加固修缮工程.xls</div>
<div class="prostatus i1">解析成功</div>
<div class="cz">
<div>重新上传</div>
<div>删除</div>
</div>
</div>
<div class="wrong">
失败原因:解析失败的原因展示
</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 class="fileli">
<div>
<img src="../../../assets/images/icon_wrapper.png">
<div class="name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)-加固修缮工程.xls</div>
<div class="prostatus i3">解析失败</div>
<div class="cz">
<div>重新上传</div>
<div>删除</div>
</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>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="工料汇总" prop="glhz">
<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>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="措施项目" prop="csxm">
<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>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="其他项目" prop="qtxm">
<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>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="现场经费" prop="xcjf">
<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>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="成本汇总" prop="cbhz">
<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>
</el-form-item>
</el-row>
</el-form>
</div>
<el-divider></el-divider>
<div class="pro-btns">
<el-button type="primary" size="small" >导入数据</el-button>
<el-button size="small">返回</el-button>
</div>
</div>
</div>
</template>
<script>
import { getDicts } from '@/api/system/dict/data'
export default {
name: 'upload',
data(){
return{
formdata:{
cbStage:null,
},
cbStagelist:[],
rules:{
cbStage:[{ required: true, message: '请选择成本阶段!', trigger: 'blur' },],
},
uploaddata:{},
uprules:{
zjfcb:[{ required: true, trigger: 'blur' },],
glhz:[{ required: true, trigger: 'blur' },],
csxm:[{ required: true, trigger: 'blur' },],
qtxm:[{ required: true, trigger: 'blur' },],
xcjf:[{ required: true, trigger: 'blur' },],
cbhz:[{ required: true, trigger: 'blur' },],
},
fileList:[],
}
},
created() {
//成本阶段
getDicts('pro_cbstage').then(res => {
this.cbStagelist = res.data
})
},
methods:{
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`);
}
}
}
</script>
<style scoped lang="scss">
.title-small{
font-size: 12px;
line-height: 24px;
margin-bottom: 16px;
>span{
font-size: 14px;
opacity: 0.4;
>i{
font-size: 12px;
margin-right: 4px;
}
}
}
.title_wrap.i{
border: 0;
padding: 16px;
.tips{
display: inline-block;
font-size: 14px;
color: #FFAB44;
line-height: 22px;
font-weight: 400;
padding-left: 8px;
cursor: pointer;
>img{
float: right;
margin-top: 5px;
margin-left: 2px;
}
}
}
::v-deep .pro-upload{
background: #fff;
.el-form-item{
margin-bottom: 16px;
}
.el-form-item__label {
font-weight: 400;
opacity: 0.8;
padding: 0;
font-size: 14px;
color: #232323;
padding-right: 16px;
}
}
::v-deep .upload-project{
padding: 0 16px;
.el-form-item{
width: 751px;
.el-form-item__label{
display: block;
text-align: left;
}
}
.filelist{
.fileli{
min-height: 36px;
margin-top: 8px;
width: 751px;
background: #F7F8FA;
border-radius: 2px;
padding: 7px 12px 7px 40px;
img{
width: 16px;
float: left;
margin-left: -26px;
margin-top: 3px;
}
.name{
float: left;
height: 22px;
font-size: 14px;
font-weight: 400;
color: #232323;
line-height: 22px;
max-width: 515px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.prostatus{
float: left;
margin-left: 12px;
height: 22px;
border-radius: 2px;
color: #fff;
padding: 0 8px;
line-height: 22px;
font-size: 12px;
&.i1{
background: #0CBC6D;
}
&.i2{
background: #FFAB44;
}
&.i3{
background: #FF3C3C;
}
}
.cz{
float: right;
height: 22px;
line-height: 22px;
>div{
cursor: pointer;
margin-left: 12px;
color: #0081FF;
display: inline-block;
&:last-child{
color: #FF3C3C;
}
}
}
}
.wrong{
clear: both;
margin-left: -28px;
font-size: 12px;
color: #FF3C3C;
line-height: 21px;
padding-top: 4px;
}
}
.upload{
margin-top: 8px;
.el-upload{
width: 100%;
}
.uploadpro{
width: 750px;
height: 36px;
line-height: 36px;
background: #FFFFFF;
border-radius: 2px;
border: 1px solid #DCDFE6;
padding: 0;
display: block;
font-size: 14px;
color: #232323;
img{
margin-right: 12px;
width: 14px;
margin-top: -4px;
}
}
}
}
.pro-btns{
padding: 16px 0;
text-align: center;
.el-button--primary{
background: #0081ff;
border-color: #0081ff;
}
.el-button{
padding: 0 16px;
height: 34px;
line-height: 34px;
border-radius: 2px;
}
.el-button + .el-button{
margin-left: 12px;
}
}
</style>
......@@ -10,6 +10,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.List;
......@@ -37,4 +38,6 @@ public interface ISysOssService {
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
InputStream downFileIO(Long ossId);
}
......@@ -128,6 +128,7 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
public SysOssVo upload(MultipartFile file) throws UnsupportedEncodingException {
String originalfileName = file.getOriginalFilename();
//文件名解码防止上传中文名文件导致的文件名乱码
assert originalfileName != null;
originalfileName = URLDecoder.decode(originalfileName,"UTF-8");
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance();
......@@ -177,6 +178,16 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public InputStream downFileIO(Long ossId) {
//文件下载
SysOss sysOss = baseMapper.selectById(ossId);
if (ObjectUtil.isNull(sysOss)) {
throw new ServiceException("文件数据不存在!");
}
return OssFactory.instance(sysOss.getService()).getObjectContent(sysOss.getUrl());
}
/**
* 匹配Url
*
......
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