Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master' into master

yangyj 1 anno fa
parent
commit
8f02afcea8

+ 37 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/config/LocalDateConverter.java

@@ -0,0 +1,37 @@
+package org.springblade.meter.config;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public class LocalDateConverter implements Converter<LocalDate> {
+
+    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+    @Override
+    public Class supportJavaTypeKey() {
+        return LocalDate.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
+                                       GlobalConfiguration globalConfiguration) throws Exception {
+        return LocalDate.parse(cellData.getStringValue(), FORMATTER);
+    }
+
+    @Override
+    public CellData<String> convertToExcelData(LocalDate value, ExcelContentProperty contentProperty,
+                                               GlobalConfiguration globalConfiguration) throws Exception {
+        return new CellData<>(value.format(FORMATTER));
+    }
+}

+ 12 - 6
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/entity/MaterialMeterForm.java

@@ -16,9 +16,11 @@
  */
 package org.springblade.meter.entity;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.format.DateTimeFormat;
 import com.baomidou.mybatisplus.annotation.TableName;
 
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 
@@ -26,6 +28,8 @@ import io.swagger.annotations.ApiModelProperty;
 import org.springblade.core.mp.base.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.meter.config.IsConverter;
+import org.springblade.meter.config.LocalDateConverter;
 
 /**
  * 材料计量单实体类
@@ -65,8 +69,10 @@ public class MaterialMeterForm extends BaseEntity {
      */
     @ApiModelProperty(value = "合同材料id")
     private Long contractMaterialId;
+
     @ApiModelProperty(value = "合同材料名称")
     private String contractMaterialName;
+
     @ApiModelProperty(value = "期号")
     private String periodNumber;
     /**
@@ -89,11 +95,6 @@ public class MaterialMeterForm extends BaseEntity {
      */
     @ApiModelProperty(value = "计量金额")
     private BigDecimal meterMoney;
-    /**
-     * 业务日期
-     */
-    @ApiModelProperty(value = "业务日期")
-    private LocalDate businessDate;
     /**
      * 备料堆放地点
      */
@@ -109,6 +110,11 @@ public class MaterialMeterForm extends BaseEntity {
      */
     @ApiModelProperty(value = "材料来源")
     private String materialSource;
+    /**
+     * 业务日期
+     */
+    @ApiModelProperty(value = "业务日期")
+    private LocalDate businessDate;
     /**
      * 材料是否符合0不符合1符合
      */

+ 105 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/excel/MaterialMeterFormExcel.java

@@ -0,0 +1,105 @@
+
+package org.springblade.meter.excel;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.format.DateTimeFormat;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.meter.config.IsConverter;
+import org.springblade.meter.config.LocalDateConverter;
+
+/**
+ * 材料计量单实体类
+ *
+ * @author BladeX
+ * @since 2023-11-29
+ */
+@Data
+public class MaterialMeterFormExcel {
+
+    private static final long serialVersionUID = 1456L;
+
+    /**
+     * 材料到场编号
+     */
+    @ApiModelProperty(value = "材料到场编号")
+    @ExcelProperty("材料到场编号")
+    private String materialArriveNumber;
+
+    @ApiModelProperty(value = "合同材料名称")
+    @ExcelProperty("合同材料")
+    private String contractMaterialName;
+
+    /**
+     * 单价
+     */
+    @ApiModelProperty(value = "单价")
+    @ExcelProperty("单价")
+    private BigDecimal price;
+    /**
+     * 计量数量
+     */
+    @ApiModelProperty(value = "计量数量")
+    @ExcelProperty("数量")
+    private BigDecimal meterAmount;
+
+    /**
+     * 备料堆放地点
+     */
+    @ApiModelProperty(value = "备料堆放地点(进料发票号)")
+    @ExcelProperty("进料发票(单据)号")
+    private String storagePlace;
+    /**
+     * 存储情况
+     */
+    @ApiModelProperty(value = "存储情况(质保书编号)")
+    @ExcelProperty("质保书编号")
+    private String storageStatus;
+    /**
+     * 材料来源
+     */
+    @ApiModelProperty(value = "材料来源")
+    @ExcelProperty("材料来源")
+    private String materialSource;
+    /**
+     * 业务日期
+     */
+    @ApiModelProperty(value = "业务日期")
+    @ExcelProperty(value = "业务日期",converter = LocalDateConverter.class)
+    private LocalDate businessDate;
+
+    @ApiModelProperty(value = "材料是否符合0不符合1符合")
+    @ExcelProperty(value = "材料是否符合要求")
+    private String materialConformName;
+
+    @ApiModelProperty(value = "存储是否符合0不符合1符合")
+    @ExcelProperty(value = "存储方法是否符合要求")
+    private String storageConformName;
+
+    @ExcelIgnore
+    private Integer materialConform;
+    @ExcelIgnore
+    private Integer storageConform;
+    /**
+     * 合格证
+     */
+    @ApiModelProperty(value = "合格证(抽检报告编号)")
+    @ExcelProperty("抽检报告编号")
+    private String certificate;
+    /**
+     * 备注
+     */
+    @ApiModelProperty(value = "备注")
+    @ExcelProperty("备注")
+    private String remark;
+
+
+}

+ 13 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -990,24 +991,32 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     public List<AppWbsTreeContractVO> searchNodeAllTableAndFile(String primaryKeyId, String type, String
             contractId, String projectId) {
         List<AppWbsTreeContractVO> vos = this.searchNodeAllTable(primaryKeyId, type, contractId, projectId, null);
+        List<AppWbsTreeContractVO> voList = new ArrayList<>();
+        List<TableFile> files2 = tableFileService.list(new LambdaQueryWrapper<TableFile>()
+                .eq(TableFile::getTabId,primaryKeyId));
         if (vos != null && vos.size() > 0) {
             List<Long> list = vos.stream().map(AppWbsTreeContractVO::getPKeyId).collect(Collectors.toList());
             List<TableFile> files = tableFileService.getAllFileByIds(list);
             if (files != null && files.size() > 0) {
                 Map<String, List<TableFile>> map = files.parallelStream()
                         .collect(Collectors.groupingBy(TableFile::getTabId));
-                List<AppWbsTreeContractVO> voList = new ArrayList<>();
                 for (AppWbsTreeContractVO vo : vos) {
                     if (map.get(vo.getPKeyId() + "") != null && map.get(vo.getPKeyId() + "").size() > 0) {
                         vo.setFileList(map.get(vo.getPKeyId() + ""));
                         voList.add(vo);
                     }
                 }
-                return voList;
             }
-            return null;
         }
-        return null;
+        /** 如果存在节点附件,末尾追加节点附件*/
+        if (files2 != null && files2.size() > 0){
+            WbsTreeContract treeContract = this.getOne(new LambdaQueryWrapper<WbsTreeContract>()
+                    .eq(WbsTreeContract::getPKeyId,primaryKeyId));
+            AppWbsTreeContractVO vo = BeanUtil.copyProperties(treeContract, AppWbsTreeContractVO.class);
+            vo.setFileList(files2);
+            voList.add(vo);
+        }
+        return voList;
     }
 
     @Override

+ 30 - 3
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/MaterialMeterFormController.java

@@ -27,12 +27,14 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.meter.dto.MaterialMeterFormDTO;
 import org.springblade.meter.vo.MaterialMeterFormVO;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.meter.entity.MaterialMeterForm;
 import org.springblade.meter.service.IMaterialMeterFormService;
 import org.springblade.core.boot.ctrl.BladeController;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 材料计量单 控制器
@@ -48,6 +50,8 @@ public class MaterialMeterFormController extends BladeController {
 
 	private final IMaterialMeterFormService materialMeterFormService;
 
+	private final JdbcTemplate jdbcTemplate;
+
 
 	/**
 	 * 新增 材料计量单
@@ -90,7 +94,7 @@ public class MaterialMeterFormController extends BladeController {
 	 * 修改 材料计量单
 	 */
 	@PostMapping("/update")
-	@ApiOperationSupport(order = 5)
+	@ApiOperationSupport(order = 4)
 	@ApiOperation(value = "修改", notes = "传入materialMeterFormDTO")
 	public R update(@Valid @RequestBody MaterialMeterFormDTO dto) {
 		materialMeterFormService.update2(dto);
@@ -101,12 +105,35 @@ public class MaterialMeterFormController extends BladeController {
 	 * 删除 材料计量单
 	 */
 	@PostMapping("/remove")
-	@ApiOperationSupport(order = 7)
+	@ApiOperationSupport(order = 5)
 	@ApiOperation(value = "逻辑删除", notes = "传入ids")
 	public R delete(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
 		materialMeterFormService.delete(Func.toLongList(ids));
 		return R.success("删除成功");
 	}
 
-	
+	/**
+	 * 获取导入模板 材料计量单
+	 */
+	@GetMapping("/getImportTemplate")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "获取材料计量单导入模板", notes = "返回导入模板URL")
+	public R<String> getImportTemplate() {
+		String url = jdbcTemplate.queryForObject("select dict_value from blade_dict_biz where code = 'import_template' and dict_key = 12 and is_deleted = 0", String.class);
+		return R.data(url);
+	}
+
+
+	/**
+	 * 导入 材料计量单
+	 */
+	@PostMapping("/importExcel")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "导入excel", notes = "传入文件,项目id,合同id,计量期id")
+	public R<String> importExcel(@RequestParam("file") MultipartFile file, Long projectId, Long contractId,Long meterPeriodId) {
+		return materialMeterFormService.importExcel(file,projectId,contractId,meterPeriodId);
+	}
+
+
+
 }

+ 4 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/service/IMaterialMeterFormService.java

@@ -18,10 +18,12 @@ package org.springblade.meter.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
 import org.springblade.meter.dto.MaterialMeterFormDTO;
 import org.springblade.meter.entity.MaterialMeterForm;
 import org.springblade.core.mp.base.BaseService;
 import org.springblade.meter.vo.MaterialMeterFormVO;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -43,4 +45,6 @@ public interface IMaterialMeterFormService extends BaseService<MaterialMeterForm
     void update2(MaterialMeterFormDTO dto);
 
     void delete(List<Long> ids);
+
+    R<String> importExcel(MultipartFile file, Long projectId, Long contractId,Long meterPeriodId);
 }

+ 104 - 7
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MaterialMeterFormServiceImpl.java

@@ -20,27 +20,31 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.excel.util.ExcelUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.meter.dto.MaterialMeterFormDTO;
-import org.springblade.meter.entity.AttachmentForm;
-import org.springblade.meter.entity.ContractMeterPeriod;
-import org.springblade.meter.entity.MaterialMeterForm;
-import org.springblade.meter.entity.MeterPeriod;
+import org.springblade.meter.entity.*;
+import org.springblade.meter.excel.MaterialMeterFormExcel;
 import org.springblade.meter.mapper.MaterialMeterFormMapper;
-import org.springblade.meter.service.IAttachmentFormService;
-import org.springblade.meter.service.IMaterialMeterFormService;
+import org.springblade.meter.service.*;
 import org.springblade.core.mp.base.BaseServiceImpl;
-import org.springblade.meter.service.IMeterPeriodService;
 import org.springblade.meter.vo.MaterialMeterFormVO;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 材料计量单 服务实现类
@@ -56,6 +60,10 @@ public class MaterialMeterFormServiceImpl extends BaseServiceImpl<MaterialMeterF
 
     private final IMeterPeriodService meterPeriodService;
 
+    private final IContractMaterialService contractMaterialService;
+
+    private final MeterContractInfoService meterContractInfoService;
+
 
     /**
      * 新增 材料计量单
@@ -159,4 +167,93 @@ public class MaterialMeterFormServiceImpl extends BaseServiceImpl<MaterialMeterF
             this.removeById(id);
         }
     }
+
+    @Override
+    public R<String> importExcel(MultipartFile file, Long projectId, Long contractId,Long meterPeriodId) {
+        //获取计量期信息
+        MeterPeriod period = meterPeriodService.getById(meterPeriodId);
+        if (ObjectUtil.isEmpty(period)){
+            throw new ServiceException("未获取到计量期相关信息");
+        }
+        if (period.getApproveStatus() != 0){
+            throw new ServiceException("当前材料计量期不是未上报状态,不能导入材料计量单");
+        }
+        //获取当前合同段所有材料
+        List<ContractMaterial> materials = contractMaterialService.list(new LambdaQueryWrapper<ContractMaterial>()
+                .eq(ContractMaterial::getContractId, contractId));
+        if (ObjectUtil.isEmpty(materials)){
+            throw new ServiceException("当前合同段没有材料");
+        }
+        Map<String, ContractMaterial> materialMap = materials.stream().collect(Collectors.toMap(l -> l.getMaterialName(), l -> l));
+        //获取后管合同段材料支付比例
+        MeterContractInfo one = meterContractInfoService.getOne(new LambdaQueryWrapper<MeterContractInfo>()
+                .eq(MeterContractInfo::getContractId, contractId));
+        if (ObjectUtil.isEmpty(one) || ObjectUtil.isEmpty(one.getClPrepaymentRatio())){
+            throw new ServiceException("当前合同段未设置材料预付款比例");
+        }
+        //校验文件类型
+        String filename = file.getOriginalFilename();
+        String fileSuffix = filename.substring(filename.lastIndexOf(".")+1);
+        try {
+            if (!"xlsx".contains(fileSuffix)) {
+                throw new ServiceException("请传入excel文件,或者先转换为xlsx");
+            }
+            List<MaterialMeterFormExcel> excels = ExcelUtil.read(file, MaterialMeterFormExcel.class);
+            excels = excels.stream()
+                    .filter(l -> (StringUtils.isNotBlank(l.getContractMaterialName())))
+                    .collect(Collectors.toList());
+            if (excels == null || excels.size() == 0) {
+                throw new ServiceException("未检测到excel中材料计量单数据,请检查格式后后重新导入");
+            }
+            excels.forEach(l->{
+                if (StringUtils.isBlank(l.getMaterialConformName()) || l.getMaterialConformName().equals("否")){
+                    l.setMaterialConform(0);
+                }else {
+                    l.setMaterialConform(1);
+                }
+                if (StringUtils.isBlank(l.getStorageConformName()) || l.getStorageConformName().equals("否")){
+                    l.setStorageConform(0);
+                }else {
+                    l.setStorageConform(1);
+                }
+            });
+            //复制数据
+            List<MaterialMeterForm> forms = BeanUtil.copy(excels, MaterialMeterForm.class);
+            //循环数据
+            forms.stream().forEach(l -> {
+                /** 校验字段 */
+                if (StringUtils.isBlank(l.getMaterialArriveNumber()) || StringUtils.isBlank(l.getContractMaterialName()) || ObjectUtil.isEmpty(l.getBusinessDate())) {
+                    throw new ServiceException("excel中有必填项未填写,请检查(材料到场编号,合同材料,业务日期)后重新导入");
+                }
+                if (l.getPrice() == null || l.getMeterAmount() == null) {
+                    throw new ServiceException("请填写单价和数量");
+                }
+                ContractMaterial material = materialMap.get(l.getContractMaterialName());
+                if (ObjectUtil.isEmpty(material)){
+                    throw new ServiceException("当前合同段没有材料:"+l.getContractMaterialName());
+                }
+                /** 补充字段 */
+                l.setProjectId(projectId);
+                l.setContractId(contractId);
+                l.setMeterPeriodId(period.getId());
+                l.setPeriodNumber(period.getPeriodNumber());
+                l.setPeriodName(period.getPeriodName());
+                l.setContractMaterialId(material.getId());
+                l.setMeterMoney(l.getPrice().multiply(l.getMeterAmount()).setScale(0,RoundingMode.HALF_UP));
+                l.setContractStatedMoney(l.getMeterMoney()
+                        .multiply(one.getClPrepaymentRatio())
+                        .multiply(new BigDecimal("0.01"))
+                        .setScale(0,RoundingMode.HALF_UP));
+            });
+            this.saveBatch(forms);
+            return R.data("成功新增" + forms.size() + "条数据");
+        }catch (Exception e){
+            if (e.getMessage().contains("java.time.LocalDate")){
+                throw new ServiceException("导入失败:" + "业务日期格式错误,正确格式:2024-01-10");
+            }else {
+                throw new ServiceException("导入失败:" + e.getMessage());
+            }
+        }
+
+    }
 }