Răsfoiți Sursa

Merge remote-tracking branch 'originzkqy/master'

lucky 2 luni în urmă
părinte
comite
ed5ca6054e

+ 25 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/CommonBtnController.java

@@ -111,11 +111,36 @@ public class CommonBtnController extends BaseController {
                 return executeBtn(commonEntity, dragTableBtn);
             case "INITIATED":  // 发起流程
                 return initiatedBtn(commonEntity, dragTableBtn);
+            case "CALCULATE":
+                return calculateBtn(commonEntity, dragTableBtn);
             default:
                 return warn("暂不支持该操作!");
         }
     }
 
+    private AjaxResult calculateBtn(CommonEntity commonEntity, DragTableBtn dragTableBtn) {
+        //点击按钮触发的操作 visible状态用来区分是否是打开还是关闭状态
+        if (commonEntity.getBasicMap().get("visible").toString().equals("false") && dragTableBtn.getBtnFormType().equals("calculateForm")) {
+            Map<String, Object> map = new HashMap<>();
+            //查询动态表单信息
+            DragForm dragForm = dragFormService.selectDragFormByformKey(dragTableBtn.getBtnFormKey());
+            map.put("template", dragForm);
+            String dfVueTemplate = dragForm.getDfVueTemplate();
+            //先查出表单的数据
+            CommonEntity common = commonService.queryCommonByCalculateBtn(commonEntity, dfVueTemplate);
+            if (common == null){
+                return AjaxResult.btnMessage(-1);
+            }
+            map.put("result", common);
+            return success(map);
+        // 点击确认按钮时对数据不做处理
+        }else if (commonEntity.getBasicMap().get("visible").toString().equals("true")){
+            return AjaxResult.btnMessage(200);
+        }else{
+            return warn("暂不支持该操作!");
+        }
+    }
+
     /**
      * 新增类型按钮
      *

+ 21 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTreeController.java

@@ -1,6 +1,7 @@
 package com.zkqy.business.controller;
 
 import com.zkqy.business.entity.DragTree;
+import com.zkqy.business.entity.dto.DragTreeNodeDto;
 import com.zkqy.business.entity.vo.DragTreeVo;
 import com.zkqy.business.service.IDragTreeService;
 import com.zkqy.common.annotation.Anonymous;
@@ -51,6 +52,26 @@ public class DragTreeController extends BaseController
         return AjaxResult.success(list);
     }
 
+
+    //新增树节点
+    @PostMapping("/node/add")
+    public AjaxResult treeNodeAdd(@RequestBody DragTreeNodeDto treeNodeDto)
+    {
+        return toAjax(dragTreeService.treeNodeAdd(treeNodeDto));
+    }
+    //新增树节点
+    @PostMapping("/node/update")
+    public AjaxResult treeNodeupdate(@RequestBody DragTreeNodeDto treeNodeDto)
+    {
+        return toAjax(dragTreeService.treeNodeUpdate(treeNodeDto));
+    }
+    //删除
+    @PostMapping("/node/delete")
+    public AjaxResult treeNodeDelete(@RequestBody DragTreeNodeDto treeNodeDto)
+    {
+        return toAjax(dragTreeService.treeNodeDelete(treeNodeDto));
+    }
+
     /**
      * 导出拖拽树结构列表
      */

+ 9 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTree.java

@@ -20,6 +20,7 @@ public class DragTree extends BaseEntity
 
     private String  treeShowLabel;
     private String  treeTableJoinTableCondition;
+    private String  treeTableJoinTablePrimaryKey;
 
     /** 唯一标识符,自增主键 */
     private Long id;
@@ -257,4 +258,12 @@ public class DragTree extends BaseEntity
     public void setTreeTableJoinTableCondition(String treeTableJoinTableCondition) {
         this.treeTableJoinTableCondition = treeTableJoinTableCondition;
     }
+
+    public String getTreeTableJoinTablePrimaryKey() {
+        return treeTableJoinTablePrimaryKey;
+    }
+
+    public void setTreeTableJoinTablePrimaryKey(String treeTableJoinTablePrimaryKey) {
+        this.treeTableJoinTablePrimaryKey = treeTableJoinTablePrimaryKey;
+    }
 }

+ 90 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/dto/DragTreeNodeDto.java

@@ -0,0 +1,90 @@
+package com.zkqy.business.entity.dto;
+
+public class DragTreeNodeDto {
+    //树的表名
+    private String tableName;
+
+    //主键名
+    private String primaryName;
+
+    private String primaryValue;
+
+    //字段名
+    private String columnName;
+
+    //字段值
+    private String columnValue;
+
+    //指向上节点的字段名
+    private String parentName;
+
+    private String parentValue;
+
+    // 增加的层级,是本级还是下一级 cur next
+    private String addLevel;
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
+
+    public String getColumnName() {
+        return columnName;
+    }
+
+    public void setColumnName(String columnName) {
+        this.columnName = columnName;
+    }
+
+    public String getColumnValue() {
+        return columnValue;
+    }
+
+    public void setColumnValue(String columnValue) {
+        this.columnValue = columnValue;
+    }
+
+    public String getPrimaryName() {
+        return primaryName;
+    }
+
+    public void setPrimaryName(String primaryName) {
+        this.primaryName = primaryName;
+    }
+
+    public String getPrimaryValue() {
+        return primaryValue;
+    }
+
+    public void setPrimaryValue(String primaryValue) {
+        this.primaryValue = primaryValue;
+    }
+
+    public String getParentName() {
+        return parentName;
+    }
+
+    public void setParentName(String parentName) {
+        this.parentName = parentName;
+    }
+
+    public String getParentValue() {
+        return parentValue;
+    }
+
+    public void setParentValue(String parentValue) {
+        this.parentValue = parentValue;
+    }
+
+    public String getAddLevel() {
+        return addLevel;
+    }
+
+    public void setAddLevel(String addLevel) {
+        this.addLevel = addLevel;
+    }
+}

+ 13 - 0
zkqy-business/src/main/java/com/zkqy/business/mapper/DragTreeMapper.java

@@ -3,6 +3,7 @@ package com.zkqy.business.mapper;
 
 
 import com.zkqy.business.entity.DragTree;
+import com.zkqy.business.entity.dto.DragTreeNodeDto;
 import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
 import org.apache.ibatis.annotations.Param;
 
@@ -88,4 +89,16 @@ public interface DragTreeMapper
      * @return 结果
      */
     public int deleteDragTreeByIds(Long[] ids);
+
+    int insertTreeNodeCur(DragTreeNodeDto treeNodeDto);
+
+    int insertTreeNodeNext(DragTreeNodeDto treeNodeDto);
+
+    int updateTreeNode(DragTreeNodeDto treeNodeDto);
+
+    int deleteTreeNodeByIds(@Param("treeMapData") List<String> treeMapData, @Param("tableName") String tableName, @Param("primaryName") String primaryName);
+
+    List<Map<String, String>> selectTreeNodeList(@Param("tableName") String tableName);
+
+
 }

+ 7 - 0
zkqy-business/src/main/java/com/zkqy/business/service/IDragTreeService.java

@@ -3,6 +3,7 @@ package com.zkqy.business.service;
 
 
 import com.zkqy.business.entity.DragTree;
+import com.zkqy.business.entity.dto.DragTreeNodeDto;
 import com.zkqy.business.entity.vo.DragTreeVo;
 
 import java.util.List;
@@ -70,4 +71,10 @@ public interface IDragTreeService
      * @return
      */
     DragTreeVo recursionTree(String treeTableKey);
+
+    int treeNodeAdd(DragTreeNodeDto treeNodeDto);
+
+    int treeNodeUpdate(DragTreeNodeDto treeNodeDto);
+
+    int treeNodeDelete(DragTreeNodeDto treeNodeDto);
 }

+ 89 - 4
zkqy-business/src/main/java/com/zkqy/business/service/impl/DragTreeServiceImpl.java

@@ -3,6 +3,7 @@ package com.zkqy.business.service.impl;
 import com.alibaba.fastjson2.JSON;
 import com.fasterxml.jackson.databind.json.JsonMapper;
 import com.zkqy.business.entity.DragTree;
+import com.zkqy.business.entity.dto.DragTreeNodeDto;
 import com.zkqy.business.entity.vo.DragTreeVo;
 import com.zkqy.business.mapper.DragTreeMapper;
 import com.zkqy.business.service.IDragTreeService;
@@ -11,13 +12,12 @@ import com.zkqy.business.utils.TreeBuilder;
 import com.zkqy.common.exception.base.BaseException;
 import com.zkqy.common.utils.DateUtils;
 import com.zkqy.common.utils.SecurityUtils;
-import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import com.zkqy.common.utils.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 拖拽树结构Service业务层处理
@@ -114,7 +114,7 @@ public class DragTreeServiceImpl implements IDragTreeService
      */
     @Override
     public DragTreeVo recursionTree(String treeTableKey) {
-        treeTableKey="48e90c10-147f-4bfa-a1a0-f702ba93b5c8";
+//        treeTableKey="48e90c10-147f-4bfa-a1a0-f702ba93b5c8";
         // 首先通过tableKey查询模版数据
         DragTree dragTree = dragTreeMapper.selectDragTreeByTreeTableKey(treeTableKey);
         // 数据表名称 ammunition_plan_information_intermediate_table
@@ -123,6 +123,8 @@ public class DragTreeServiceImpl implements IDragTreeService
         String tableId = dragTree.getTreeTablePrimaryKey();
         // 递归列
         String treeTableDgl = dragTree.getTreeTableDgl();
+        // 下划线转驼峰
+        treeTableDgl = StringUtils.toCamelCase(treeTableDgl);
         // 展示字段(label)
         String treeShowLabel = dragTree.getTreeShowLabel();
         // 当前表字段的所有列名
@@ -159,4 +161,87 @@ public class DragTreeServiceImpl implements IDragTreeService
         //查询对应的表格信息
         return dragTreeVo;
     }
+
+    @Override
+    public int treeNodeAdd(DragTreeNodeDto treeNodeDto) {
+        Boolean legalParam = isLegalParam(treeNodeDto);
+        //增加情况额外判断
+        String parentValue = treeNodeDto.getParentValue();
+        String addLevel = treeNodeDto.getAddLevel();
+        if (legalParam.equals(false) || StringUtils.isBlank(parentValue) || StringUtils.isBlank(addLevel)){
+            return -1;
+        }
+        //当前层级添加
+        if (addLevel.equals("cur")){
+            return dragTreeMapper.insertTreeNodeCur(treeNodeDto);
+        //下一层级添加
+        }else if(addLevel.equals("next")){
+            return dragTreeMapper.insertTreeNodeNext(treeNodeDto);
+        }else{
+            return -1;
+        }
+    }
+
+    @Override
+    public int treeNodeUpdate(DragTreeNodeDto treeNodeDto) {
+        Boolean legalParam = isLegalParam(treeNodeDto);
+        if (legalParam.equals(false)){
+            return -1;
+        }
+        return dragTreeMapper.updateTreeNode(treeNodeDto);
+    }
+
+    @Override
+    public int treeNodeDelete(DragTreeNodeDto treeNodeDto) {
+        Boolean legalParam = isLegalParam(treeNodeDto);
+        if (legalParam.equals(false)){
+            return -1;
+        }
+        String tableName = treeNodeDto.getTableName();
+        String primaryValue = treeNodeDto.getPrimaryValue();
+        String primaryName = treeNodeDto.getPrimaryName();
+        String parentName = treeNodeDto.getParentName();
+        // 查询出所有的数据
+        List<Map<String, String>> mapList = dragTreeMapper.selectTreeNodeList(tableName);
+        //递归得到要删除的树形id集合
+        List<String> ids = new ArrayList<>();
+        // 下划线转驼峰
+        parentName = StringUtils.toCamelCase(parentName);
+        List<String> treeMapData = TreeBuilder.getTreeIdList(mapList,primaryValue,primaryName,parentName,ids);
+        // 删除这些id
+        return dragTreeMapper.deleteTreeNodeByIds(treeMapData,tableName,primaryName);
+    }
+
+    //参数校验
+    public Boolean isLegalParam(DragTreeNodeDto treeNodeDto){
+        if (treeNodeDto == null){
+            return false;
+        }
+        boolean a = StringUtils.isNotBlank(treeNodeDto.getTableName());
+        boolean a1 = StringUtils.isNotBlank(treeNodeDto.getPrimaryName());
+        boolean a2 = StringUtils.isNotBlank(treeNodeDto.getPrimaryValue());
+        boolean a3 = StringUtils.isNotBlank(treeNodeDto.getColumnName());
+        boolean a4 = StringUtils.isNotBlank(treeNodeDto.getColumnValue());
+        boolean a5 = StringUtils.isNotBlank(treeNodeDto.getParentName());
+        if (a && a1 && a2 && a3 && a4 && a5){
+            return true;
+        }
+        return false;
+    }
+    public static void main(String[] args) {
+        String s = "parentId";
+        String s1 = "asdsadas";
+        String s2 = "   ";
+        String s3 = "asd_asdd_as";
+        String s4 = StringUtils.toCamelCase(s3);
+        String s5 = StringUtils.toCamelCase(s);
+        String s6 = StringUtils.toCamelCase(s1);
+        String s7 = StringUtils.toCamelCase(s2);
+        System.out.println(s4);
+        System.out.println(s5);
+        System.out.println(s6);
+        System.out.println(s7);
+    }
+
+
 }

+ 24 - 4
zkqy-business/src/main/java/com/zkqy/business/utils/TreeBuilder.java

@@ -28,6 +28,24 @@ public class TreeBuilder {
                 .collect(Collectors.toList());
     }
 
+    // 递归的找到所有本节点和子节点的id
+    public static List<String> getTreeIdList(List<Map<String, String>> allNodes, String parentId,String tableId,String treeTableDgl,List<String> resIds) {
+        resIds.add(parentId);
+         allNodes.stream()
+                .filter(node ->Objects.equals(convertToString(parentId), convertToString(node.get(treeTableDgl))))
+                .map(parentNode -> {
+                    // 确保 tableId 对应的值被正确地转换为字符串
+                    Object tableIdObj = parentNode.get(tableId);
+                    String tableIdStr = convertToString(tableIdObj);
+                    System.out.println(tableIdStr);
+                    getTreeIdList(allNodes, tableIdStr, tableId,treeTableDgl,resIds);
+                    return parentNode;
+                })
+                .collect(Collectors.toList());
+        List<String> resIdList = resIds.stream().distinct().collect(Collectors.toList());
+        return resIdList;
+    }
+
     private static String convertToString(Object obj) {
         if (obj instanceof Integer) {
             return ((Integer) obj).toString();
@@ -48,7 +66,7 @@ public class TreeBuilder {
                 new HashMap<String, String>() {{
                     put("id", "1");
                     put("name", "根节点");
-                    put("parentId", null); // 根节点
+                    put("parentId", "0"); // 根节点
                 }},
                 new HashMap<String, String>() {{
                     put("id", "2");
@@ -67,9 +85,11 @@ public class TreeBuilder {
                 }});
 
         // 构建树形结构
-        List<Map<String, ?>> tree = buildTree(mapList, null,"id","parentId");
-        String jsonString = JSON.toJSONString(tree);
-        System.out.println(jsonString);
+        ArrayList<String> strings = new ArrayList<>();
+        List<String> treeIdList = getTreeIdList(mapList, "2", "id", "parentId", strings);
+//        List<Map<String, ?>> tree = buildTree(mapList, "1","id","parentId");
+//        String jsonString = JSON.toJSONString(tree);
+//        System.out.println(jsonString);
         // 打印结果
 //        printTree(tree);
     }

+ 37 - 5
zkqy-business/src/main/resources/mapper/dragmapper/DragTreeMapper.xml

@@ -27,10 +27,11 @@
         <result property="treeTableKey" column="tree_table_key"/>
         <result property="treeShowLabel" column="tree_show_label"/>
         <result property="treeTableJoinTableCondition" column="tree_table_join_table_condition"/>
+        <result property="treeTableJoinTablePrimaryKey" column="tree_table_join_table_primary_key"/>
     </resultMap>
 
     <sql id="selectDragTreeVo">
-        select id, menu_id, menu_name, tree_desc, tree_table_name, tree_table_primary_key, tree_table_dgl, tree_table_condition, tree_table_join_table, table_name_des, del_flag, create_by, create_by_id, create_time, update_by, update_by_id, update_time,table_id,tree_table_key,tree_show_label,tree_table_join_table_condition from {DBNAME}.drag_tree
+        select id, menu_id, menu_name, tree_desc, tree_table_name, tree_table_primary_key, tree_table_dgl, tree_table_condition, tree_table_join_table, table_name_des, del_flag, create_by, create_by_id, create_time, update_by, update_by_id, update_time,table_id,tree_table_key,tree_show_label,tree_table_join_table_condition,tree_table_join_table_primary_key from {DBNAME}.drag_tree
     </sql>
 
     <select id="selectDragTreeList" parameterType="com.zkqy.business.entity.DragTree" resultMap="DragTreeResult">
@@ -49,6 +50,9 @@
             <if test="updateById != null "> and update_by_id = #{updateById}</if>
             <if test="tableId != null">and table_id=#{tableId},</if>
             <if test="treeTableKey!=null">and tree_table_key=#{treeTableKey}</if>
+            <if test="treeShowLabel!=null">and tree_show_label=#{treeShowLabel}</if>
+            <if test="treeTableJoinTableCondition!=null">and tree_table_join_table_condition=#{treeTableJoinTableCondition}</if>
+            <if test="treeTableJoinTablePrimaryKey!=null">and tree_table_join_table_primary_key=#{treeTableJoinTablePrimaryKey}</if>
         </where>
     </select>
 
@@ -74,8 +78,10 @@
         WHERE TABLE_SCHEMA = #{dbname}
           AND TABLE_NAME = #{tableName}
     </select>
-
-
+    <select id="selectTreeNodeList" resultType="java.util.Map">
+        select *
+        from {DBNAME}.${tableName}
+    </select>
 
 
     <insert id="insertDragTree" parameterType="com.zkqy.business.entity.DragTree" useGeneratedKeys="true" keyProperty="id">
@@ -99,6 +105,9 @@
             <if test="updateTime != null">update_time,</if>
             <if test="tableId != null">table_id,</if>
             <if test="treeTableKey!=null">tree_table_key,</if>
+            <if test="treeShowLabel!=null">tree_show_label,</if>
+            <if test="treeTableJoinTableCondition!=null">tree_table_join_table_condition,</if>
+            <if test="treeTableJoinTablePrimaryKey!=null">tree_table_join_table_primary_key,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="menuId != null">#{menuId},</if>
@@ -118,9 +127,23 @@
             <if test="updateById != null">#{updateById},</if>
             <if test="updateTime != null">#{updateTime},</if>
             <if test="tableId != null">#{tableId},</if>
-            <if test="treeTableKey!=null">#{treeTableKey}</if>
+            <if test="treeTableKey!=null">#{treeTableKey},</if>
+            <if test="treeShowLabel!=null">#{treeShowLabel},</if>
+            <if test="treeTableJoinTableCondition!=null">#{treeTableJoinTableCondition},</if>
+            <if test="treeTableJoinTablePrimaryKey!=null">#{treeTableJoinTablePrimaryKey},</if>
         </trim>
     </insert>
+    <insert id="insertTreeNodeCur" parameterType="com.zkqy.business.entity.dto.DragTreeNodeDto">
+        insert into {DBNAME}.${tableName} (${columnName},${parentName}) values(#{columnValue},#{parentValue})
+    </insert>
+    <insert id="insertTreeNodeNext" parameterType="com.zkqy.business.entity.dto.DragTreeNodeDto">
+        insert into {DBNAME}.${tableName} (${columnName},${parentName}) values(#{columnValue},#{primaryValue})
+    </insert>
+    <update id="updateTreeNode">
+        update {DBNAME}.${tableName}
+        set ${columnName} = #{columnValue}
+        where ${primaryName} = #{primaryValue}
+    </update>
 
     <update id="updateDragTree" parameterType="com.zkqy.business.entity.DragTree">
         update {DBNAME}.drag_tree
@@ -142,7 +165,10 @@
             <if test="updateById != null">update_by_id = #{updateById},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="tableId != null">table_id=#{tableId},</if>
-            <if test="treeTableKey!=null">tree_table_key=#{treeTableKey}</if>
+            <if test="treeTableKey!=null">tree_table_key=#{treeTableKey},</if>
+            <if test="treeShowLabel!=null">tree_show_label=#{treeShowLabel}</if>
+            <if test="treeTableJoinTableCondition!=null">tree_table_join_table_condition=#{treeTableJoinTableCondition},</if>
+            <if test="treeTableJoinTablePrimaryKey!=null">tree_table_join_table_primary_key=#{treeTableJoinTablePrimaryKey},</if>
         </trim>
         where id = #{id}
     </update>
@@ -157,5 +183,11 @@
             #{id}
         </foreach>
     </delete>
+    <delete id="deleteTreeNodeByIds">
+        delete from {DBNAME}.${tableName} where ${primaryName} in
+        <foreach item="id" collection="treeMapData" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
 
 </mapper>

+ 10 - 0
zkqy-process-execution/src/main/java/com/zkqy/execution/produce/dispersed/entity/CommonEntity.java

@@ -59,6 +59,9 @@ public class CommonEntity extends BaseEntity implements Serializable,Cloneable {
      */
     private Map<String, Object> btnParametersMap;
 
+    // 计算表单的结果返回存放位置
+    private Map<String,Object> calculateResultMap;
+
     public List<Map<String, String>> getAddListMap() {
         return addListMap;
     }
@@ -166,6 +169,13 @@ public class CommonEntity extends BaseEntity implements Serializable,Cloneable {
         this.execlMap = execlMap;
     }
 
+    public Map<String, Object> getCalculateResultMap() {
+        return calculateResultMap;
+    }
+
+    public void setCalculateResultMap(Map<String, Object> calculateResultMap) {
+        this.calculateResultMap = calculateResultMap;
+    }
 }
 /*
 

+ 1 - 1
zkqy-process-execution/src/main/java/com/zkqy/execution/produce/dispersed/service/ICommonService.java

@@ -98,5 +98,5 @@ public interface ICommonService {
      */
     CommonEntity queryDropDownBoxData(List<CommonEntity> commonEntityList);
 
-
+    CommonEntity queryCommonByCalculateBtn(CommonEntity commonEntity, String dfVueTemplate);
 }

+ 135 - 11
zkqy-process-execution/src/main/java/com/zkqy/execution/produce/dispersed/service/impl/CommonServiceImpl.java

@@ -25,10 +25,14 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static com.zkqy.common.utils.StringUtils.*;
 
@@ -355,19 +359,9 @@ public class CommonServiceImpl implements ICommonService {
         // 可能会存在多个时间范围的查询,根据查询字段名称做筛选条件
         Map<String, Object> timeMap = JSONObject.parseObject(queryMap.get("timehorizon") != null ? queryMap.get("timehorizon").toString() : String.valueOf(new HashMap<String, Object>()));
 
-
         String beginTimeSql = " AND date_format(#{field},'%Y%m%d%H%i%s') >= date_format('#{beginTime}','%Y%m%d%H%i%s')";
         String endTimeSql = " AND date_format(#{field},'%Y%m%d%H%i%s') <= date_format('#{endTime}','%Y%m%d%H%i%s')";
 
-
-        //		<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
-        //			AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
-        //		</if>
-        //		<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
-        //			AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
-        //		</if>
-
-
         //  处理时间sql拼接
         timeMap.keySet().forEach(item -> {
             Map<String, Object> endtime = (Map) timeMap.get(item);
@@ -517,7 +511,90 @@ public class CommonServiceImpl implements ICommonService {
         return commonEntity;
     }
 
-    public static String extractSubstring(String input, String identifier) {
+    @Override
+    public CommonEntity queryCommonByCalculateBtn(CommonEntity commonEntity, String dfVueTemplate) {
+        //分析模板数据
+        JSONObject options = new JSONObject();
+        List<Map> columnList = new ArrayList<>();
+        try {
+            JSONObject dfVtemplateJson = JSONObject.parseObject(dfVueTemplate);
+            options = dfVtemplateJson
+                    .getJSONArray("list")
+                    .getJSONObject(0)
+                    .getJSONObject("options");
+            JSONArray tableColumns = options
+                    .getJSONArray("tableColumns");
+            columnList = tableColumns.toJavaList(Map.class);
+        }catch (NullPointerException e){
+            e.printStackTrace();
+            return null;
+        }
+        // 得到需要查询的结果列
+        List<String> columns = columnList.stream()
+                .filter(map -> (map.get("type") != null && !map.get("type").equals("result")) || (map.get("type") == null))
+                .flatMap(map -> {
+                    Object prop = map.get("prop");
+                    return prop != null ? Stream.of(prop.toString()) : Stream.empty();
+                })
+                .collect(Collectors.toList());
+        //构建得到sql所需要的查询列
+        String queryColumn = "";
+        for (int i = 0; i < columns.size(); i++) {
+            queryColumn += columns.get(i);
+            if (i != columns.size()-1){
+                queryColumn += ",";
+            }
+        }
+        //动态构建sql语句 得到查询结果
+        String mainTableName = options.getString("tableName");
+        String mainTableCondition = options.getString("mainTableCondition");
+        String joinTableCondition = options.getString("joinTableCondition");
+        // 判空
+        if (StringUtils.isBlank(mainTableName) || StringUtils.isBlank(mainTableCondition) || StringUtils.isBlank(joinTableCondition)){
+            return null;
+        }
+        CommonEntity infoById = getInfoById(commonEntity);
+        String joinTableConditionValue = infoById.getResultMap().get(joinTableCondition).toString();
+        String sql = "select " + queryColumn + " from {DBNAME}." + mainTableName + " where " + mainTableCondition + "= " + joinTableConditionValue;
+        //这里查询到的是驼峰的k-v,需要整体数组拷贝成下划线的,方便展示
+        List<Map<String, Object>> maps = commonMapper.executeSqlSelectData(sql);
+        List<Map<String, Object>> mapsUnderLine = copyListMapWithCamelToUnderline(maps);
+        //得到需要手动计算的特殊列名
+        List<String> columnsNeedHandle = columnList.stream()
+                .filter(map -> (map.get("type") != null && map.get("type").equals("result")))
+                .flatMap(map -> {
+                    Object prop = map.get("prop");
+                    return prop != null ? Stream.of(prop.toString()) : Stream.empty();
+                })
+                .collect(Collectors.toList());
+        //为每一行的返回结果加上手动计算列,根据数据库查询出来的数据二次计算
+        for (Map<String, Object> map : mapsUnderLine) {
+            for (String column : columnsNeedHandle) {
+                map.put(column,calculate(column,map));
+            }
+        }
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("tableColumn",columnList);
+        map.put("tableValue",mapsUnderLine);
+        // 计算公式类型返回
+        map.put("formula",options.get("formula"));
+        map.put("showSummary",options.get("showSummary"));
+        infoById.setCalculateResultMap(map);
+        return infoById;
+    }
+
+    // 复制集合,将驼峰转换成下划线
+    private List<Map<String, Object>> copyListMapWithCamelToUnderline(List<Map<String, Object>> maps) {
+        List<Map<String, Object>> resMap = new ArrayList<>();
+        for (Map<String, Object> map : maps) {
+            HashMap<String, Object> tempMap = new HashMap<>();
+            map.forEach((s, o) -> tempMap.put(StringUtils.toUnderScoreCase(s),o));
+            resMap.add(tempMap);
+        }
+        return resMap;
+    }
+
+    public String extractSubstring(String input, String identifier) {
         int startIndex = input.indexOf(identifier);
         if (startIndex == -1) {
             return null; // 如果找不到指定的标识符,则返回空
@@ -530,6 +607,53 @@ public class CommonServiceImpl implements ICommonService {
         String sqlColumn = input.substring(startIndex + identifier.length() + 1, endIndex);
         return convertToCamelCase(sqlColumn);
     }
+
+    // 目前只支持两列的加减乘除,后续如果需要支持多列待补充
+    public static Object calculate(String columns, Map<String, Object> resMap) {
+        try {
+            if (columns.contains("~+~")) {
+                String[] split = columns.split("~\\+~");
+                BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
+                BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
+                return roundToTwoDecimalPlaces(one.add(two));
+            } else if (columns.contains("~-~")) {
+                String[] split = columns.split("~-~");
+                BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
+                BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
+                return roundToTwoDecimalPlaces(one.subtract(two));
+            } else if (columns.contains("~*~")) {
+                String[] split = columns.split("~\\*~");
+                BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
+                BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
+                return roundToTwoDecimalPlaces(one.multiply(two));
+            } else if (columns.contains("~/~")) {
+                String[] split = columns.split("~/~");
+                BigDecimal one = getBigDecimalFromMap(resMap, split[0]);
+                BigDecimal two = getBigDecimalFromMap(resMap, split[1]);
+                if (two.compareTo(BigDecimal.ZERO) == 0) {
+                    return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); // 除数为零时返回 0.00
+                }
+                return roundToTwoDecimalPlaces(one.divide(two, RoundingMode.HALF_UP));
+            } else {
+                throw new IllegalArgumentException("无效的表达式");
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException("计算失败: " + e.getMessage());
+        }
+    }
+
+    private static BigDecimal getBigDecimalFromMap(Map<String, Object> resMap, String key) {
+        Object value = resMap.getOrDefault(key, BigDecimal.ZERO);
+        if (value instanceof Number) {
+            return new BigDecimal(value.toString()); // 将 Number 转换为 BigDecimal
+        } else {
+            throw new IllegalArgumentException("值不是数字类型: " + key);
+        }
+    }
+
+    private static BigDecimal roundToTwoDecimalPlaces(BigDecimal number) {
+        return number.setScale(2, RoundingMode.HALF_UP); // 保留两位小数,四舍五入
+    }
 }
 
 /*

+ 69 - 2
zkqy-ui/src/assets/js/kFormDesign.js

@@ -1,3 +1,5 @@
+
+
 let tempData = [
   {
     "title": "基础组件",
@@ -431,7 +433,6 @@ let tempData = [
           "disabled": false,
           "hidden": false,
           "showLabel": false,
-          "hideSequence": false,
           "width": "100%"
         },
         "rules": [
@@ -468,6 +469,12 @@ let tempData = [
         ],
         "model": "",
         "key": "",
+        "rules": [
+          {
+            "required": false,
+            "message": "必填项"
+          }
+        ]
       },
       {
         "type": "selectInputList",
@@ -569,7 +576,7 @@ let tempData = [
         "icon": "icon-fengexian",
         "options": {
           "orientation": "left",
-          "noFormItem": true
+          "noFormItem": true,
         },
         "key": "",
         "model": ""
@@ -679,6 +686,66 @@ let tempData = [
         "model": ""
       }
     ]
+  },
+  {
+    "title": "自定义组件",
+    "list": [
+      {
+        "type": "calculation_table",
+        "label": "计算表格",
+        "icon": "icon-table",
+        // "component":Tabulation,
+        "options": {
+          "disabled": false,
+          "showSummary":false,
+          "showAddButton":true,
+          "formula":'sum',
+          "tableColor": "#fafafa",
+          "tableTextColor": "#000",
+          "jsTableFlag":true,
+          // 表关联
+          "mainTableCondition":'',
+          // 条件表字段
+          "joinTableCondition":'',
+
+          // "jsTableValue":'',
+          // "tjbzdTableValue":'',
+          "eventAttribute":true,
+          "eventAttributeList":[
+            {
+              "leftProp": "",
+              "rightProp": "",
+              "symbol":"",
+              "result":''
+            }
+          ],
+          "tableColumns": [
+            {
+              "prop": "",
+              "label": "",
+              "type":"",
+              "list": []
+            },
+            {
+              "prop": "",
+              "label": "",
+              "type":"",
+              "list": []
+            }
+          ],
+          
+        },
+        "tableData": [
+          // {
+          //   // "name": "",
+          // }
+        ],
+        
+        "key": "",
+        "model": ""
+      },
+     
+    ]
   }
 ]
 export default tempData

+ 0 - 17
zkqy-ui/src/views/tablelist/commonTable/BtnMenu.vue

@@ -7,22 +7,11 @@
           :icon="btnObj.btnIcon"
           type="warning"
           ><span>
-            <!-- <svg-icon
-              class="pre-icon"
-              v-if="btnObj.btnIcon"
-              slot="prefix"
-              :icon-class="btnObj.btnIcon" /> -->
             {{ btnObj.btnName }}
             <i class="el-icon-arrow-down el-icon--right"></i></span
         ></el-button>
         <el-button :icon="btnObj.btnIcon" v-else>
           <span>
-            <!-- <svg-icon
-              class="pre-icon"
-              v-if="btnObj.btnIcon"
-              slot="prefix"
-              v-hasPermi="[btnObj.btnHasPermi]"
-              :icon-class="btnObj.btnIcon" /> -->
             {{ btnObj.btnName }}
             <i class="el-icon-arrow-down el-icon--right"></i
           ></span>
@@ -39,12 +28,6 @@
               :icon="item.btnIcon"
             >
               <span>
-                <!-- <svg-icon
-                  v-if="item.btnIcon"
-                  class="pre-icon"
-                  slot="prefix"
-                  :icon-class="item.btnIcon"
-                /> -->
                 {{ item.btnName }}</span
               >
             </el-button>

+ 239 - 332
zkqy-ui/src/views/tablelist/commonTable/listInfo.vue

@@ -1,34 +1,16 @@
 <template>
   <el-card shadow="always" :body-style="{ padding: '10px' }">
     <div class="app-container">
-      <el-dialog
-        :title="upload.title"
-        :visible.sync="upload.open"
-        width="400px"
-        append-to-body
-      >
-        <el-upload
-          ref="upload"
-          :limit="1"
-          accept=".xlsx, .xls"
-          :headers="upload.headers"
-          :action="
-            upload.url +
-            '?updateSupport=' +
-            upload.updateSupport +
-            '&tableName=' +
-            tableName +
-            '&sqlKey=' +
-            tableKey
-          "
-          v-loading="upload.isUploading"
-          :disabled="upload.isUploading"
-          :on-progress="handleFileUploadProgress"
-          :on-success="handleFileSuccess"
-          :auto-upload="false"
-          :onChange="handleChange"
-          drag
-        >
+      <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+        <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url +
+    '?updateSupport=' +
+    upload.updateSupport +
+    '&tableName=' +
+    tableName +
+    '&sqlKey=' +
+    tableKey
+    " v-loading="upload.isUploading" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
+          :on-success="handleFileSuccess" :auto-upload="false" :onChange="handleChange" drag>
           <i class="el-icon-upload"></i>
           <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
           <div class="el-upload__tip text-center" slot="tip">
@@ -37,12 +19,8 @@
             <!--            是否更新已经存在的用户数据-->
             <!--          </div>-->
             <span>仅允许导入xls、xlsx格式文件。</span>
-            <el-link
-              type="primary"
-              :underline="false"
-              style="font-size: 12px; vertical-align: baseline"
-              @click="importTemplate"
-              >下载模板
+            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
+              @click="importTemplate">下载模板
             </el-link>
           </div>
         </el-upload>
@@ -51,110 +29,51 @@
           <el-button @click="upload.open = false">取 消</el-button>
         </div>
       </el-dialog>
-      <Queryfrom
-        v-if="QueryfromLoading"
-        :formVals="templateInfo.where"
-        :statisticList="statisticList"
-        :showCount="showCount"
-        :showSearch="showSearch"
-        @getList="getList"
-        ref="mychild"
-      />
+      <Queryfrom v-if="QueryfromLoading" :formVals="templateInfo.where" :statisticList="statisticList"
+        :showCount="showCount" :showSearch="showSearch" @getList="getList" ref="mychild" />
       <el-row :gutter="10" class="mb8">
         <!-- 按钮行 start -->
-        <btn-menu-list
-          @topBtnHandler="topBtnHandler"
-          :topBtnArr="topBtnArr"
-          :selection="selection"
-        ></btn-menu-list>
-        <right-toolbar
-          :showCount.sync="showCount"
-          :showSearch.sync="showSearch"
-          :counts="true"
-          @queryTable="pageList"
-        ></right-toolbar>
+        <btn-menu-list @topBtnHandler="topBtnHandler" :topBtnArr="topBtnArr" :selection="selection"></btn-menu-list>
+        <right-toolbar :showCount.sync="showCount" :showSearch.sync="showSearch" :counts="true"
+          @queryTable="pageList"></right-toolbar>
       </el-row>
-      <el-table
-        v-loading="loading"
-        :data="tableList"
-        @selection-change="handleSelectionChange"
-        ref="tableRef"
-        :cell-style="cellStyle"
-        :reserve-selection="true"
-        :row-key="getRowKey"
-      >
-        <el-table-column
-          type="selection"
-          width="55"
-          reserve-selection
-          align="center"
-        >
+      <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange" ref="tableRef"
+        :cell-style="cellStyle" :reserve-selection="true" :row-key="getRowKey">
+        <el-table-column type="selection" width="55" reserve-selection align="center">
         </el-table-column>
-        <el-table-column
-          v-for="item in columns"
-          :key="item.key"
-          :label="item.value"
-          align="center"
-          :prop="item.key"
-        >
+        <el-table-column v-for="item in columns" :key="item.key" :label="item.value" align="center" :prop="item.key">
           <template slot-scope="scope">
             <!-- 存在字段样式或字典样式 -->
-            <template
-              v-if="
-                scope.row.styleFieldObj != undefined &&
-                scope.row.styleFieldObj[item.key]
-              "
-            >
+            <template v-if="scope.row.styleFieldObj != undefined &&
+    scope.row.styleFieldObj[item.key]
+    ">
               <!-- 字段样式 -->
               <template v-if="scope.row.styleFieldObj[item.key].styleType == 1">
                 <!-- 一般字体样式 -->
-                <template
-                  v-if="scope.row.styleFieldObj[item.key].fieldStyleType == 0"
-                >
-                  <span
-                    :style="`color:${
-                      scope.row.styleFieldObj[item.key].fontColor
-                    }`"
-                    >{{ scope.row[item.key] }}</span
-                  >
+                <template v-if="scope.row.styleFieldObj[item.key].fieldStyleType == 0">
+                  <span :style="`color:${scope.row.styleFieldObj[item.key].fontColor
+    }`">{{ scope.row[item.key] }}</span>
                 </template>
                 <!-- 标签字体样式 -->
-                <template
-                  v-else-if="
-                    scope.row.styleFieldObj[item.key].fieldStyleType == 1
-                  "
-                >
-                  <el-tag
-                    :type="scope.row.styleFieldObj[item.key].tagType"
-                    :effect="
-                      scope.row.styleFieldObj[item.key].isTagFullBg
-                        ? 'dark'
-                        : 'light'
-                    "
-                  >
+                <template v-else-if="scope.row.styleFieldObj[item.key].fieldStyleType == 1
+    ">
+                  <el-tag :type="scope.row.styleFieldObj[item.key].tagType" :effect="scope.row.styleFieldObj[item.key].isTagFullBg
+    ? 'dark'
+    : 'light'
+    ">
                     {{ scope.row[item.key] }}
                   </el-tag>
                 </template>
               </template>
               <!-- 字典样式 -->
-              <template
-                v-else-if="scope.row.styleFieldObj[item.key].styleType == 2"
-              >
-                <span
-                  v-if="
-                    scope.row.styleFieldObj[item.key].listClass == '' ||
-                    scope.row.styleFieldObj[item.key].listClass == 'default'
-                  "
-                  >{{ scope.row.styleFieldObj[item.key].dictLabel }}</span
-                >
-                <el-tag
-                  v-else
-                  :type="
-                    scope.row.styleFieldObj[item.key].listClass == 'primary'
-                      ? ''
-                      : scope.row.styleFieldObj[item.key].listClass
-                  "
-                  >{{ scope.row.styleFieldObj[item.key].dictLabel }}
+              <template v-else-if="scope.row.styleFieldObj[item.key].styleType == 2">
+                <span v-if="scope.row.styleFieldObj[item.key].listClass == '' ||
+    scope.row.styleFieldObj[item.key].listClass == 'default'
+    ">{{ scope.row.styleFieldObj[item.key].dictLabel }}</span>
+                <el-tag v-else :type="scope.row.styleFieldObj[item.key].listClass == 'primary'
+    ? ''
+    : scope.row.styleFieldObj[item.key].listClass
+    ">{{ scope.row.styleFieldObj[item.key].dictLabel }}
                 </el-tag>
               </template>
             </template>
@@ -164,93 +83,57 @@
             </template>
           </template>
         </el-table-column>
-        <el-table-column
-          v-if="isShowExcuteCol"
-          label="操作"
-          align="center"
-          class-name="small-padding fixed-width"
-        >
+        <el-table-column v-if="isShowExcuteCol" label="操作" align="center" class-name="small-padding fixed-width">
           <template slot-scope="scope">
-            <Menu
-              :row="scope.row"
-              v-for="btnObj in excuteBtnArr"
-              :key="btnObj.id"
-              :listAll="btnObj"
-              @excuteHandler="excuteHandler"
-            ></Menu>
+            <Menu :row="scope.row" v-for="btnObj in excuteBtnArr" :key="btnObj.id" :listAll="btnObj"
+              @excuteHandler="excuteHandler"></Menu>
           </template>
         </el-table-column>
       </el-table>
-      <pagination
-        v-show="total > 0"
-        :total="total"
-        :page.sync="queryParams.pageNum"
-        :limit.sync="queryParams.pageSize"
-        @pagination="pageList"
-      />
+      <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+        @pagination="pageList" />
       <!-- 添加或修改 -->
       <el-dialog :title="title" :visible.sync="open" append-to-body>
         <!-- <template v-else> -->
-        <div
-          v-show="formType == 'dragFormGroup' && !formListShow"
-          class="dialog_loading"
-        >
+        <div v-show="formType == 'dragFormGroup' && !formListShow" class="dialog_loading">
           <i class="el-icon-loading"></i>
         </div>
         <template>
-          <!-- :style="{ opacity: formListShow ? 1 : 0 }" -->
-          <FormList
-            v-show="formType == 'dragFormGroup' && formListShow && !isLayout"
-            ref="formGroupRef"
-            :formList="formList"
-          ></FormList>
-          <LayoutIndex
-            v-show="formType == 'dragFormGroup' && formListShow && isLayout"
-            ref="formGroupLayoutRef"
-            :layoutData="layoutData"
-          ></LayoutIndex>
-          <!-- <div v-show="times" class="times">
-            <i class="el-icon-loading" style="font-size: 30px"></i>
-          </div> -->
-          <!-- <el-button @click="showValue">test</el-button> -->
+          <FormList v-show="formType == 'dragFormGroup' && formListShow && !isLayout" ref="formGroupRef"
+            :formList="formList"></FormList>
+          <LayoutIndex v-show="formType == 'dragFormGroup' && formListShow && isLayout" ref="formGroupLayoutRef"
+            :layoutData="layoutData"></LayoutIndex>
         </template>
         <template>
-          <k-form-build
-            v-if="jsonData && formType == 'dragForm'"
-            class="formBuild"
-            ref="addFromRef"
-            :dynamicData="dynamicData"
-            :defaultValue="defaultValue"
-            @submit="tempSubBtn"
-            @change="formChangeHandler"
-            :value="jsonData"
-            :tableData="tableTempList"
-          />
+          <k-form-build v-if="jsonData && formType == 'dragForm'" class="formBuild" ref="addFromRef"
+            :dynamicData="dynamicData" :defaultValue="defaultValue" @submit="tempSubBtn" @change="formChangeHandler"
+            :value="jsonData" :tableData="tableTempList" />
         </template>
-
-        <div slot="footer" class="dialog-footer">
-          <el-button type="primary" @click="editConfirmHandler"
-            >确 定
+        <template>
+          <el-table v-if="jsonData && formType == 'calculateForm'" :data="calculateTableData" style="width: 100%"
+            :show-summary="showSummary" :summary-method="getformula">
+            <!-- 固定序号列 -->
+            <el-table-column label="序号" width="80" header-align="center" align="center">
+              <template #default="{ $index }">
+                {{ $index + 1 }}
+              </template>
+            </el-table-column>
+            <el-table-column v-for="(item, index) in calculateTableColumn" :key="index" :prop="item.prop"
+              :label="item.label" header-align="center" align="center">
+            </el-table-column>
+          </el-table>
+        </template>
+        <div slot="footer" class="dialog-footer" v-if="jsonData && formType !== 'calculateForm'">
+          <el-button type="primary" @click="editConfirmHandler">确 定
           </el-button>
           <el-button @click="cancel">取 消</el-button>
         </div>
       </el-dialog>
 
       <!-- 绑定按钮dialog -->
-      <el-dialog
-        title="提示"
-        :visible.sync="btnDialogVisible"
-        :before-close="handleClose"
-      >
-        <DialogTemplate
-          ref="dialogRef"
-          :groupKey="groupKey"
-          :rowobj="rowobj"
-          :subCount="subCount"
-          :tableCount="tableCount"
-          :subTableName="subTableName"
-          @addList="addListHandler"
-        >
+      <el-dialog title="提示" :visible.sync="btnDialogVisible" :before-close="handleClose">
+        <DialogTemplate ref="dialogRef" :groupKey="groupKey" :rowobj="rowobj" :subCount="subCount"
+          :tableCount="tableCount" :subTableName="subTableName" @addList="addListHandler">
         </DialogTemplate>
         <span slot="footer" class="dialog-footer">
           <el-button @click="btnDialogVisible = false">取 消</el-button>
@@ -259,20 +142,9 @@
       </el-dialog>
 
       <!-- 自定义弹窗 -->
-      <el-dialog
-        title="提示"
-        :visible.sync="btnDialogVisible"
-        :before-close="handleClose"
-      >
-        <DialogTemplate
-          ref="dialogRef"
-          :groupKey="groupKey"
-          :rowobj="rowobj"
-          :subCount="subCount"
-          :tableCount="tableCount"
-          :subTableName="subTableName"
-          @addList="addListHandler"
-        >
+      <el-dialog title="提示" :visible.sync="btnDialogVisible" :before-close="handleClose">
+        <DialogTemplate ref="dialogRef" :groupKey="groupKey" :rowobj="rowobj" :subCount="subCount"
+          :tableCount="tableCount" :subTableName="subTableName" @addList="addListHandler">
         </DialogTemplate>
         <span slot="footer" class="dialog-footer">
           <el-button @click="btnDialogVisible = false">取 消</el-button>
@@ -297,9 +169,7 @@
         </span>
         <template #footer>
           <span>
-            <el-button type="primary" @click="toastShow = false"
-              >确认</el-button
-            >
+            <el-button type="primary" @click="toastShow = false">确认</el-button>
           </span>
         </template>
       </el-dialog>
@@ -346,7 +216,19 @@ export default {
   },
   data() {
     return {
-      isLayout:false,
+      calculateTableData: [
+        { date: '2023-10-01', name: '张三', address: '北京市' },
+        { date: '2023-10-02', name: '李四', address: '上海市' },
+        { date: '2023-10-03', name: '王五', address: '广州市' }
+      ],
+      calculateTableColumn: [
+        { prop: 'date', label: '日期', width: '180' },
+        { prop: 'name', label: '姓名', width: '180' },
+        { prop: 'address', label: '地址' }
+      ],
+      formula: 'sum',
+      showSummary: false,
+      isLayout: false,
       QueryfromLoading: false,
       layoutData: "", //表单组布局数据
       times: 1, //请求次数
@@ -510,9 +392,9 @@ export default {
   created() {
     // 得到当前展示的table的唯一标识
     this.tableKey = this.$route.query.tableKey;
-    console.log('this.$route.query',this.$route.query)
+    console.log('this.$route.query', this.$route.query)
     // 优化共通模版查询调用逻辑 (Don't fucking change it)
-    console.log('this.queryParams',this.queryParams)
+    console.log('this.queryParams', this.queryParams)
     this.getList(this.queryParams);
   },
   mounted() {
@@ -556,18 +438,18 @@ export default {
     /** 查询列表 */
     getList(queryParams) {
       this.loading = true;
-        // 序列化当前查询参数列表
-        queryParams && (this.queryParams.queryMap = Object.assign({}, queryParams.queryMap));
-        if (typeof queryParams.queryMap.timehorizon != undefined) {
-          // timehorizon 时间范围转换字符串回传后台
-          this.queryParams.queryMap.timehorizon = JSON.stringify(
-            Object.assign({}, queryParams.queryMap.timehorizon)
-          );
-        }
+      // 序列化当前查询参数列表
+      queryParams && (this.queryParams.queryMap = Object.assign({}, queryParams.queryMap));
+      if (typeof queryParams.queryMap.timehorizon != undefined) {
+        // timehorizon 时间范围转换字符串回传后台
+        this.queryParams.queryMap.timehorizon = JSON.stringify(
+          Object.assign({}, queryParams.queryMap.timehorizon)
+        );
+      }
       // 获取当前表单结构信息
       dragTableInfo({ queryMap: { tableKey: this.tableKey } })
         .then((res) => {
-          console.log('[表格中dragTableInfo的结果中的resultMap属性]',res.data.resultMap)
+          console.log('[表格中dragTableInfo的结果中的resultMap属性]', res.data.resultMap)
           // 得到当前模版信息 --- sql columns queryWhere
           this.templateInfo = res.data.resultMap;
           this.QueryfromLoading = true; // 加载查询组件
@@ -581,6 +463,7 @@ export default {
           this.excuteBtnArr = res.data.resultMap.button?.filter(
             (item) => item.btnGroupType == "right"
           );
+          // console.log('[========excuteBtnArr==============]',this.excuteBtnArr)
           this.topBtnArr =
             res.data.resultMap.button?.filter(
               (item) => item.btnGroupType == "top"
@@ -702,9 +585,9 @@ export default {
       this.$refs.mychild.pageList(
         row == undefined
           ? {
-              limit: this.queryParams.pageSize,
-              page: this.queryParams.pageNum,
-            }
+            limit: this.queryParams.pageSize,
+            page: this.queryParams.pageNum,
+          }
           : row
       );
     },
@@ -713,9 +596,9 @@ export default {
       this.ids = selection.map(
         (item) =>
           item[
-            camelCase(
-              this.tableName + "_" + this.templateInfo.template?.primaryKey
-            )
+          camelCase(
+            this.tableName + "_" + this.templateInfo.template?.primaryKey
+          )
           ]
       );
       this.selection = selection;
@@ -802,7 +685,7 @@ export default {
     // 延迟
     sleep(ms) {
       var unixtime_ms = new Date().getTime();
-      while (new Date().getTime() < unixtime_ms + ms) {}
+      while (new Date().getTime() < unixtime_ms + ms) { }
       return "";
     },
     /** 修改按钮操作 */
@@ -995,8 +878,76 @@ export default {
       console.log(this.times);
       return;
     },
+    getformula({ columns, data }) {
+      // console.log('[当前合计行的columns或data]', columns, data)
+      // console.log('[当前calculateTableColumn]', this.calculateTableColumn)
+      // 循环columns,将columns.property== this.calculateTableColumn数组中的prop的对象找出,将匹配的this.calculateTableColumn.type的值赋给columns.columns.type
+      // 遍历传入的columns数组,并更新ColumnType
+    columns = columns.map(column => {
+      if (column && column.property) {
+        const matchingColumn = this.calculateTableColumn.find(
+          calcColumn => calcColumn.prop === column.property
+        );
+        if (matchingColumn) {
+          column.ColumnType = matchingColumn.type;
+        }
+      }
+      return column;
+    });
+
+    const sums = [];
+    const formula = this.formula; // 假设formula是在组件数据中的变量
+
+    columns.forEach((column, index) => {
+      // 跳过序号列
+      if (index === 0) {
+        // 第一列显示合计行的标题
+        sums[index] = formula === 'sum' ? '合计' : 
+                      formula === 'min' ? '最小值' : 
+                      formula === 'max' ? '最大值' : 
+                      formula === 'average' ? '平均值' : '合计';
+        return;
+      }
+
+      // 检查ColumnType是否为numberTotal或result
+      if (!['numberTotal', 'result'].includes(columns[index].ColumnType)) {
+        sums[index] = ''; // 如果不是这两种类型,则不显示合计信息
+        return;
+      }
+
+      // 获取当前列的数据
+      const values = data.map(item => Number(item[column.property]));
 
+      // 确保所有值都是数字
+      if (values.every(value => !isNaN(value))) {
+        switch (formula) {
+          case 'sum':
+            sums[index] = values.reduce((prev, curr) => prev + curr, 0);
+            break;
+          case 'min':
+            sums[index] = Math.min(...values);
+            break;
+          case 'max':
+            sums[index] = Math.max(...values);
+            break;
+          case 'average':
+            sums[index] = values.reduce((prev, curr) => prev + curr, 0) / values.length;
+            break;
+          default:
+            sums[index] = values.reduce((prev, curr) => prev + curr, 0);
+        }
+        // 格式化显示(保留两位小数)
+        sums[index] = Number(sums[index].toFixed(2));
+      } else {
+        sums[index] = '-'; // 如果列中有非数字,显示 -
+      }
+    });
+
+    return sums;
+    },
+    // 计算表格方法
     async handleCalculate(row, btnData) {
+      console.log("btnData, row", btnData, row);
       let nameTable = this.templateInfo.template.dtTableName;
       this.rowobj = {};
       let obj = {};
@@ -1014,6 +965,8 @@ export default {
       // 新的修改请求
       try {
         let { btnFormType, btnGroupType } = btnData;
+        // console.log("btnFormType, btnGroupType", btnFormType, btnGroupType);
+        // console.log('this.currentBtnData', this.currentBtnData)
         let payLoad = {};
         let primary = camelCase(
           this.tableName + "_" + this.templateInfo.template?.primaryKey
@@ -1053,83 +1006,37 @@ export default {
             this.$message.error("当前按钮未绑定表单!");
             return;
           }
-          if (btnFormType == "dragFormGroup") {
-            //表单组
-            if (res.code == 200) {
-              if (res.data.mainForm) {
-                //表单组
-                // 判断是否有布局数据
-                this.isLayout =
-                  res.data.layoutJson &&
-                  JSON.parse(res.data.layoutJson)?.list.length > 0;
-                this.transformDataFormat(res.data);
-                if (this.isLayout) {
-                  //自定义布局
-                  this.layoutData = JSON.parse(JSON.stringify(res.data));
-                }
-              } else {
-                this.formList = res.data;
-              }
-              this.open = true;
-              if (btnData.btnFormType == "dragFormGroup") {
-                if (this.times) {
-                  this.times = 0;
-                  // debugger;
-                  this.$nextTick(async () => {
-                    // debugger;
-                    setTimeout(() => {
-                      this.handleUpdate(row, btnData).then((res) => {
-                        this.formListShow = true;
-                      });
-                      // setTimeout(() => {
-                      //   this.times = 0;
-                      // }, 1000);
-                    }, 1000);
-                  });
-                }
-              }
-              if (this.isLayout) {
-                //布局样式
-                this.$nextTick(() => {
-                  // 手动触发布局组件的数据处理函数
-                  this.$refs.formGroupLayoutRef?.initLayoutData(
-                    JSON.parse(JSON.stringify(res.data))
-                  );
-                });
-              }
-            } else {
-              this.$message.error("网络异常,请稍后再试");
-            }
-          } else {
-            let optionsData = "",
-              templateData = "";
-            if (btnGroupType == "top") {
-              optionsData = res.data.dfFormSql;
-              templateData = res.data.dfVueTemplate;
-            } else {
-              //修改
-              optionsData = res.data.template.dfFormSql;
-              templateData = res.data.template.dfVueTemplate;
-
-              this.addRealFieldName(res.data.result.resultMap);
-              let resultMap = res.data.result.resultMap;
-
-              Object.assign(this.defaultValue, resultMap);
-            }
-            //单个表单
+          if (btnFormType == "calculateForm") {
+            let optionsData = res.data.template.dfFormSql;//暂时不知道是干什么的
+            let templateData = res.data.template.dfVueTemplate;
+            this.addRealFieldName(res.data.result.resultMap);//没返回?
+            let resultMap = res.data.result.resultMap;
+            //this.defaultValue回显表格数据
+            Object.assign(this.defaultValue, resultMap);
+            // dynamicData下拉框动态数据--data上这么备注的,是个要传给k-form-build的对象
+            // 当 optionsData 存在时执行 JSON.parse(optionsData) 并赋值给 this.dynamicData。
             optionsData && (this.dynamicData = JSON.parse(optionsData));
             this.jsonData = JSON.parse(templateData);
-            // console.log('[----- this.jsonData -----]', this.jsonData )
             this.open = true;
             this.title = "计算表单";
-            this.form.password = this.initPassword;
-            if (btnGroupType == "right") {
-              this.$nextTick(() => {
-                this.$refs.addFromRef.setData(res.data.result.resultMap);
-                console.log('[----- res.data.result.resultMap -----]', res.data.result.resultMap )
+            let calculateResultMap = res.data.result.calculateResultMap
+            if (calculateResultMap && calculateResultMap.tableColumn && calculateResultMap.tableValue) {
+              this.calculateTableData = calculateResultMap.tableValue
+              this.calculateTableColumn = calculateResultMap.tableColumn
 
-              });
+
+              this.formula = calculateResultMap.formula
+              this.showSummary = calculateResultMap.showSummary
+
+            } else {
+              this.calculateTableData = []
+              this.calculateTableColumn = []
             }
+            // if (this.$refs.addFromRef) {
+            //   this.$refs.addFromRef.setData(res.data.result.resultMap);
+            // } else {
+            //   console.error('addFromRef is undefined');
+            // }
           }
         } else {
           this.subTableName = res.data.result.dragTables[1].dtTableName;
@@ -1218,9 +1125,9 @@ export default {
         defaultValue: mainForm.showValue ? mainForm.showValue[0].resultMap : {},
       });
       if (subFormList && subFormList.length > 0) {
-        console.log("subFormList",subFormList)
+        console.log("subFormList", subFormList)
         subFormList.forEach((item) => {
-          console.log("sub item",item)
+          console.log("sub item", item)
           let showValue = null;
           if (item.showValue) {
             showValue = item.showValue[0];
@@ -1270,7 +1177,7 @@ export default {
             formType: item.showTemplate.spare == "2" ? "batch" : "normal",
             defaultValue,
             insertMap: item.insertMap,
-            updateMap:item.updateMap,
+            updateMap: item.updateMap,
             isMainForm: false,
           });
           console.log(this.FormNameList)
@@ -1367,7 +1274,7 @@ export default {
           this.$refs.mychild.pageList();
           this.$modal.msgSuccess("删除成功");
         })
-        .catch(() => {});
+        .catch(() => { });
     },
     // 批量删除接口
     handleBatchDelete() {
@@ -1393,7 +1300,7 @@ export default {
           this.$refs.mychild.pageList();
           this.$modal.msgSuccess("删除成功");
         })
-        .catch(() => {});
+        .catch(() => { });
     },
     /** 导出按钮操作 */
     handleExport() {
@@ -1427,7 +1334,7 @@ export default {
     importTemplate() {
       this.download(
         process.env.VUE_APP_BASE_API1 +
-          `common/exportTemplate?tableName=${this.tableName}&sqlkey=${this.templateInfo.template.sqlKey}`,
+        `common/exportTemplate?tableName=${this.tableName}&sqlkey=${this.templateInfo.template.sqlKey}`,
         {},
         `下载模版名称${new Date().getTime()}.xlsx`
       );
@@ -1443,8 +1350,8 @@ export default {
       this.$refs.upload.clearFiles();
       this.$alert(
         "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
-          response.msg +
-          "</div>",
+        response.msg +
+        "</div>",
         "导入结果",
         { dangerouslyUseHTMLString: true }
       );
@@ -1473,7 +1380,7 @@ export default {
       this.addLists.push(...val);
     },
     // 绑定弹窗Dialog确定按钮
-    btnComfirm() {},
+    btnComfirm() { },
     // 去掉表名 开头字母小写
     formatField(field = "", tableName) {
       let temp = field.replace(tableName, "");
@@ -1501,7 +1408,7 @@ export default {
       });
     },
     // 处理 动态表单 动态表格 修改数据
-    getEditBatchData(values, data) {},
+    getEditBatchData(values, data) { },
     // 处理 表单组  含有动态表格  新增数据
     getFormGroupBatchData(values, index, result) {
       let tableName = Object.keys(values.data.batch)[0];
@@ -1554,16 +1461,16 @@ export default {
                   item.fieldValue
                     ? item.fieldValue
                     : this.currentRow[
-                        camelCase(item.fieldName.replace(".", "_"))
-                      ];
+                    camelCase(item.fieldName.replace(".", "_"))
+                    ];
               });
               conditionData.forEach((item) => {
                 data.conditionMap[item.fieldName.split(".")[1]] =
                   item.fieldValue
                     ? item.fieldValue
                     : this.currentRow[
-                        camelCase(item.fieldName.replace(".", "_"))
-                      ];
+                    camelCase(item.fieldName.replace(".", "_"))
+                    ];
               });
             }
             if (Object.keys(this.defaultValue).length) {
@@ -1620,13 +1527,13 @@ export default {
             promiseArray.push(...item);
           });
         } else {
-          console.log("res",this.FormNameList)
+          console.log("res", this.FormNameList)
           promiseArray = this.FormNameList.map((item) => {
-            console.log("如何循环---",item);
+            console.log("如何循环---", item);
             return this.$refs.formGroupRef?.getFormData(item);
           });
         }
-        console.log(promiseArray,"111111")
+        console.log(promiseArray, "111111")
         Promise.all(promiseArray).then(async (res) => {
           // console.log("res", res);
           // return;
@@ -1693,8 +1600,8 @@ export default {
                     item.fieldValue
                       ? item.fieldValue
                       : this.currentRow[
-                          camelCase(item.fieldName.replace(".", "_"))
-                        ];
+                      camelCase(item.fieldName.replace(".", "_"))
+                      ];
                 });
                 payLoad.updateCommonEntityList.push(result);
               } else {
@@ -1744,7 +1651,7 @@ export default {
                   let fieldName = formItem.split(".")[1];
                   let value =
                     this.currentRow[
-                      camelCase(relateFormItem.replace(".", "_"))
+                    camelCase(relateFormItem.replace(".", "_"))
                     ];
                   result.conditionMap[fieldName] = value;
                   payLoad.updateCommonEntityList.push(result);
@@ -1794,11 +1701,11 @@ export default {
             });
           } else if (this.currentBtnData.btnType == "INITIATED") {
             payLoad.updateCommonEntityList = res.map((item, index) => {
-              let a={};
-              if(item.updateMap?.length){
-                 item.updateMap.forEach((item) => {
-                   a[item.fieldName.split(".")[1]] =item.refValue;
-                 })
+              let a = {};
+              if (item.updateMap?.length) {
+                item.updateMap.forEach((item) => {
+                  a[item.fieldName.split(".")[1]] = item.refValue;
+                })
               }
               let result = {
                 basicMap: {
@@ -1819,8 +1726,8 @@ export default {
                     item.fieldValue
                       ? item.fieldValue
                       : this.currentRow[
-                          camelCase(item.fieldName.replace(".", "_"))
-                        ];
+                      camelCase(item.fieldName.replace(".", "_"))
+                      ];
                 });
               } else {
                 // 从表条件
@@ -1833,7 +1740,7 @@ export default {
               return result;
             });
           }
-          console.log( payLoad.updateCommonEntityList,"hmc");
+          console.log(payLoad.updateCommonEntityList, "hmc");
           data.basicMap.BpmRunNodeFormDateVo = payLoad;
           // return;
           try {
@@ -1910,8 +1817,8 @@ export default {
     // 使用提交数据类型的按钮获取数据
     tempSubBtn(getData) {
       getData()
-        .then((values) => {})
-        .catch(() => {});
+        .then((values) => { })
+        .catch(() => { });
     },
     // 判断是否生效行样式
     cellStyle({ row, column, rowIndex, columnIndex }) {
@@ -2054,7 +1961,7 @@ export default {
     },
     // 操作列回调
     excuteHandler(btnData, row) {
-      console.log("btnData, row", btnData, row);
+      // console.log("btnData, row", btnData, row);
       let { btnType, btnParams, btnFormType } = btnData;
       this.formType = btnFormType;
       this.currentBtnData = btnData;
@@ -2226,8 +2133,8 @@ export default {
                 item.fieldValue
                   ? item.fieldValue
                   : this.currentRow[
-                      camelCase(item.fieldName.replace(".", "_"))
-                    ];
+                  camelCase(item.fieldName.replace(".", "_"))
+                  ];
             });
           }
           data.basicMap.btnType = this.currentBtnData.btnType;
@@ -2250,10 +2157,10 @@ export default {
           this.$refs.mychild.pageList();
           // this.$modal.msgSuccess("操作成功");
         })
-        .catch(() => {});
+        .catch(() => { });
     },
     // k-form-build表单变化回调
-    formChangeHandler(value, label) {},
+    formChangeHandler(value, label) { },
   },
 };
 </script>

+ 4 - 4
zkqy-ui/src/views/tablelist/commonTable/listTreeInfo.vue

@@ -43,7 +43,7 @@
           <!-- show-checkbox 节点是否可以被选择 -->
           <el-tree :data="treeData" :props="defaultProps" 
           default-expand-all
-          @node-click="handleNodeClick" @node-dblclick="handleNodeDblClick" :expand-on-click-node="false">
+          @node-click="handleNodeClick" :expand-on-click-node="false">
             <span class="custom-tree-node" slot-scope="{ node, data }">
               <!-- <span style="margin-right: 10px;">{{ node.label }}</span> -->
               <span style="margin-right: 10px;">
@@ -689,9 +689,9 @@ export default {
         })
         .finally((fes) => {
           if (this.treeNode.id) {
-            console.log('[vtreeNode]', this.treeNode)
-            let columnValue = this.templateData?.treeTableCondition == 'name' ? this.treeNode.name : this.treeNode.label
-            let treeQueryMap = this.templateData?.treeTableJoinTableCondition
+            console.log('[vtreeNode]', this.templateData,this.treeNode)
+            let columnValue = this.templateData?.treeTableCondition == 'value' ? this.treeNode.value : this.treeNode.label
+            let treeQueryMap =  this.templateData?.treeTableCondition == 'value' ? this.templateData?.treeTablePrimaryKey : this.templateData?.treeTableJoinTableCondition
             this.queryParams.queryMap[treeQueryMap] = `'${columnValue}'`
             this.queryParams.queryMap.queryCriteriaValue = ''
             if (this.$refs.mychild) {