소스 검색

08 17 update reportForm code

hr 4 년 전
부모
커밋
92da560ec6

+ 49 - 0
src/main/java/com/imed/costaccount/common/util/CommonUtil.java

@@ -0,0 +1,49 @@
+package com.imed.costaccount.common.util;
+
+/**
+ * 通用工具类
+ */
+public class CommonUtil {
+
+    /**
+     * 校验字符串中括号是否闭合'[']'('')''{''}'
+     *
+     * @param str
+     * @return
+     */
+    public static boolean whetherStringClose(String str) {
+        int parenthesesNums = 0;//小括号数量
+        int bracketsNums = 0;//中括号数量
+        int bracesNums = 0;//大括号数量
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (c == '{') {
+                bracesNums += 1;
+            }
+            if (c == '[') {
+                bracketsNums += 1;
+            }
+            if (c == '(') {
+                parenthesesNums += 1;
+            }
+            if (c == '}') {
+                bracesNums -= 1;
+            }
+            if (c == ']') {
+                bracketsNums -= 1;
+            }
+            if (c == ')') {
+                parenthesesNums -= 1;
+            }
+            if (parenthesesNums < 0 || bracesNums < 0 || bracketsNums < 0) {
+                break;
+            }
+        }
+        if (parenthesesNums != 0 || bracesNums != 0 || bracketsNums != 0) {
+            return false;
+        } else {
+            return true;
+        }
+
+    }
+}

+ 58 - 53
src/main/java/com/imed/costaccount/model/ReportForm.java

@@ -14,9 +14,9 @@ import lombok.experimental.Accessors;
 
 /**
  * 报表项目
- * 
+ *
  * @author huangrui
- * @email 
+ * @email
  * @date 2021-08-03 13:53:52
  */
 @Data
@@ -25,58 +25,63 @@ import lombok.experimental.Accessors;
 @NoArgsConstructor
 @TableName("cost_report_form")
 public class ReportForm implements Serializable {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	/**
-	 * 主键
-	 */
-	@TableId
-	private Long id;
-	/**
-	 * 报表项目编号一个医院中必须唯一
-	 */
-	private Integer num;
-	/**
-	 * 报表名称
-	 */
-	private String reportName;
-	/**
-	 * 父级id
-	 */
-	private Long parentId;
-	/**
-	 * 计算类型 0.不设置,1.对应会计科目,2.对应分摊层级,3.小计,4.计算公式
-	 */
-	private Integer calcType;
-	/**
-	 * 报表类型:0.损益表、1.完全成本法表、2.变动成本表、3.全院损益表、4.全成本报表
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 报表项目编号一个医院中同一个类型必须唯一
+     */
+    private Integer num;
+    /**
+     * 报表名称
+     */
+    private String reportName;
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 计算类型 0.不设置,1.对应会计科目,2.对应分摊层级,3.小计,4.计算公式,5.按责任中心
+     */
+    private Integer calcType;
+    /**
+     * 报表类型:0.损益表、1.完全成本法表、2.变动成本表、3.全院损益表、4.全成本报表
+     */
+    private Integer reportType;
+    /**
+     * 计算公式,当计算类型为计算公式的时候必传
+     */
+    private String calcFormula;
+    /**
+     * 排序字段
+     */
+    private Integer sort;
+    /**
+     * 比率基数,默认100%,后续再进行修改
+     */
+    private String ratioBase;
+    /**
+     * 医院id
+     */
+    private Long hospId;
 
-	 */
-	private Integer reportType;
-	/**
-	 * 计算公式,当计算类型为计算公式的时候必传
-	 */
-	private String calcFormula;
-	/**
-	 * 排序字段
-	 */
-	private Integer sort;
-	/**
-	 * 比率基数,默认100%,后续再进行修改
-	 */
-	private String ratioBase;
-	/**
-	 * 医院id
-	 */
-	private Long hospId;
-	/**
-	 * 创建时间
-	 */
-	private Long createTime;
-	/**
-	 * 删除时间
-	 */
-	@TableLogic(value = "0",delval = "UNIX_TIMESTAMP(NOW()) * 1000")
-	private Long deleteTime;
+    /**
+     * 旧id主键,暂时只在复制功能体现!!!
+     */
+    private Long oldId;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+    /**
+     * 删除时间
+     */
+    @TableLogic(value = "0", delval = "UNIX_TIMESTAMP(NOW()) * 1000")
+    private Long deleteTime;
 
 }

+ 20 - 0
src/main/java/com/imed/costaccount/model/dto/CopyReportDTO.java

@@ -0,0 +1,20 @@
+package com.imed.costaccount.model.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel("复制报表数据")
+public class CopyReportDTO {
+
+    @NotNull(message = "复制的报表类型不能为空")
+    @ApiModelProperty(name = "fromReportType",value = "复制的报表类型")
+    private Integer fromReportType;
+
+    @NotNull(message = "辅助到的报表类型不能为空")
+    @ApiModelProperty(name = "toReportType",value = "辅助到的报表类型")
+    private Integer toReportType;
+}

+ 8 - 0
src/main/java/com/imed/costaccount/service/ReportFormService.java

@@ -2,6 +2,7 @@ package com.imed.costaccount.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.imed.costaccount.model.User;
+import com.imed.costaccount.model.dto.CopyReportDTO;
 import com.imed.costaccount.model.dto.ReportFormEditDTO;
 import com.imed.costaccount.model.dto.ReportFormSaveDTO;
 import com.imed.costaccount.model.vo.ReportFormVO;
@@ -40,5 +41,12 @@ public interface ReportFormService extends IService<ReportForm> {
      */
     void updateReport(ReportFormEditDTO formEditDTO);
 
+    /**
+     * 辅助数据
+     * @param copyReportDTO {@link CopyReportDTO}
+     * @param hospId 医院id
+     */
+    void copyReport(CopyReportDTO copyReportDTO, Long hospId);
+
 }
 

+ 2 - 0
src/main/java/com/imed/costaccount/service/ReportRelationService.java

@@ -1,6 +1,7 @@
 package com.imed.costaccount.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.imed.costaccount.model.dto.CopyReportDTO;
 import com.imed.costaccount.model.dto.ReportRelationDTO;
 import com.imed.costaccount.model.vo.RelationVO;
 import com.imed.costaccount.model.ReportRelation;
@@ -48,5 +49,6 @@ public interface ReportRelationService extends IService<ReportRelation> {
      */
     void saveReportRelation(ReportRelationDTO reportRelationDTO, Long hospId);
 
+
 }
 

+ 130 - 42
src/main/java/com/imed/costaccount/service/impl/ReportFormServiceImpl.java

@@ -1,28 +1,31 @@
 package com.imed.costaccount.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ReUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.imed.costaccount.common.exception.CostException;
+import com.imed.costaccount.common.util.BeanUtil;
+import com.imed.costaccount.common.util.CommonUtil;
 import com.imed.costaccount.mapper.ReportFormMapper;
 import com.imed.costaccount.model.ReportForm;
 import com.imed.costaccount.model.User;
+import com.imed.costaccount.model.dto.CopyReportDTO;
 import com.imed.costaccount.model.dto.ReportFormEditDTO;
 import com.imed.costaccount.model.dto.ReportFormSaveDTO;
 import com.imed.costaccount.model.vo.RelationVO;
 import com.imed.costaccount.model.vo.ReportFormVO;
 import com.imed.costaccount.service.ReportFormService;
 import com.imed.costaccount.service.ReportRelationService;
-import com.imed.costaccount.common.util.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 import static com.imed.costaccount.common.constants.NumberConstant.THREE;
@@ -67,7 +70,6 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
         }).collect(Collectors.toList());
 
 
-
         List<ReportFormVO> roots = reportFormVOS.stream().filter(i -> i.getParentId() == 0L).collect(Collectors.toList());
         for (ReportFormVO root : roots) {
             List<ReportFormVO> children = root.getChildren();
@@ -85,29 +87,6 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
         return roots;
     }
 
-    /**
-     * 填充对应的关联关系
-     *
-     * @param reportFormVO {@link ReportFormVO}
-     * @param hospId
-     */
-    private void setRelation(ReportFormVO reportFormVO, Long hospId) {
-        Integer showAddRelation = reportFormVO.getShowAddRelation();
-        if (Objects.isNull(showAddRelation)) {
-            return;
-        }
-        if (showAddRelation == 1) {
-            List<RelationVO> list = reportRelationService.getAccountRelation(reportFormVO.getId(), hospId);
-            reportFormVO.setReportRelations(list);
-            return;
-        } else if (showAddRelation == 2) {
-            List<RelationVO> list = reportRelationService.getShareLevel(reportFormVO.getId(), hospId);
-            reportFormVO.setReportRelations(list);
-            return;
-        }
-
-    }
-
 
     /**
      * 新增一个报表项目
@@ -119,8 +98,7 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
     public void saveReport(ReportFormSaveDTO reportFormDTO, Long hospId) {
         ReportForm reportForm = BeanUtil.convertObj(reportFormDTO, ReportForm.class);
-        Integer num = this.createNum(hospId);
-        // TODO: 2021/8/4 控制唯一性
+        Integer num = this.createNum(hospId,reportFormDTO.getReportType());
         reportForm.setHospId(hospId)
                 .setNum(num)
                 .setCreateTime(System.currentTimeMillis());
@@ -134,12 +112,13 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
 
     /**
      * 根据是否父节点设置必要的数据
-     *    ***后台默认处理报表节点不一致的问题***
-     * @param hospId 医院id
+     * ***后台默认处理报表节点不一致的问题***
+     *
+     * @param hospId     医院id
      * @param reportForm 需要构建的实体
-     * @param parentId 父级id
+     * @param parentId   父级id
      */
-    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public void setDataByParentId(Long hospId, ReportForm reportForm, Long parentId) {
         if (parentId == 0L) {
             reportForm.setCalcType(0);
@@ -157,20 +136,69 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
         } else {
             // 父子节点报表类型必须一致
             ReportForm byId = this.getById(parentId);
-            checkExist(byId,"选择的父报表层级不正确");
+            checkExist(byId, "选择的父报表层级不正确");
             reportForm.setReportType(byId.getReportType());
             // 如果子节点 小计只能存在一个
             if (reportForm.getCalcType() == 3) {
                 this.isSubtotal(parentId, hospId);
             }
+            if (reportForm.getCalcType() == 4) {
+                // 校验计算公式合法性 [7]+[11]-[22]
+                this.checkCalcFormula(reportForm.getCalcFormula(),hospId,reportForm.getReportType());
+            }
         }
     }
 
+    /**
+     * 校验表达式中的内容是否存在
+     * @param calcFormula 表达式 [7]+[11]-[22]
+     */
+    private void checkCalcFormula(String calcFormula,Long hospId,Integer reportType) {
+        // 校验公式不存在单独的'[' 或 ']',中括号未闭合
+        boolean flag = CommonUtil.whetherStringClose(calcFormula);
+        if (!flag) {
+            throw new CostException("计算公式错误,英文中括号未正确闭合");
+        }
+        // 以下校验公式编号是否合法
+        Pattern pattern = Pattern.compile("(\\[[^\\]]*\\])");
+        Matcher m = pattern.matcher(calcFormula);
+        List<String> list = new ArrayList<>();
+        while (m.find()) {
+            if (StrUtil.isNotBlank(m.group())) {
+                list.add(m.group());
+            }
+        }
+        if (list.size() == 0) {
+            throw new CostException("计算公式错误,请使用英文输入状态下括号标识");
+        }
+        // 校验所有编号不是同一个
+        Set<String> set = new HashSet<>(list);
+        if (set.size() != list.size()) {
+            throw new CostException("公式中编号有重复");
+        }
+
+        // 校验编号是否存在
+        list.forEach(i -> {
+            String sub = StrUtil.sub(i, i.indexOf("[") + 1, i.lastIndexOf("]"));
+            ReportForm one = this.getOne(
+                    new LambdaQueryWrapper<ReportForm>().select(ReportForm::getId)
+                            .eq(ReportForm::getNum, sub)
+                            .eq(ReportForm::getHospId, hospId)
+                            .eq(ReportForm::getReportType, reportType)
+                            .last(LIMIT_ONE)
+            );
+            if (Objects.isNull(one)) {
+                throw new CostException("计算公式中编号不存在");
+            }
+        });
+    }
+
     /**
      * 子类型中小计计算类型只能存在一个
-     *    判断是否存在小计的计算类型,存在抛出异常
+     * 判断是否存在小计的计算类型,存在抛出异常
+     *
      * @param parentId 父级id
-     * @param hospId 医院id
+     * @param hospId   医院id
      */
     private void isSubtotal(Long parentId, Long hospId) {
         List<ReportForm> list = this.list(
@@ -187,12 +215,14 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
      * 创建最新的num 获取最大的num + 1
      *
      * @param hospId 医院id
+     * @param reportType 计算类型
      * @return 返回本医院最新编号
      */
-    private Integer createNum(Long hospId) {
+    private Integer createNum(Long hospId,Integer reportType) {
         ReportForm one = this.getOne(
                 new LambdaQueryWrapper<ReportForm>().select(ReportForm::getNum)
                         .eq(ReportForm::getHospId, hospId)
+                        .eq(ReportForm::getReportType,reportType)
                         .orderByDesc(ReportForm::getNum).last(LIMIT_ONE)
         );
         if (Objects.isNull(one)) {
@@ -211,7 +241,7 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
     public void updateReport(ReportFormEditDTO formEditDTO) {
         Long id = formEditDTO.getId();
         ReportForm byId = this.getById(id);
-        checkExist(byId,"选择的报表项目不存在");
+        checkExist(byId, "选择的报表项目不存在");
 
         BeanUtil.convertObj(formEditDTO, byId);
 
@@ -224,12 +254,70 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
 
     /**
      * 抛出异常
-     * @param byId POJO类
+     *
+     * @param byId     POJO类
      * @param errorMsg 抛出信息
      */
-    private void checkExist(ReportForm byId,String errorMsg) {
+    private void checkExist(ReportForm byId, String errorMsg) {
         if (Objects.isNull(byId)) {
             throw new CostException(errorMsg);
         }
     }
+
+    /**
+     * 辅助数据
+     *
+     * @param copyReportDTO {@link CopyReportDTO}
+     * @param hospId        医院id
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
+    public void copyReport(CopyReportDTO copyReportDTO, Long hospId) {
+        Integer toReportType = copyReportDTO.getToReportType();
+        Integer fromReportType = copyReportDTO.getFromReportType();
+        List<ReportForm> list = this.list(
+                new LambdaQueryWrapper<ReportForm>()
+                        .eq(ReportForm::getHospId, hospId)
+                        .eq(ReportForm::getReportType, fromReportType)
+        );
+        if (list.isEmpty()) {
+            throw new CostException("复制的报表类型下不存在数据");
+        }
+
+        // 删除掉需要复制到的数据
+        this.remove(new LambdaQueryWrapper<ReportForm>().eq(ReportForm::getHospId, hospId).eq(ReportForm::getReportType, toReportType));
+
+       // 先添加父层级数据
+       list.forEach(i -> {
+           if (i.getParentId() == 0) {
+               // 旧id
+               i.setOldId(i.getId());
+               i.setId(null);
+               i.setReportType(toReportType);
+               i.setCreateTime(System.currentTimeMillis());
+               // 父节点不存在计算公式问题
+               this.save(i);
+           }
+       });
+
+       // 处理子节点
+        List<ReportForm> childrenForms = list.stream().filter(i -> i.getParentId() != 0).collect(Collectors.toList());
+        List<ReportForm> newParentForms = this.list(
+                new LambdaQueryWrapper<ReportForm>()
+                        .select(ReportForm::getOldId)
+                        .eq(ReportForm::getHospId, hospId)
+                        .eq(ReportForm::getReportType, toReportType)
+        );
+        childrenForms.forEach(i -> {
+            newParentForms.forEach(j -> {
+                if (j.getOldId() != 0 && j.getOldId().equals(i.getParentId())) {
+                    i.setParentId(j.getId());
+                    i.setCreateTime(System.currentTimeMillis());
+                    i.setReportType(toReportType);
+                    this.save(i);
+                }
+            });
+        });
+
+    }
 }

+ 0 - 3
src/main/java/com/imed/costaccount/test.json

@@ -1,3 +0,0 @@
-{
-  ""
-}

+ 8 - 0
src/main/java/com/imed/costaccount/web/ReportFormController.java

@@ -2,6 +2,7 @@ package com.imed.costaccount.web;
 
 import com.imed.costaccount.common.util.PageUtils;
 import com.imed.costaccount.common.util.Result;
+import com.imed.costaccount.model.dto.CopyReportDTO;
 import com.imed.costaccount.model.dto.ReportFormEditDTO;
 import com.imed.costaccount.model.dto.ReportFormSaveDTO;
 import com.imed.costaccount.model.dto.ReportRelationDTO;
@@ -126,5 +127,12 @@ public class ReportFormController extends AbstractController {
         return Result.ok(list);
     }
 
+    @ApiOperation("复制数据")
+    @PostMapping("/copyReport")
+    public Result copyReport(@RequestBody @Valid CopyReportDTO copyReportDTO) {
+        reportFormService.copyReport(copyReportDTO, getHospId());
+        return Result.ok();
+    }
+
 
 }

+ 1 - 0
src/main/resources/mapper/ReportFormMapper.xml

@@ -15,6 +15,7 @@
         <result property="sort" column="sort"/>
         <result property="ratioBase" column="ratio_base"/>
         <result property="hospId" column="hosp_id"/>
+        <result property="oldId" column="old_id" />
         <result property="createTime" column="create_time"/>
         <result property="deleteTime" column="delete_time"/>
     </resultMap>