Explorar o código

模板查询列表,Sql生成初步算法!

周壕 hai 1 ano
pai
achega
181afdfa34
Modificáronse 22 ficheiros con 553 adicións e 70 borrados
  1. 19 0
      src/main/java/com/bowintek/practice/controller/TempController.java
  2. 2 3
      src/main/java/com/bowintek/practice/mapper/cquery/TempCQuery.java
  3. 221 0
      src/main/java/com/bowintek/practice/services/impl/GenSqlStringServiceImpl.java
  4. 15 0
      src/main/java/com/bowintek/practice/services/impl/TempServiceImpl.java
  5. 11 0
      src/main/java/com/bowintek/practice/services/service/GenSqlStringService.java
  6. 4 0
      src/main/java/com/bowintek/practice/services/service/TempService.java
  7. 3 1
      src/main/java/com/bowintek/practice/util/StringUtils.java
  8. 1 1
      src/main/java/com/bowintek/practice/vo/practicebase/ImportPositionModel.java
  9. 1 1
      src/main/java/com/bowintek/practice/vo/common/ImportBaseModel.java
  10. 16 0
      src/main/java/com/bowintek/practice/vo/temp/SqlColumnModel.java
  11. 19 0
      src/main/java/com/bowintek/practice/vo/temp/SqlFieldModel.java
  12. 0 29
      src/main/java/com/bowintek/practice/vo/temp/TempModel.java
  13. 3 0
      src/main/java/com/bowintek/practice/vo/temp/TempObjectModel.java
  14. 13 0
      src/main/resources/mapping/cquery/TempCQuery.xml
  15. 8 6
      vue/src/components/basic/query/drag-base.vue
  16. 6 5
      vue/src/components/basic/query/drag-measure.vue
  17. 4 4
      vue/src/components/basic/query/drag-where.vue
  18. 1 0
      vue/src/router/asyncModules/sale.ts
  19. 1 2
      vue/src/views/dashboard/welcome/index.vue
  20. 2 2
      vue/src/views/position/index.vue
  21. 27 16
      vue/src/views/query/index.vue
  22. 176 0
      vue/src/views/query/table.vue

+ 19 - 0
src/main/java/com/bowintek/practice/controller/TempController.java

@@ -4,7 +4,10 @@ import com.bowintek.practice.filter.exception.BaseErrorEnum;
 import com.bowintek.practice.filter.exception.BaseException;
 import com.bowintek.practice.filter.exception.BaseResponse;
 import com.bowintek.practice.filter.exception.RespGenerstor;
+import com.bowintek.practice.model.SrSaerchtemp;
+import com.bowintek.practice.model.SrSubject;
 import com.bowintek.practice.services.service.AccountService;
+import com.bowintek.practice.services.service.GenSqlStringService;
 import com.bowintek.practice.services.service.TempService;
 import com.bowintek.practice.services.service.system.RoleService;
 import com.bowintek.practice.vo.system.FunctionCodeModel;
@@ -27,8 +30,18 @@ public class TempController {
     @Autowired
     private TempService tempService;
     @Autowired
+    private GenSqlStringService genSqlStringService;
+    @Autowired
     private AccountService accountService;
 
+    @ResponseBody
+    @GetMapping("/getList")
+    public BaseResponse<PageInfo<SrSaerchtemp>> getList(@RequestParam("page") int page, @RequestParam("rows") int rows,
+                                                        String tempNo, String tempName) throws Exception {
+        PageInfo<SrSaerchtemp> result = tempService.getList(page, rows, tempNo, tempName, null);
+        return RespGenerstor.success(result);
+    }
+
     @ResponseBody
     @GetMapping("/getSubjectTree")
     public BaseResponse<List<HashMap<String, Object>>> getSubjectTree(@RequestParam(required = false) String tabName) {
@@ -44,4 +57,10 @@ public class TempController {
     public BaseResponse<TempObjectModel> saveTemp(@RequestBody TempObjectModel data) {
         return RespGenerstor.success(tempService.saveTemp(data, accountService.getLoginUserID()));
     }
+
+    @PostMapping("/genTest")
+    public BaseResponse<TempObjectModel> genTest(@RequestBody TempObjectModel data) {
+        genSqlStringService.Generation(data, accountService.getLoginUserID());
+        return RespGenerstor.success(0);
+    }
 }

+ 2 - 3
src/main/java/com/bowintek/practice/mapper/cquery/TempCQuery.java

@@ -1,8 +1,6 @@
 package com.bowintek.practice.mapper.cquery;
 
-import com.bowintek.practice.model.SrTempdimension;
-import com.bowintek.practice.model.SrTempfield;
-import com.bowintek.practice.model.SrTempmeasure;
+import com.bowintek.practice.model.*;
 import com.bowintek.practice.vo.system.RoleFunctionCodeModel;
 import org.apache.ibatis.annotations.Param;
 
@@ -10,6 +8,7 @@ import java.util.HashMap;
 import java.util.List;
 
 public interface TempCQuery {
+    List<SrSaerchtemp> getList(String tempNo, String tempName, String tempIdsString);
     List<HashMap<String,Object>> getListToHashMap(String tempName);
     Integer batchInsertDimension(@Param("dataList") List<SrTempdimension> dataList);
     Integer batchInsertField(@Param("dataList") List<SrTempfield> dataList);

+ 221 - 0
src/main/java/com/bowintek/practice/services/impl/GenSqlStringServiceImpl.java

@@ -0,0 +1,221 @@
+package com.bowintek.practice.services.impl;
+
+import com.bowintek.practice.mapper.SrSaerchtempMapper;
+import com.bowintek.practice.mapper.SrSubjectMapper;
+import com.bowintek.practice.mapper.SrSubjectfieldMapper;
+import com.bowintek.practice.mapper.cquery.SubjectCQuery;
+import com.bowintek.practice.mapper.cquery.TempCQuery;
+import com.bowintek.practice.model.*;
+import com.bowintek.practice.services.service.GenSqlStringService;
+import com.bowintek.practice.services.service.TempService;
+import com.bowintek.practice.vo.temp.SqlColumnModel;
+import com.bowintek.practice.vo.temp.SqlFieldModel;
+import com.bowintek.practice.vo.temp.TempObjectModel;
+import com.bowintek.practice.vo.temp.TempSaveResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.RecursiveTask;
+import java.util.stream.Collectors;
+
+@Component
+public class GenSqlStringServiceImpl implements GenSqlStringService {
+    @Autowired
+    SrSubjectMapper srSubjectMapper;
+    @Autowired
+    SrSubjectfieldMapper srSubjectfieldMapper;
+
+    //查询语句生成,要素点:查询主表、关联子表、查询字段、查询条件
+    //查询主表:FROM (sr_subject.execSql) AS T
+    //查询字段-维度:sr_tempdimension.fieldAlias
+    //查询字段-度量:sr_tempmeasure.fieldAlias + 函数名称/表达式; SUM({$FIELD$}) / COUNT(*) 替换中间字段名称
+    //查询条件:检测出 日期型、字符型、数字型,在针对性生成条件语句
+    //输出字段 AS:ReFieldName0,1,2...;依据维度度量排序来
+    //表名 AS:T 主表,T0,1,2...;子表,依据维度度量子表排序来
+    @Override
+    public void Generation(TempObjectModel data, String userID){
+        //取得字段原本定义
+        data.sub = srSubjectMapper.selectByPrimaryKey(data.temp.getSubId());
+        List<SrSubjectfield> fileds = getSubjectfieldsBySubId(data.temp.getSubId());
+        //循环分析出关联表
+        //isForeignKey leftFieldId rightFieldId referencesTab displayColumn
+        int tabIndex = 0;
+        HashMap<String, SqlColumnModel> aliasMap = new HashMap<>();
+        List<SqlFieldModel> models = new ArrayList<>();
+        data.bases.forEach(it->{ models.add(SqlFieldModel.GenModel(it.getFieldId(),it.getTempFeildId()));});
+        data.measures.forEach(it->{ models.add(SqlFieldModel.GenModel(it.getFieldId(),it.getTempFeildId()));});
+
+        //生成主要的字段、关联表、表T名称、字段T名称对照表
+        String leftTableString = "";
+        for(int i=0;i<models.size();i++){
+            SrSubjectfield fd = findFieldByFieldId(fileds, models.get(i).getFieldId());
+            SqlColumnModel cm = getSqlColumn(fd.getIsForeignKey(), fd.getFieldAlias(), fd.getFieldCode(), fd.getForeignKey(),
+                    fd.getReferencesTab(), fd.getDisplayColumn(), tabIndex);
+            if(cm.getIsForeignKey()) {
+                tabIndex++;
+                leftTableString+=cm.getLeftJoinString();
+            }
+            aliasMap.put(models.get(i).getTempFieldId(), cm);
+        }
+
+        int fieldIndex = 0;
+        String colString = "", groupString = "";
+        //维度生成,Group生成
+        for(int i=0;i<data.bases.size();i++){
+            SrTempdimension dim = data.bases.get(i);
+            SqlColumnModel cm = aliasMap.get(dim.getTempFeildId());
+
+            colString += MessageFormat.format("{0} {1} AS {2}\n\t",
+                    getCommaString(fieldIndex), cm.getDisplayColumn(), getFieldName(fieldIndex));
+            groupString += MessageFormat.format("{0} {1}\n\t",getCommaString(fieldIndex), cm.getDisplayColumn());
+            fieldIndex++;
+        }
+
+        //度量生成
+        for(int i=0;i<data.measures.size();i++){
+            SrTempmeasure msr = data.measures.get(i);
+            SqlColumnModel cm = aliasMap.get(msr.getTempFeildId());
+
+            colString += MessageFormat.format("{0} {1} AS {2}\n\t",
+                    getCommaString(fieldIndex),
+                    getMeasurString(msr.getOperation(), cm.getDisplayColumn()),
+                    getFieldName(fieldIndex));
+            fieldIndex++;
+        }
+
+        //查询条件的生成
+        String whereString = "";
+        for(int i=0;i<data.wheres.size();i++){
+            SrTempfield stf = data.wheres.get(i);
+            int dataType = getDataType(stf.getDataType());
+            if(dataType==0) whereString += genWhereString(stf);
+            else if(dataType==1) whereString += genWhereNumber(stf);
+            else if(dataType==2) whereString += genWhereDate(stf);
+        }
+
+        //生成排序字段
+        String orderByString = "";
+        if(IsNullEmpty(data.orderBy) || !aliasMap.containsKey(data.orderBy)) data.orderBy = aliasMap.keySet().stream().findFirst().get();
+        System.out.println("data.orderBy:"+data.orderBy);
+
+        if(aliasMap.containsKey(data.orderBy)){
+            if(IsNullEmpty(data.orderByString)) data.orderByString = "aes";
+            SqlColumnModel cmOrder = aliasMap.get(data.orderBy);
+            orderByString = MessageFormat.format("ORDER BY {0} {1}", cmOrder.getDisplayColumn(), data.orderByString);
+        }
+
+        String mainSqlStrimg = MessageFormat.format("SELECT {0} \nFROM ({1}) AS T {2} \nGROUP BY {3} \nWHERE 1=1 {4} \n\n{5}",
+                colString, data.sub.getExecSql(), leftTableString, groupString, whereString, orderByString);
+        System.out.println(mainSqlStrimg);
+    }
+
+
+
+    public int getDataType(String typeString){
+        List<String> strings = Arrays.asList(new String[]{"char","varchar","text"});
+        List<String> numbers = Arrays.asList(new String[]{"int","bigint","decimal"});
+        List<String> dates = Arrays.asList(new String[]{"date"});
+        if(strings.indexOf(typeString.toLowerCase(Locale.ROOT))>=0) return 0;
+        if(numbers.indexOf(typeString.toLowerCase(Locale.ROOT))>=0) return 1;
+        if(dates.indexOf(typeString.toLowerCase(Locale.ROOT))>=0) return 2;
+        return -1;
+    }
+
+    public static boolean IsNullEmpty(String value) {
+        return value == null || value.isEmpty();
+    }
+    public String genWhereString(SrTempfield stf){
+        if(stf.getOperation().isEmpty() || stf.getValue1().isEmpty())
+            return genRemark("genWhereString", stf.getTempFeildId());
+
+        if(stf.getOperation().equals("="))
+            return MessageFormat.format("\n\tAND T.{0}='{1}'", stf.getFieldAlias(),
+                    "'"+stf.getValue1()+"'");
+        else if(stf.getOperation().equals("like"))
+            return MessageFormat.format("\n\tAND T.{0} like {1}", stf.getFieldAlias(),
+                    "'%"+stf.getValue1()+"%'");
+        else
+            return MessageFormat.format("\n\tAND T.{0} {1}", stf.getFieldAlias(), stf.getOperation());
+    }
+
+    public String genWhereNumber(SrTempfield stf){
+        if(stf.getOperation().isEmpty() || stf.getValue1().isEmpty() ||
+                (stf.getOperation().equals("limit") && stf.getValue2().isEmpty()))
+            return genRemark("genWhereNumber", stf.getTempFeildId());
+
+        if(stf.getOperation().equals("limit"))
+            return MessageFormat.format("\n\tAND T.{0} >= {1} AND T.{2}<={3}",
+                    stf.getFieldAlias(), stf.getValue1(), stf.getFieldAlias(), stf.getValue2());
+        else
+            return MessageFormat.format("\n\tAND T.{0} {1} {2}", stf.getFieldAlias(), stf.getOperation(), stf.getValue1());
+    }
+
+    public String genWhereDate(SrTempfield stf){
+        if(stf.getOperation().isEmpty()) return genRemark("genWhereDate", stf.getTempFeildId());
+
+        String where = "";
+        if(!stf.getValue1().isEmpty())
+            where += MessageFormat.format("\n\tAND T.{0} >= {1}", stf.getFieldAlias(),
+                    "'"+stf.getValue1()+"'");
+        if(!stf.getValue2().isEmpty())
+            where += MessageFormat.format("\n\tAND T.{0} <= {1}", stf.getFieldAlias(),
+                    "'"+stf.getValue2()+"'");
+
+        return where.isEmpty()?genRemark("genWhereDate", stf.getTempFeildId()) : where;
+    }
+
+    public String genRemark(String fun,String key) {
+        return "\n/*" + fun + " " + key + " is gen err*/";
+    }
+
+    public SrSubjectfield findFieldByFieldId(List<SrSubjectfield> fields, String fieldId){
+        return fields.stream().filter(t->t.getFieldId().equals(fieldId)).findAny().orElse(null);
+    }
+
+    public List<SrSubjectfield> getSubjectfieldsBySubId(String subId){
+        SrSubjectfieldExample example = new SrSubjectfieldExample();
+        SrSubjectfieldExample.Criteria criteria = example.or();
+        criteria.andSubIdIn(Arrays.asList(new String[]{subId}));
+        List<SrSubjectfield> fileds = srSubjectfieldMapper.selectByExample(example);
+        System.out.println("getSubjectfieldsBySubId Size:"+fileds.size());
+        return fileds;
+    }
+
+    public SqlColumnModel getSqlColumn(int isForeignKey, String filedAlias, String leftFieldId, String rightFieldId,
+                                       String referencesTab, String displayColumn, int index){
+        SqlColumnModel model = new SqlColumnModel();
+        if(isForeignKey==0 || leftFieldId.isEmpty() || rightFieldId.isEmpty() || referencesTab.isEmpty() || displayColumn.isEmpty()){
+            model.setIsForeignKey(false);
+            model.setTableAlias("T");
+            model.setDisplayColumn(MessageFormat.format("{0}.{1}","T", filedAlias));
+            return model;
+        }
+
+        model.setIsForeignKey(true);
+        model.setTableAlias("T"+index);
+        String leftJoinString = MessageFormat.format("\nLEFT JOIN {0} AS {1} on T.{2}={3}.{4}",
+                referencesTab, model.getTableAlias(), leftFieldId, model.getTableAlias(), rightFieldId);
+        model.setLeftJoinString(leftJoinString);
+        model.setDisplayColumn(MessageFormat.format("{0}.{1}",model.getTableAlias(), displayColumn));
+
+        return model;
+    }
+
+    public String getFieldName(int index){
+        return "ReFieldName"+index;
+    }
+
+    public String getCommaString(boolean is){
+        return is?",":"";
+    }
+
+    public String getCommaString(int index){
+        return getCommaString(index>0);
+    }
+
+    public String getMeasurString(String oprationStr, String fieldName){
+        return oprationStr.replaceAll("\\{\\$FIELD\\$\\}", fieldName);
+    }
+}

+ 15 - 0
src/main/java/com/bowintek/practice/services/impl/TempServiceImpl.java

@@ -8,6 +8,7 @@ import com.bowintek.practice.model.*;
 import com.bowintek.practice.services.service.TempService;
 import com.bowintek.practice.services.service.UserService;
 import com.bowintek.practice.util.DateUtils;
+import com.bowintek.practice.util.StringUtils;
 import com.bowintek.practice.vo.temp.TempObjectModel;
 import com.bowintek.practice.vo.temp.TempSaveResult;
 import com.bowintek.practice.vo.user.DataRange;
@@ -30,6 +31,20 @@ public class TempServiceImpl implements TempService {
     SrSaerchtempMapper srSaerchtempMapper;
     @Autowired
     SrSubjectMapper srSubjectMapper;
+    @Autowired
+    private StringUtils stringUtils;
+
+    @Override
+    public PageInfo<SrSaerchtemp> getList(Integer page, Integer rows,
+                                       String tempNo, String tempName, List<String> idList) {
+        PageHelper.startPage(page, rows);
+
+        List<SrSaerchtemp> dataList = tempCQuery.getList(tempNo, tempName,
+                stringUtils.ListToInSql(idList));
+
+        PageInfo<SrSaerchtemp> result = new PageInfo(dataList);
+        return result;
+    }
 
     @Override
     public TempObjectModel getTemp(String tempId){

+ 11 - 0
src/main/java/com/bowintek/practice/services/service/GenSqlStringService.java

@@ -0,0 +1,11 @@
+package com.bowintek.practice.services.service;
+
+import com.bowintek.practice.vo.temp.TempObjectModel;
+import com.bowintek.practice.vo.temp.TempSaveResult;
+
+import java.util.HashMap;
+import java.util.List;
+
+public interface GenSqlStringService {
+    void Generation(TempObjectModel data, String userID);
+}

+ 4 - 0
src/main/java/com/bowintek/practice/services/service/TempService.java

@@ -1,13 +1,17 @@
 package com.bowintek.practice.services.service;
 
+import com.bowintek.practice.model.SrSaerchtemp;
 import com.bowintek.practice.model.SysMenu;
 import com.bowintek.practice.vo.temp.TempObjectModel;
 import com.bowintek.practice.vo.temp.TempSaveResult;
+import com.github.pagehelper.PageInfo;
 
 import java.util.HashMap;
 import java.util.List;
 
 public interface TempService {
+    PageInfo<SrSaerchtemp> getList(Integer page, Integer rows,
+                                   String tempNo, String tempName, List<String> idList);
     List<HashMap<String,Object>> getSubjectTree(String likeName);
     TempSaveResult saveTemp(TempObjectModel data, String userID);
     TempObjectModel getTemp(String tempId);

+ 3 - 1
src/main/java/com/bowintek/practice/util/StringUtils.java

@@ -12,7 +12,6 @@ public class StringUtils {
         return value == null || value.length() == 0;
     }
 
-
     public <T> String ListToInSql(List<T> list) {
 
         if (list == null || list.size() <= 0)
@@ -23,4 +22,7 @@ public class StringUtils {
         return "'" + sql + "'";
     }
 
+    public static boolean IsNullEmpty(String value) {
+        return value == null || value.isEmpty();
+    }
 }

+ 1 - 1
src/main/java/com/bowintek/practice/vo/practicebase/ImportPositionModel.java

@@ -1,6 +1,6 @@
 package com.bowintek.practice.vo.practicebase;
 
-import com.bowintek.practice.vo.common.ImportBaseModel;
+import com.bowintek.practice.vo.system.common.ImportBaseModel;
 import lombok.Data;
 
 @Data

+ 1 - 1
src/main/java/com/bowintek/practice/vo/common/ImportBaseModel.java

@@ -1,4 +1,4 @@
-package com.bowintek.practice.vo.common;
+package com.bowintek.practice.vo.system.common;
 
 import lombok.Data;
 

+ 16 - 0
src/main/java/com/bowintek/practice/vo/temp/SqlColumnModel.java

@@ -0,0 +1,16 @@
+package com.bowintek.practice.vo.temp;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SqlColumnModel {
+    private Boolean isForeignKey;
+
+    private String tableAlias;
+
+    private String displayColumn;
+
+    private String leftJoinString;
+}

+ 19 - 0
src/main/java/com/bowintek/practice/vo/temp/SqlFieldModel.java

@@ -0,0 +1,19 @@
+package com.bowintek.practice.vo.temp;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SqlFieldModel {
+    private String fieldId;
+
+    private String tempFieldId;
+
+    public static SqlFieldModel GenModel(String fieldId, String tempFieldId){
+        SqlFieldModel model = new SqlFieldModel();
+        model.setFieldId(fieldId);
+        model.setTempFieldId(tempFieldId);
+        return model;
+    }
+}

+ 0 - 29
src/main/java/com/bowintek/practice/vo/temp/TempModel.java

@@ -1,29 +0,0 @@
-package com.bowintek.practice.vo.temp;
-
-import lombok.Data;
-
-import java.util.Date;
-import java.util.List;
-
-@Data
-public class TempModel {
-    private String tempId;
-
-    private String tempName;
-
-    private String tempNo;
-
-    private String subId;
-
-    private String remark;
-
-    private Date createTime;
-
-    private Date modifyTime;
-
-    private String createdBy;
-
-    private String modifyBy;
-
-    private Integer status;
-}

+ 3 - 0
src/main/java/com/bowintek/practice/vo/temp/TempObjectModel.java

@@ -13,4 +13,7 @@ public class TempObjectModel {
     public List<SrTempdimension> bases;
     public List<SrTempfield> wheres;
     public List<SrTempmeasure> measures;
+
+    public String orderBy;
+    public String orderByString;
 }

+ 13 - 0
src/main/resources/mapping/cquery/TempCQuery.xml

@@ -1,6 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.bowintek.practice.mapper.cquery.TempCQuery">
+    <select id="getList" resultType="com.bowintek.practice.model.SrSaerchtemp">
+        select *
+        from sr_saerchtemp tmp
+        where 1=1
+        <if test="tempName!='' and tempName!=null">
+            and tmp.tempName like Concat('%',#{tempName},'%')
+        </if>
+        <if test="tempNo!='' and tempNo!=null">
+            and tmp.tempNo like Concat('%',#{tempNo},'%')
+        </if>
+        order by tmp.createTime desc
+    </select>
+
     <select id="getListToHashMap" resultType="java.util.HashMap">
         select *
         from sr_saerchtemp st

+ 8 - 6
vue/src/components/basic/query/drag-base.vue

@@ -30,7 +30,7 @@
 </template>
 <script lang="ts">
   import {defineComponent, computed} from "vue";
-  //import {message} from "ant-design-vue";
+  import {cloneDeep} from 'lodash';
 
   export  default defineComponent ({
     props:{
@@ -61,7 +61,7 @@
         context.emit('change', list, obj)
       }
       const subjectId = computed(() => {
-        return props.subjectId? props.subjectId : null
+        return props.subjectId? props.subjectId : null;
       });
 
       return{
@@ -87,7 +87,7 @@
           fieldName: data.fieldName,
           isDrag: 1,
           displayName: data.displayName ? data.displayName : null,
-          operation: data.operation ? data.operation : 'sum',
+          operation: data.operation ? data.operation : 'SUM({$FIELD$})',
 
           subId : data.subId? data.subId : null,
           subjectName : data.subjectName? data.subjectName : null
@@ -106,7 +106,7 @@
         const obj = this.getObject(data);
         //检查主题是否合法
         console.log("handleDragOver", data, obj, this.tagList);
-        if(obj.subId==null || obj.subjectName==null) return; //主题不合法
+        if(obj.subId==null) return; //主题不合法
         if(this.subjectId && this.subjectId != obj.subId) {
           //message.error("无法放置,同一模板只能放置统一主题的维度、度量!");
           return;//有主题,但是和当前模板中的主题不同
@@ -148,7 +148,7 @@
 
         const data = window["dragData"];
         //检查主题是否合法
-        if(data.subId==null || data.subjectName==null) return; //主题不合法
+        if(data.subId==null) return; //主题不合法
         if(this.subjectId && this.subjectId != data.subId) return;//有主题,但是和当前模板中的主题不同
 
         this.tagList.splice(this.index,1)
@@ -165,7 +165,9 @@
       },
       childDragstart : function (ev, index) {
         console.log(ev);
-        window["dragData"] = JSON.parse(JSON.stringify(this.tagList[index]));
+        window["dragData"] = cloneDeep(this.tagList[index]);//JSON.parse(JSON.stringify(this.tagList[index]));
+        window["dragData"].subId = this.subjectId;
+        console.log("childDragstart", window["dragData"].subId);
         this.index = -1;
         setTimeout(()=>{
           this.tagList.splice(index,1);

+ 6 - 5
vue/src/components/basic/query/drag-measure.vue

@@ -9,11 +9,12 @@
     data(){
       return{
         aggregates : [
-          { value: 'sum', label: '求和'},
-          { value: 'avg', label: '平均'},
-          { value: 'max', label: '最大值'},
-          { value: 'min', label: '最小值'},
-          { value: 'count', label: '非NULL行数'}
+          { value: 'SUM({$FIELD$})', label: '求和'},
+          { value: 'AVG({$FIELD$})', label: '平均'},
+          { value: 'MAX({$FIELD$})', label: '最大值'},
+          { value: 'MIN({$FIELD$})', label: '最小值'},
+          { value: 'COUNT({$FIELD$})', label: '非NULL行数'},
+          { value: 'COUNT(*)', label: '行数'}
         ] as SelectProps['options']
       }
     },

+ 4 - 4
vue/src/components/basic/query/drag-where.vue

@@ -173,15 +173,15 @@
         this.tagList.forEach((row, index)=>{
           row.disOrder = index;
           row.operation = row.values[0].operation;
-          if(this.convertDataType(row.dataType)==2){
+          if(this.convertDataType(row.dataType)==2) {
             let formatString = "YYYY-MM-DD";
-            if(row.values[0].operation=="datetime") formatString="YYYY-MM-DD HH:mm:ss";
+            if (row.values[0].operation == "datetime") formatString = "YYYY-MM-DD HH:mm:ss";
 
-            if(row.values[0].val && row.values[0].val.length>0 && row.values[0].val[0]){
+            if (row.values[0].val && row.values[0].val.length > 0 && row.values[0].val[0]) {
               //row.value1 = row.values[0].val[0].toDate().getTime();
               row.value1 = row.values[0].val[0].format(formatString);
             }
-            if(row.values[0].val && row.values[0].val.length>1 && row.values[0].val[1]) {
+            if (row.values[0].val && row.values[0].val.length > 1 && row.values[0].val[1]) {
               //row.value2 = row.values[0].val[1].toDate().getTime();
               row.value2 = row.values[0].val[1].format(formatString);
             }

+ 1 - 0
vue/src/router/asyncModules/sale.ts

@@ -3,6 +3,7 @@ export default {
   'views/positionedit': () => import( '@/views/position/edit.vue'),
   'views/positiondetail': () => import( '@/views/position/detail.vue'),
   'views/queryindex': () => import( '@/views/query/index.vue'),
+  'views/queryTable': () => import( '@/views/query/table.vue'),
   'views/subjectlist': () => import( '@/views/subject/index.vue'),
   'views/subjectedit': () => import( '@/views/subject/edit.vue'),
   'views/subjectdetail': () => import( '@/views/subject/detail.vue'),

+ 1 - 2
vue/src/views/dashboard/welcome/index.vue

@@ -31,8 +31,7 @@
           <div style="display: flex;flex-wrap: wrap;text-align: center;">
             <div v-for="item in shortcutMenuList" @click="onShortcutMenuClick(item)"
                  style="flex: 0 0 33%;display: flex;align-items: center;flex-direction: column;cursor: pointer;margin: 10px 0;">
-              <div><img :src="require('@/assets/shortcutMenu/'+item.shortcutIcon)" style="width: 50px;height: 50px;"/>
-              </div>
+
               <div><span>{{ item.menuName }}</span></div>
             </div>
             <div v-if="shortcutMenuList.length==0">暂无</div>

+ 2 - 2
vue/src/views/position/index.vue

@@ -234,8 +234,8 @@ export default defineComponent({
       tabsViewStore.addTabByPath('/position/detail', {id: key});
     };
     const add = () => {
-      tabsViewStore.addTabByPath('/position/edit', {});
-      //tabsViewStore.addTabByPath('/query/index', {tempId: 'af029fdd-62ca-443e-9503-f940f40a7fdc'});
+      //tabsViewStore.addTabByPath('/position/edit', {});
+      tabsViewStore.addTabByPath('/query/index', {tempId: 'af029fdd-62ca-443e-9503-f940f40a7fdc'});
     };
     const edit = (key: string) => {
       tabsViewStore.addTabByPath('/position/edit', {id: key});

+ 27 - 16
vue/src/views/query/index.vue

@@ -3,9 +3,9 @@
     <div class="query-index-tree">
       <div class="query-index-tree-search">
         <a-input-search
-          v-model:value="value"
+          v-model:value="subjectTrees.searchStr"
           placeholder="主题名称关键字..."
-          @search="onSearch"
+          @search="getSubjectTree"
         />
       </div>
       <div class="query-index-tree-box">
@@ -16,7 +16,7 @@
           <template #title="{ title, key, subId, fieldCode, fieldId, fieldName, fieldAlias, dataType, subjectName }">
             <div v-if="(fieldAlias)" class="query-index-tree-item"
                  draggable="true"
-                 @dragstart="onDragStart($event,{subId,fieldCode, fieldId, fieldName, fieldAlias, dataType, subjectName})"
+                 @dragstart="onDragStart($event,{subId, fieldCode, fieldId, fieldName, fieldAlias, dataType, subjectName})"
             >{{ title }}</div>
             <div v-else class="query-index-tree-item">{{ title }}</div>
           </template>
@@ -29,7 +29,7 @@
                 class="ant-advanced-search-form"
                 :label-col="labelCol"
                 :model="formState.temp">
-          <a-row :gutter="24">
+          <a-row :gutter="24" class="query-index-row">
             <a-col :span="9">
               <a-form-item name="tempName"
                            :rules="[{ required: true, message: '请输入模板名称!' }]">
@@ -118,7 +118,8 @@ export default defineComponent({
 
     const subjectTrees = ref({
       data :[] as TreeProps['treeData'],
-      expandedKeys : ['']
+      expandedKeys : [''],
+      searchStr : ''
     });
     const formState = ref({
       temp : {
@@ -142,20 +143,26 @@ export default defineComponent({
         return;
       }
       formRef.value.validate().then(() => {
-        formState.value.measures = (measure.value as any).getTagList();
-        formState.value.wheres = (where.value as any).getTagList();
-        formState.value.bases = (base.value as any).getTagList();
-        console.log("formState", formState);
-
-        save('temp/save', formState.value).then(result => {
+        save('temp/save', formStateGet()).then(result => {
           console.log(result);
           getTemp(result["tempId"]);
         });
       });
     }
 
-    const onSelect= () =>{
+    const formStateGet = () =>{
+      formState.value.measures = (measure.value as any).getTagList();
+      formState.value.wheres = (where.value as any).getTagList();
+      formState.value.bases = (base.value as any).getTagList();
+      console.log("formState", formState.value);
+
+      return formState.value;
+    };
 
+    const onSelect= () =>{
+      save('temp/genTest', formStateGet()).then(result => {
+        console.log(result)
+      });
     }
 
     const onDragStart = (event, obj) =>{
@@ -164,9 +171,9 @@ export default defineComponent({
       window["dragData"] = obj;
       console.log("onDragStart", obj);
     }
-    const getSubjectTree = async function (tabName : string) {
+    const getSubjectTree = async function () {
       //loading.value = true;
-      subjectTrees.value.data = await get('temp/getSubjectTree', {tabName : tabName});
+      subjectTrees.value.data = await get('temp/getSubjectTree', {tabName : subjectTrees.value.searchStr});
       //计算第一个展开节点
       subjectTrees.value.expandedKeys = [];
       if(subjectTrees.value.data && subjectTrees.value.data.length>0){
@@ -177,7 +184,7 @@ export default defineComponent({
       }
       console.log("getSubjectTree",subjectTrees.value,subjectTrees.value.expandedKeys);
     }
-    getSubjectTree('');
+    getSubjectTree();
 
     const getTemp = async function(tempId){
       const rtn = await get('temp/get', {tempId : tempId});
@@ -265,7 +272,8 @@ export default defineComponent({
 
       dataList,
       columns,
-      subjectTrees
+      subjectTrees,
+      getSubjectTree
     };
   },
   created() {
@@ -329,4 +337,7 @@ export default defineComponent({
     padding-top: 10px;
     overflow:auto;
   }
+  .query-index-row{
+
+  }
 </style>

+ 176 - 0
vue/src/views/query/table.vue

@@ -0,0 +1,176 @@
+<template>
+  <div class="card-search">
+    <a-form
+      ref="formRef"
+      name="advanced_search"
+      class="ant-advanced-search-form"
+      :model="formState"
+      @finish="onFinish"
+    >
+      <a-row :gutter="24">
+        <a-col :span="9">
+          <a-form-item
+            name="tempName"
+            label="模板名称"
+            :label-col="{span:6}">
+            <a-input v-model:value="formState.tempName" style="width: 200px"></a-input>
+          </a-form-item>
+        </a-col>
+        <a-col :span="9">
+          <a-form-item
+            name="tempNo"
+            label="模板编号"
+            :label-col="{span:6}">
+            <a-input v-model:value="formState.tempNo" style="width: 200px"></a-input>
+          </a-form-item>
+        </a-col>
+        <a-col  :span="6" style="text-align: left">
+          <a-button type="primary" html-type="submit" @click="onFinish">查询</a-button>
+          <a-button style="margin: 0 8px" @click="() => {formRef.resetFields();loadData()}">重置</a-button>
+        </a-col>
+      </a-row>
+      <a-row class="edit-operation">
+        <a-col :span="24" style="text-align: right">
+          <a-button type="primary" html-type="button" @click="add" functioncode="T010601">新增</a-button>
+          <a-popconfirm placement="leftTop"
+            title="是否删除模板数据?"
+            @confirm="onDelete()">
+            <a-button type="primary" style="margin: 0 8px" html-type="button" functioncode="T010604">删除</a-button>
+          </a-popconfirm>
+        </a-col>
+      </a-row>
+    </a-form>
+    <div class="search-result-list">
+      <a-table :columns="columns" :data-source="data" :scroll="{ x:'100%', y: 500 }" :pagination="pagination"
+               :loading="loading"
+               :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+               @change="handleTableChange" :row-key="record=>record.positionID"
+               bordered>
+        <template #bodyCell="{ column,record }">
+          <template v-if="column.key === 'operation'">
+            <a-button type="link" size="small" @click="edit(record.tempId)">编辑</a-button>
+          </template>
+        </template>
+      </a-table>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import {reactive, ref, defineComponent, computed} from 'vue';
+import type {FormInstance} from 'ant-design-vue';
+import type {TableColumnsType, TableProps} from 'ant-design-vue';
+import { get, postdel} from '@/api/common';
+import {useRoute, useRouter} from "vue-router";
+import {useTabsViewStore} from "@/store/modules/tabsView";
+import {message} from "ant-design-vue";
+import {getPaginationTotalTitle} from "@/utils/common";
+import dayjs from "dayjs";
+
+export default defineComponent({
+  name: 'tempList',
+  components: {},
+  setup() {
+
+    const route = useRoute();
+    const router = useRouter();
+    const expand = ref(false);
+    const formRef = ref<FormInstance>();
+    const tabsViewStore = useTabsViewStore();
+    const selectedRowKeys =ref([]) ;
+    const formState = reactive({
+      page: 1, rows: 10, tempName: '', tempNo: '', tempId: "", total: 0,isPostManage:true
+    });
+
+    const columns: TableColumnsType = [
+      {
+        title: '序号',
+        width: 60,
+        dataIndex: 'index',
+        key: 'index',
+        align: "center",
+        customRender: item => `${formState.rows * (formState.page - 1) + item.index + 1}`
+      },
+      {title: '模板编号', dataIndex: 'tempNo', key: 'tempNo', width:180,align:"center"},
+      {title: '模板名称', dataIndex: 'tempName', key: '1', width:300},
+      {title: '创建时间', dataIndex: 'createTime', key: '2', width: 180, customRender: ({record}) =>
+          record.createTime==null?"": (dayjs(record.createTime).format('YYYY-MM-DD HH:mm'))},
+      {title: '模板状态', dataIndex: 'status', key: '3', width: 100,align:"center", customRender: ({record}) =>
+          record.status==0?"正常":"禁用"},
+      {title: '备注', dataIndex: 'remark', key: '4',ellipsis: true},
+      {title: '操作', key: 'operation', width: 120, align: "center"},
+    ];
+
+    const data = ref([]);
+    const pagination = computed(() => ({
+      total: formState.total,
+      current: formState.page,
+      pageSize: formState.rows,
+      showSizeChanger: true,
+      showTotal: total => getPaginationTotalTitle(total)
+    }));
+    const loading = ref(false);
+
+    const handleTableChange: TableProps['onChange'] = (
+      pag: { pageSize: number; current: number },
+    ) => {
+      formState.page = pag.current;
+      formState.rows = pag.pageSize;
+      loadData();
+    };
+
+    const onFinish = () => {
+      loadData();
+    }
+
+    const loadData = async function () {
+      loading.value = true;
+      const result: any = await get('temp/getList', formState);
+
+      data.value = result.list;
+      formState.total = result.total;
+      loading.value = false;
+    }
+    const onDelete = () => {
+      if (selectedRowKeys.value.length <= 0) {
+        message.warning('请选择需要删除的数据!');
+        return false;
+      }
+      postdel('temp/deletes', selectedRowKeys.value).then(() => {
+        loadData();
+      })
+    };
+    const add = () => {
+      tabsViewStore.addTabByPath('/query/index', {});
+    };
+    const edit = (key: string) => {
+      tabsViewStore.addTabByPath('/query/index', {tempId: key});
+    };
+    const onSelectChange = (keys: any) => {
+      selectedRowKeys.value = keys;
+    };
+    return {
+      router,
+      route,
+      expand,
+      formRef,
+      formState,
+      columns,data,loading,selectedRowKeys,
+      pagination,
+      handleTableChange,
+      onSelectChange,
+      onFinish,
+      loadData,
+      add,
+      edit,onDelete
+    };
+  },
+  created() {
+    this.loadData();
+  },
+  activated() {
+    if (history.state.params?.reload)
+      this.loadData();
+  }
+});
+</script>