瀏覽代碼

Merge remote-tracking branch 'origin/master'

yusm 3 月之前
父節點
當前提交
f6760cb22f
共有 21 個文件被更改,包括 1681 次插入131 次删除
  1. 37 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/AIQuestionController.java
  2. 6 3
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/TableColumnController.java
  3. 42 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/AIQuestion.java
  4. 86 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/AIQuestionDetail.java
  5. 36 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/ColumnFixTrans.java
  6. 61 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/CustomMultipartFile.java
  7. 59 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/ExcelMultipartFile.java
  8. 1 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/FormTransColumn.java
  9. 44 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/bo/QuestionBO.java
  10. 13 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/ColumnAliasVO.java
  11. 7 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/AIQuestionDetailMapper.java
  12. 7 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/AIQuestionMapper.java
  13. 7 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/ColumnFixTransMapper.java
  14. 2 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/CusTableColumnMapper.java
  15. 37 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/provider/CusTableColumnProvider.java
  16. 15 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/AIQuestionService.java
  17. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CusTableColumnService.java
  18. 500 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/AIQuestionServiceImpl.java
  19. 627 125
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CusTableColumnServiceImpl.java
  20. 89 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/util/ExcelConverter.java
  21. 4 0
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/application.yml

+ 37 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/AIQuestionController.java

@@ -0,0 +1,37 @@
+package com.management.platform.controller;
+
+import com.management.platform.entity.bo.QuestionBO;
+import com.management.platform.service.AIQuestionService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/aiQuestion")
+public class AIQuestionController {
+
+    @Resource
+    private AIQuestionService aiQuestionService;
+
+    @PostMapping("/ask")
+    public HttpRespMsg ask(QuestionBO questionBO
+            , HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        msg = aiQuestionService.ask(questionBO,request);
+        return msg;
+    }
+
+    @PostMapping("/downloadContent")
+    public ResponseEntity<byte[]> downloadContent(@RequestParam(value = "questionId")Integer questionId
+            , HttpServletRequest request){
+        ResponseEntity<byte[]> responseEntity = aiQuestionService.downloadContent(questionId, request);
+        return responseEntity;
+    }
+
+}

+ 6 - 3
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/TableColumnController.java

@@ -15,7 +15,7 @@ import javax.servlet.http.HttpServletRequest;
 
 @RestController
 @RequestMapping("/tableColumn")
-public class TableColumnController {
+public class CusTableColumnController {
 
     @Resource
     private CusTableColumnService cusTableColumnService;
@@ -34,9 +34,12 @@ public class TableColumnController {
     }
 
     @PostMapping("/getResByFormJson")
-    public HttpRespMsg getResByFormJson(@RequestParam("formJson") String formJson,HttpServletRequest request){
+    public HttpRespMsg getResByFormJson(@RequestParam("formJson") String formJson
+            ,@RequestParam(value = "formTransConditionJson",required = false)String formTransConditionJson
+            ,@RequestParam(value = "formFieldHead") String formFieldHead
+            ,HttpServletRequest request){
         HttpRespMsg msg = new HttpRespMsg();
-        msg = cusTableColumnService.getResByFormJson(formJson,request);
+        msg = cusTableColumnService.getResByFormJson(formJson,formTransConditionJson,formFieldHead,request);
         return msg;
     }
 

+ 42 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/AIQuestion.java

@@ -0,0 +1,42 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("ai_question")
+public class AIQuestion extends Model<AIQuestion> {
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "question_id",type = IdType.AUTO)
+    private Integer questionId;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 创建人
+     */
+    @TableField("creator_id")
+    private String creatorId;
+}

+ 86 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/AIQuestionDetail.java

@@ -0,0 +1,86 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("ai_question_detail")
+public class AIQuestionDetail extends Model<AIQuestionDetail> {
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "detail_id",type = IdType.AUTO)
+    private Integer detailId;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+    @TableField("question_id")
+    private Integer questionId;
+
+    /**对话类型 0ai 1客户*/
+    @TableField("type")
+    private Integer type;
+
+    /**对话内容*/
+    @TableField("content")
+    private String content;
+
+    /**排序*/
+    @TableField("seq")
+    private Integer seq;
+
+    /**数据来源 1系统表 2自定义报表 3本地上传 4自由对话*/
+    @TableField("question_data_source")
+    private Integer questionDataSource;
+
+    /**来源内容 系统表存表名 报表存formId 文件存文件名*/
+    @TableField("source_content")
+    private String sourceContent;
+
+    /**文件路径*/
+    @TableField("url")
+    private String url;
+
+    /**
+     * 系统表查询的开始时间
+     */
+    @TableField("start_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date startDate;
+
+    /**
+     * 系统表查询的结束时间
+     */
+    @TableField("end_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date endDate;
+
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /**
+     * 创建人
+     */
+    @TableField("creator_id")
+    private String creatorId;
+}

+ 36 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/ColumnFixTrans.java

@@ -0,0 +1,36 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ColumnFixTrans extends Model<ColumnFixTrans> {
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**表名*/
+    @TableField("tbl_name")
+    private String tblName;
+
+    /**字段名*/
+    @TableField("col_name")
+    private String colName;
+
+    /**值*/
+    @TableField("col_val")
+    private String colVal;
+
+    /**值对应含义*/
+    @TableField("val_mean")
+    private String valMean;
+
+}

+ 61 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/CustomMultipartFile.java

@@ -0,0 +1,61 @@
+package com.management.platform.entity;
+
+import org.springframework.web.multipart.MultipartFile;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class CustomMultipartFile implements MultipartFile {
+
+    private final byte[] content;
+    private final String name;
+    private final String originalFilename;
+    private final String contentType;
+
+    public CustomMultipartFile(byte[] content, String name, String originalFilename, String contentType) {
+        this.content = content;
+        this.name = name;
+        this.originalFilename = originalFilename;
+        this.contentType = contentType;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getOriginalFilename() {
+        return originalFilename;
+    }
+
+    @Override
+    public String getContentType() {
+        return contentType;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return content == null || content.length == 0;
+    }
+
+    @Override
+    public long getSize() {
+        return content.length;
+    }
+
+    @Override
+    public byte[] getBytes() throws IOException {
+        return content;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return new ByteArrayInputStream(content);
+    }
+
+    @Override
+    public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
+        new java.io.FileOutputStream(dest).write(content);
+    }
+}

+ 59 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/ExcelMultipartFile.java

@@ -0,0 +1,59 @@
+package com.management.platform.entity;
+
+import org.springframework.web.multipart.MultipartFile;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ExcelMultipartFile implements MultipartFile {
+
+    private final byte[] excelBytes;
+    private final String fileName;
+
+    public ExcelMultipartFile(byte[] excelBytes, String fileName) {
+        this.excelBytes = excelBytes;
+        this.fileName = fileName;
+    }
+
+    @Override
+    public String getName() {
+        return "file";
+    }
+
+    @Override
+    public String getOriginalFilename() {
+        return fileName;
+    }
+
+    @Override
+    public String getContentType() {
+        return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return excelBytes == null || excelBytes.length == 0;
+    }
+
+    @Override
+    public long getSize() {
+        return excelBytes.length;
+    }
+
+    @Override
+    public byte[] getBytes() throws IOException {
+        return excelBytes;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return new ByteArrayInputStream(excelBytes);
+    }
+
+    @Override
+    public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
+        try (java.io.FileOutputStream fos = new java.io.FileOutputStream(dest)) {
+            fos.write(excelBytes);
+        }
+    }
+}

+ 1 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/FormTransColumn.java

@@ -11,6 +11,7 @@ import lombok.experimental.Accessors;
 @Data
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
+/**需转义字段*/
 public class FormTransColumn extends Model<FormTransColumn> {
     private static final long serialVersionUID=1L;
 

+ 44 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/bo/QuestionBO.java

@@ -0,0 +1,44 @@
+package com.management.platform.entity.bo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Date;
+
+@Data
+public class QuestionBO {
+
+    /**问题id*/
+    private Integer questionId;
+
+    /**数据来源 1系统表 2自定义报表 3本地上传 4自由对话*/
+    private Integer questionDataSource;
+
+    /**来源内容 系统表存表名 报表存formId 文件存文件名*/
+    private String sourceContent;
+//    private String tblName;
+//
+//    private Integer formId;
+
+    private String url;
+
+    /**提问内容*/
+    private String content;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
+    private Date startDate;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
+    private Date endDate;
+
+
+    private MultipartFile file;
+
+
+
+
+}

+ 13 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/ColumnAliasVO.java

@@ -0,0 +1,13 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+@Data
+public class ColumnAliasVO {
+    /**字段 中文别名*/
+    private String columnCHN;
+    /**字段 表名.字段名*/
+    private String columnTblName;
+    /**字段 别名.字段名*/
+    private String columnAliasName;
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/AIQuestionDetailMapper.java

@@ -0,0 +1,7 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.AIQuestionDetail;
+
+public interface AIQuestionDetailMapper extends BaseMapper<AIQuestionDetail> {
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/AIQuestionMapper.java

@@ -0,0 +1,7 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.AIQuestion;
+
+public interface AIQuestionMapper extends BaseMapper<AIQuestion> {
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/ColumnFixTransMapper.java

@@ -0,0 +1,7 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.ColumnFixTrans;
+
+public interface ColumnFixTransMapper extends BaseMapper<ColumnFixTrans> {
+}

+ 2 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/mapper/CusTableColumnMapper.java

@@ -1,6 +1,7 @@
 package com.management.platform.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.BusObjRelation;
 import com.management.platform.entity.CusTableColumn;
 import com.management.platform.provider.CusTableColumnProvider;
 import org.apache.ibatis.annotations.Mapper;
@@ -12,7 +13,7 @@ import java.util.List;
 public interface CusTableColumnMapper extends BaseMapper<CusTableColumn> {
 
     @SelectProvider(type = CusTableColumnProvider.class,method = "getStructByTableName")
-    List<CusTableColumn> getStructByTableName(String tableName);
+    List<CusTableColumn> getStructByTableName(String tableName,List<BusObjRelation> busObjRelations);
 
     @SelectProvider(type = CusTableColumnProvider.class,method = "getTableAliasByTableName")
     String getTableAliasByTableName(String tableName);

+ 37 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/provider/CusTableColumnProvider.java

@@ -1,7 +1,24 @@
 package com.management.platform.provider;
 
+import com.management.platform.entity.BusObjRelation;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
 public class CusTableColumnProvider {
-    public String getStructByTableName(String tableName){
+
+    public static List<String> EXCLUDE_COLUMNS = new ArrayList<>();
+    static {
+        EXCLUDE_COLUMNS.add("is_active");
+        EXCLUDE_COLUMNS.add("is_ops");
+        EXCLUDE_COLUMNS.add("is_first_login");
+        EXCLUDE_COLUMNS.add("is_mob_first_login");
+        EXCLUDE_COLUMNS.add("only_audit_once");
+        EXCLUDE_COLUMNS.add("cost_apply_date");
+    }
+
+    public String getStructByTableName(String tableName, List<BusObjRelation> busObjRelations){
         StringBuilder stringBuilder = new StringBuilder();
         stringBuilder
                 .append("SELECT * FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA=(SELECT DATABASE()) AND TABLE_NAME = ")
@@ -9,7 +26,26 @@ public class CusTableColumnProvider {
                 .append(tableName).append("'")
                 .append(" AND COLUMN_NAME not like '%_id%' AND COLUMN_NAME not like '%id%' ")
                 .append(" AND COLUMN_NAME not like '%seq%'")
+                .append(" AND COLUMN_NAME not like '%plate%'")
         ;
+
+        if(CollectionUtils.isNotEmpty(EXCLUDE_COLUMNS)){
+            stringBuilder.append(" AND COLUMN_NAME not in (");
+            for (String excludeColumn : EXCLUDE_COLUMNS) {
+                stringBuilder.append("'").append(excludeColumn).append("',");
+            }
+            stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
+            stringBuilder.append(") ");
+        }
+
+        if(CollectionUtils.isNotEmpty(busObjRelations)){
+            stringBuilder.append(" AND COLUMN_NAME not in (");
+            for (BusObjRelation busObjRelation : busObjRelations) {
+                stringBuilder.append("'").append(busObjRelation.getFromCol()).append("',");
+            }
+            stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
+            stringBuilder.append(") ");
+        }
         return stringBuilder.toString();
     }
 

+ 15 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/AIQuestionService.java

@@ -0,0 +1,15 @@
+package com.management.platform.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.AIQuestion;
+import com.management.platform.entity.bo.QuestionBO;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.http.ResponseEntity;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface AIQuestionService extends IService<AIQuestion> {
+    HttpRespMsg ask(QuestionBO questionBO, HttpServletRequest request);
+
+    ResponseEntity<byte[]> downloadContent(Integer questionId, HttpServletRequest request);
+}

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/CusTableColumnService.java

@@ -34,7 +34,7 @@ public interface CusTableColumnService extends IService<CusTableColumn> {
 
     HttpRespMsg getAllStoresTree(HttpServletRequest request);
 
-    HttpRespMsg getResByFormJson(String formJson, HttpServletRequest request);
+    HttpRespMsg getResByFormJson(String formJson, String formTransConditionJson,String formFieldHead,HttpServletRequest request);
 
     HttpRespMsg getFormJsonByFormId(Integer formId, HttpServletRequest request);
 

+ 500 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/AIQuestionServiceImpl.java

@@ -0,0 +1,500 @@
+package com.management.platform.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.entity.*;
+import com.management.platform.entity.bo.QuestionBO;
+import com.management.platform.mapper.*;
+import com.management.platform.service.AIQuestionService;
+import com.management.platform.service.CusTableColumnService;
+import com.management.platform.service.ExcelExportService;
+import com.management.platform.util.ExcelConverter;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.poi.xwpf.usermodel.BreakType;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.*;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.sql.DataSource;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.*;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.stream.Collectors;
+
+@Service
+public class AIQuestionServiceImpl extends ServiceImpl<AIQuestionMapper, AIQuestion>  implements AIQuestionService {
+
+    @Value("${aiask.fileaskurl}")
+    private String aiFileAskUrl;
+
+    @Value("${aiask.askurl}")
+    private String aiAskUrl;
+
+    @Resource
+    private AIQuestionMapper aiQuestionMapper;
+
+    @Resource
+    private AIQuestionDetailMapper aiQuestionDetailMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private BusObjRelationMapper busObjRelationMapper;
+
+    @Resource
+    private CusTableColumnMapper cusTableColumnMapper;
+
+    @Resource
+    private ExcelExportService excelExportService;
+
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+
+    @Resource
+    private CusReportFormMapper cusReportFormMapper;
+
+    @Resource
+    private CusTableColumnService cusTableColumnService;
+
+    @Resource
+    private DataSource dataSource;
+
+    @Value(value = "${upload.path}")
+    private String path;
+
+    /**将备注名作为别名 并剔除掉 shortName*/
+    public static List<Map<String, Object>> convertListWithComment(ResultSet rs,Map<String, String> columnCommentMap) {
+        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+        try {
+            ResultSetMetaData md = rs.getMetaData();
+            int columnCount = md.getColumnCount();
+            while (rs.next()) {
+                Map<String, Object> rowData = new HashMap<String, Object>();
+                for (int i = 1; i <= columnCount; i++) {
+                    String columnName = md.getColumnName(i);
+                    String columnComment = columnCommentMap.get(columnName);
+                    if(columnComment.length()>10){
+                        Matcher matcher = CusTableColumnServiceImpl.COMMENT_SIGN_PATTERN.matcher(columnComment);
+                        if(matcher.find()){
+                            columnComment = matcher.group(1);
+                        }
+                    }else{
+                        int index = columnComment.indexOf("shortName");
+                        if(-1 != index){
+                            String trim = columnComment.substring(0, i).trim();
+                            columnComment = trim;
+                        }
+                    }
+                    rowData.put(columnComment,rs.getObject(i));
+                }
+                list.add(rowData);
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (rs != null)
+                    rs.close();
+                rs = null;
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+        return list;
+    }
+
+    public MultipartFile getMultipartFileFromPath(String filePath) throws IOException {
+        Path path = Paths.get(filePath);
+        String fileName = path.getFileName().toString();
+        String contentType = Files.probeContentType(path);
+        byte[] content = Files.readAllBytes(path);
+
+        return new MockMultipartFile(
+                fileName,
+                fileName,
+                contentType,
+                content
+        );
+    }
+
+    public ByteArrayResource getFileByteArrayResource(List<Map<String,Object>> columnList,String fileName) {
+        ByteArrayResource byteArrayResource = null;
+        try {
+            // 2. 转换为Excel格式的MultipartFile
+            MultipartFile excelFile = ExcelConverter.convertToExcel(
+                    columnList,
+                    fileName);
+            //下载到本地 TODO 生产环境注释
+//            excelFile.transferTo(new java.io.File(fileName));
+            byteArrayResource = new ByteArrayResource(excelFile.getBytes()) {
+                @Override
+                public String getFilename() {
+                    return excelFile.getOriginalFilename();
+                }
+            };
+        }catch (IOException e){
+            e.printStackTrace();
+        }
+        return byteArrayResource;
+    }
+
+    @Async
+    public ResponseEntity<String> getResponseEntityWithFileAI(List<Map<String,Object>> columnList,String question){
+//        String uploadUrl = aiFileAskUrl;
+        RestTemplate restTemplate = new RestTemplate();
+        //转换为MultipartFile 准备表单数据
+        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
+        body.add("question", question);
+        String fileName = "提问数据"+System.currentTimeMillis()+".xlsx";
+        ByteArrayResource fileByteArrayResource = getFileByteArrayResource(columnList, fileName);
+        body.add("file",fileByteArrayResource);
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+        HttpEntity<MultiValueMap<String, Object>> requestEntity =
+                new HttpEntity<>(body, headers);
+        ResponseEntity<String> response = restTemplate.exchange(
+                aiFileAskUrl,
+                HttpMethod.POST,
+                requestEntity,
+                String.class);
+        return response;
+    }
+
+    @Override
+    @Transactional
+    public HttpRespMsg ask(QuestionBO questionBO, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+
+        String queryRes = "";
+        if(1 == questionBO.getQuestionDataSource()){
+            /**
+             * 系统表
+             * 查询表结构 获取字段对应备注
+             * 查询内容并添加create_time 范围
+             * select 字段名 as '别名' 作为表头
+             */
+
+            String tableName = questionBO.getSourceContent();
+
+            //排除relation表中的关联字段
+            List<BusObjRelation> busObjRelations = busObjRelationMapper.selectList(new LambdaQueryWrapper<BusObjRelation>()
+                    .eq(BusObjRelation::getFromTbl, tableName)
+            );
+            List<CusTableColumn> checkColumns = cusTableColumnMapper.getStructByTableName(tableName,busObjRelations);
+            //映射字段和comment
+            Map<String, String> columnCommentMap = checkColumns.stream().collect(Collectors.toMap(CusTableColumn::getColumnName, CusTableColumn::getColumnComment));
+
+            StringBuilder stringBuilder = new StringBuilder();
+            stringBuilder.append(" select ");
+            for (String key : columnCommentMap.keySet()) {
+                stringBuilder.append(" ").append(key).append(",");
+            }
+            stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
+            stringBuilder.append(" from ")
+                    .append(tableName)
+                    .append(" where company_id =")
+                    .append(user.getCompanyId());
+            if(null != questionBO.getStartDate() && null != questionBO.getEndDate()){
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                stringBuilder.append(" and date_format(create_time,'%Y-%m-%d') between ")
+                        .append("'").append(sdf.format(questionBO.getStartDate())).append("'")
+                        .append(" and ")
+                        .append("'").append(sdf.format(questionBO.getEndDate())).append("'");
+            }
+
+            List<Map<String,Object>> columnList = new ArrayList<>();
+            try (Connection connection = dataSource.getConnection()) {
+                PreparedStatement preparedStatement = connection.prepareStatement(stringBuilder.toString());
+                ResultSet resultSet = preparedStatement.executeQuery();
+                columnList = this.convertListWithComment(resultSet,columnCommentMap);
+            }catch (SQLException e) {
+                e.printStackTrace();
+                httpRespMsg.setError("查询系统表有误,请联系管理员");
+                return httpRespMsg;
+            }
+
+            if(CollectionUtils.isNotEmpty(columnList)){
+                ResponseEntity<String> responseEntity = getResponseEntityWithFileAI(columnList, questionBO.getContent());
+                if(responseEntity.getStatusCode().is2xxSuccessful()){
+                    JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
+                    System.out.println("jsonObject=== "+jsonObject);
+                    queryRes = jsonObject.getString("data");
+                }else{
+                    queryRes = "AI分析有误,稍后再试";
+                }
+            }else{
+                queryRes = "无数据";
+            }
+
+        } else if (2 == questionBO.getQuestionDataSource()) {
+            /**
+             * 自定义报表
+             * 查询formId对应的sql,获取返回结果 封装为表格
+             */
+            HttpRespMsg respMsg = cusTableColumnService.getFormResByFormId(Integer.parseInt(questionBO.getSourceContent()), request);
+            if(respMsg.getCode().equals("ok")){
+                List<Map<String,Object>> resColumnList = (List<Map<String, Object>>) respMsg.getData();
+                if(CollectionUtils.isNotEmpty(resColumnList)){
+                    ResponseEntity<String> responseEntity = getResponseEntityWithFileAI(resColumnList, questionBO.getContent());
+                    if(responseEntity.getStatusCode().is2xxSuccessful()){
+                        JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
+                        System.out.println("jsonObject=== "+jsonObject);
+                        queryRes = jsonObject.getString("data");
+                    }else{
+                        queryRes = "AI分析有误,稍后再试";
+                    }
+                }else{
+                    queryRes = "无数据";
+                }
+            }
+
+        } else if (3 == questionBO.getQuestionDataSource()) {
+            /**
+             * 获取url 读取文件内容并返回
+             */
+            RestTemplate restTemplate = new RestTemplate();
+            //转换为MultipartFile 准备表单数据
+            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
+            body.add("question", questionBO.getContent());
+            ByteArrayResource byteArrayResource = null;
+            try {
+                MultipartFile multipartFileFromPath = getMultipartFileFromPath(questionBO.getUrl());
+                byteArrayResource = new ByteArrayResource(multipartFileFromPath.getBytes()) {
+                    @Override
+                    public String getFilename() {
+                        return multipartFileFromPath.getOriginalFilename();
+                    }
+                };
+            }catch (IOException e){
+                e.printStackTrace();
+            }
+            body.add("file",byteArrayResource);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+            HttpEntity<MultiValueMap<String, Object>> requestEntity =
+                    new HttpEntity<>(body, headers);
+            ResponseEntity<String> response = restTemplate.exchange(
+                    aiFileAskUrl,
+                    HttpMethod.POST,
+                    requestEntity,
+                    String.class);
+            if(response.getStatusCode().is2xxSuccessful()){
+                JSONObject jsonObject = JSONObject.parseObject(response.getBody());
+                System.out.println("jsonObject=== "+jsonObject);
+                queryRes = jsonObject.getString("data");
+            }else{
+                queryRes = "AI分析有误,稍后再试";
+            }
+
+        }else{
+            // 自由对话
+            RestTemplate restTemplate = new RestTemplate();
+            //转换为MultipartFile 准备表单数据
+            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
+            body.add("question", questionBO.getContent());
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+
+            HttpEntity<MultiValueMap<String, Object>> requestEntity =
+                    new HttpEntity<>(body, headers);
+            ResponseEntity<String> response = restTemplate.exchange(
+                    aiFileAskUrl,
+                    HttpMethod.POST,
+                    requestEntity,
+                    String.class);
+            if(response.getStatusCode().is2xxSuccessful()){
+                JSONObject jsonObject = JSONObject.parseObject(response.getBody());
+                System.out.println("jsonObject=== "+jsonObject);
+                queryRes = jsonObject.getString("data");
+            }else{
+                queryRes = "AI分析有误,稍后再试";
+            }
+        }
+
+        if(null == questionBO.getQuestionId()){
+            //提问获取回答,再插入
+            AIQuestion aiQuestion = new AIQuestion();
+            aiQuestion.setCompanyId(user.getCompanyId());
+            aiQuestion.setCreatorId(user.getId());
+            aiQuestionMapper.insert(aiQuestion);
+
+            Integer questionId = aiQuestion.getQuestionId();
+            AIQuestionDetail cusAsk = new AIQuestionDetail();
+            cusAsk.setCreatorId(user.getId());
+            cusAsk.setCompanyId(user.getCompanyId());
+            cusAsk.setSeq(1);
+            cusAsk.setQuestionId(questionId);
+            cusAsk.setType(1);
+            cusAsk.setContent(questionBO.getContent());
+            cusAsk.setQuestionDataSource(questionBO.getQuestionDataSource());
+            cusAsk.setSourceContent(questionBO.getSourceContent());
+            cusAsk.setStartDate(questionBO.getStartDate());
+            cusAsk.setEndDate(questionBO.getEndDate());
+            aiQuestionDetailMapper.insert(cusAsk);
+
+            AIQuestionDetail aiAnswer = new AIQuestionDetail();
+            aiAnswer.setCreatorId(user.getId());
+            aiAnswer.setCompanyId(user.getCompanyId());
+            aiAnswer.setSeq(2);
+            aiAnswer.setQuestionId(questionId);
+            aiAnswer.setType(0);
+            aiAnswer.setContent(queryRes);
+            aiAnswer.setQuestionDataSource(questionBO.getQuestionDataSource());
+            aiAnswer.setSourceContent(questionBO.getSourceContent());
+            aiAnswer.setStartDate(questionBO.getStartDate());
+            aiAnswer.setEndDate(questionBO.getEndDate());
+            aiQuestionDetailMapper.insert(aiAnswer);
+        } else {
+            Integer questionId = questionBO.getQuestionId();
+            AIQuestionDetail lastOne = aiQuestionDetailMapper.selectOne(new LambdaQueryWrapper<AIQuestionDetail>()
+                    .eq(AIQuestionDetail::getCompanyId, user.getCompanyId())
+                    .eq(AIQuestionDetail::getQuestionId, questionId)
+                    .orderByDesc(AIQuestionDetail::getSeq)
+                    .last(" limit 1 ")
+            );
+            Integer startSeq = 0;
+            if(null != lastOne){
+                startSeq = lastOne.getSeq();
+            }
+            AIQuestionDetail cusAsk = new AIQuestionDetail();
+            cusAsk.setCreatorId(user.getId());
+            cusAsk.setCompanyId(user.getCompanyId());
+            cusAsk.setSeq(startSeq+1);
+            cusAsk.setQuestionId(questionId);
+            cusAsk.setType(1);
+            cusAsk.setContent(questionBO.getContent());
+            cusAsk.setQuestionDataSource(questionBO.getQuestionDataSource());
+            cusAsk.setSourceContent(questionBO.getSourceContent());
+            cusAsk.setStartDate(questionBO.getStartDate());
+            cusAsk.setEndDate(questionBO.getEndDate());
+            aiQuestionDetailMapper.insert(cusAsk);
+
+            AIQuestionDetail aiAnswer = new AIQuestionDetail();
+            aiAnswer.setCreatorId(user.getId());
+            aiAnswer.setCompanyId(user.getCompanyId());
+            aiAnswer.setSeq(startSeq+2);
+            aiAnswer.setQuestionId(questionId);
+            aiAnswer.setType(0);
+            aiAnswer.setContent(queryRes);
+            aiAnswer.setQuestionDataSource(questionBO.getQuestionDataSource());
+            aiAnswer.setSourceContent(questionBO.getSourceContent());
+            aiAnswer.setStartDate(questionBO.getStartDate());
+            aiAnswer.setEndDate(questionBO.getEndDate());
+            aiQuestionDetailMapper.insert(aiAnswer);
+
+        }
+
+        httpRespMsg.setData(queryRes);
+        return httpRespMsg;
+    }
+
+    @Override
+    public ResponseEntity<byte[]> downloadContent(Integer questionId, HttpServletRequest request) {
+//        AIQuestionDetail aiQuestionDetail = aiQuestionDetailMapper.selectById(detailId);
+//        String content = aiQuestionDetail.getContent();
+
+        List<AIQuestionDetail> aiQuestionDetails = aiQuestionDetailMapper.selectList(new LambdaQueryWrapper<AIQuestionDetail>()
+                .eq(AIQuestionDetail::getQuestionId, questionId)
+                .orderByAsc(AIQuestionDetail::getSeq)
+        );
+
+        // 创建Word文档
+        XWPFDocument document = new XWPFDocument();
+
+        // 添加内容
+        if(CollectionUtils.isNotEmpty(aiQuestionDetails)){
+            int index = 0;
+            for (AIQuestionDetail aiQuestionDetail : aiQuestionDetails) {
+                XWPFParagraph paragraph = document.createParagraph();
+                XWPFRun run = paragraph.createRun();
+                run.setText(aiQuestionDetail.getContent());
+                run.setFontSize(12);
+                run.setFontFamily("Arial");
+
+                if (index< aiQuestionDetails.size() - 1) {
+                    run.addBreak(BreakType.TEXT_WRAPPING);
+                }
+                index++;
+            }
+        }
+
+
+        // 将文档写入字节数组
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            document.write(out);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }finally {
+            try {
+                document.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+
+        // 设置响应头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+        headers.setContentDispositionFormData("attachment", "data.docx");
+
+        return ResponseEntity.ok()
+                .headers(headers)
+                .body(out.toByteArray());
+    }
+
+    public static List<Map<String, Object>> convertListWithAlias(ResultSet rs) {
+        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
+        try {
+            ResultSetMetaData md = rs.getMetaData();
+            int columnCount = md.getColumnCount();
+            while (rs.next()) {
+                Map<String, Object> rowData = new HashMap<String, Object>();
+                for (int i = 1; i <= columnCount; i++) {
+                    rowData.put(md.getColumnLabel(i), rs.getObject(i));
+                }
+                list.add(rowData);
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (rs != null)
+                    rs.close();
+                rs = null;
+            } catch (SQLException e) {
+                e.printStackTrace();
+            }
+        }
+        return list;
+    }
+}

+ 627 - 125
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CusTableColumnServiceImpl.java

@@ -1,7 +1,9 @@
 package com.management.platform.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -10,16 +12,12 @@ import com.management.platform.entity.bo.FormStorePageBO;
 import com.management.platform.entity.vo.SysRichFunction;
 import com.management.platform.mapper.*;
 import com.management.platform.service.CusTableColumnService;
+import com.management.platform.service.ExcelExportService;
 import com.management.platform.service.WxCorpInfoService;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -28,8 +26,6 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.sql.DataSource;
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.sql.*;
 import java.util.Date;
 import java.util.*;
@@ -79,6 +75,12 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
     @Resource
     private WxCorpInfoMapper wxCorpInfoMapper;
 
+    @Resource
+    private ExcelExportService excelExportService;
+
+    @Resource
+    private ColumnFixTransMapper columnFixTransMapper;
+
     @Autowired
     private DataSource dataSource;
 
@@ -102,6 +104,10 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
 
     public static final Pattern INSERT_SIGN_PATTERN = Pattern.compile(REGEX_INSERT_SIGN);
 
+    public static final String REGEX_COMMENT_SIGN = "shortName\\((.*?)\\)";
+
+    public static final Pattern COMMENT_SIGN_PATTERN = Pattern.compile(REGEX_COMMENT_SIGN);
+
     @Value(value = "${upload.path}")
     private String path;
 
@@ -129,7 +135,29 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
 
         Map<String,Object> resMap = new HashMap<>();
         resMap.put("busObject",busObject);
-        List<CusTableColumn> columnList = cusTableColumnMapper.getStructByTableName(tableName);
+
+        //排除relation表中的关联字段
+        List<BusObjRelation> busObjRelations = busObjRelationMapper.selectList(new LambdaQueryWrapper<BusObjRelation>()
+                .eq(BusObjRelation::getFromTbl, tableName)
+        );
+        List<CusTableColumn> columnList = cusTableColumnMapper.getStructByTableName(tableName,busObjRelations);
+
+        //超过10个字段长度取shortName
+        for (CusTableColumn cusTableColumn : columnList) {
+            String columnComment = cusTableColumn.getColumnComment();
+            if(cusTableColumn.getColumnComment().length()>10){
+                Matcher matcher = COMMENT_SIGN_PATTERN.matcher(columnComment);
+                if(matcher.find()){
+                    cusTableColumn.setColumnComment(matcher.group(1));
+                }
+            }else{
+                int i = columnComment.indexOf("shortName");
+                if(-1 != i){
+                    String trim = columnComment.substring(0, i).trim();
+                    cusTableColumn.setColumnComment(trim);
+                }
+            }
+        }
 
         //字段转义提示
         if(1 == user.getUserNameNeedTranslate()){ //TODO user.getUserNameNeedTranslate()
@@ -316,42 +344,52 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
             msg.setError("主业务表无法识别,请联系管理员");
             return msg;
         }
-//        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
         if(StringUtils.isNotBlank(tableAlias) && StringUtils.isNotBlank(tableName)){
             String s = cusReportForm.getExecuteSql()+" and "+tableAlias+".company_id="+user.getCompanyId()+" ";
-
-//            List<FormTransCondition> formTransConditions = JSONObject.parseArray(cusReportForm.getFormTransConditionJson(), FormTransCondition.class);
-//            for (FormTransCondition formTransCondition : formTransConditions) {
-//                String str = formTransCondition.getTblAlias()+"."+formTransCondition.getColName();
-//                String replaceObj = str+" like concat('%','"+formTransCondition.getUseVal()+"','%')";
-//                if(1 == formTransCondition.getTransType()){
-//                    HashMap<String, List> result = null;
-//                    try {
-//                        result = wxCorpInfoService.getOpenId(wxCorpInfo.getCorpid(), formTransCondition.getUseVal(), null,1,200);
-//                    } catch (Exception e) {
-//                        e.printStackTrace();
-//                        msg.setError("企微转义有误,请联系管理员");
-//                        return msg;
-//                    }
-//                    List users = result.get("user");
-//                    List<User> realUser = userMapper.getUserByDepartment(null, user.getCompanyId(), null,null, null, null, null, users);
-//                    String replaceStr = str+" in(";
-//                    int count = 0;
-//                    for (User tmpUser : realUser) {
-//                        replaceStr += "'"+tmpUser.getName()+"'";
-//                        count++;
-//                        if(count<realUser.size()){
-//                            replaceStr += ", ";
-//                        }
-//                    }
-//                    replaceStr +=") ";
-//
-//                    s.replace(replaceObj,replaceStr);
-//
-//                } else if (2 == formTransCondition.getTransType()) {
-//
-//                }
-//            }
+            if(null != wxCorpInfo && 1 == wxCorpInfo.getSaasSyncContact()){
+                List<FormTransCondition> formTransConditions = JSONObject.parseArray(cusReportForm.getFormTransConditionJson(), FormTransCondition.class);
+                for (FormTransCondition formTransCondition : formTransConditions) {
+                    String str = formTransCondition.getTblAlias()+"."+formTransCondition.getColName();
+                    String replaceObj = str+" like concat('%','"+formTransCondition.getUseVal()+"','%')";
+                    if(1 == formTransCondition.getTransType()){
+                        HashMap<String, List> result = null;
+                        try {
+                            result = wxCorpInfoService.getOpenId(wxCorpInfo.getCorpid(), formTransCondition.getUseVal(), null,1,200);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            msg.setError("企微转义有误,请联系管理员");
+                            return msg;
+                        }
+                        List users = result.get("user");
+                        List<User> realUser = userMapper.getUserByDepartment(null, user.getCompanyId(), null,null, null, null, null, users);
+                        String replaceStr = str+" in(";
+                        int count = 0;
+                        for (User tmpUser : realUser) {
+                            replaceStr += "'"+tmpUser.getName()+"'";
+                            count++;
+                            if(count<realUser.size()){
+                                replaceStr += ", ";
+                            }
+                        }
+                        replaceStr +=") ";
+                        s.replace(replaceObj,replaceStr);
+                    } else if (2 == formTransCondition.getTransType()) {
+                        Integer deptWxId = null;
+                        try {
+                            deptWxId = wxCorpInfoService.searchCorpWxDeptId(wxCorpInfo.getCorpid(), formTransCondition.getUseVal());
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            msg.setError("企微转义有误,请联系管理员");
+                            return msg;
+                        }
+                        if(null != deptWxId){
+                            String replaceStr = str+" ="+deptWxId+" ";
+                            s.replace(replaceObj,replaceStr);
+                        }
+                    }
+                }
+            }
 
             cusReportForm.setExecuteSql(s);
 
@@ -650,6 +688,8 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
     public HttpRespMsg getFormResByFormId(Integer formId, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         List<Map<String,Object>> columnList = new ArrayList<>();
+        List<Map<String,Object>> resColumnList = new ArrayList<>();
+        User user = userMapper.selectById(request.getHeader("token"));
         CusReportForm cusReportForm = cusReportFormMapper.selectById(formId);
         if(null == cusReportForm){
             msg.setError("未找到该报表,请联系管理员");
@@ -665,7 +705,162 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
             msg.setError("SQL语句有误,请联系管理员");
             return msg;
         }
-        msg.setData(columnList);
+
+        //转换固定值
+        List<FormFieldHead> formFieldHeads = JSONArray.parseArray(cusReportForm.getFormFieldHead(), FormFieldHead.class);
+        List<ColumnFixTrans> columnFixTrans = columnFixTransMapper.selectList(null);
+        Map<String, List<ColumnFixTrans>> tableColumnFixTransMap = columnFixTrans.stream()
+                .collect(Collectors.groupingBy(ColumnFixTrans::getTblName));// key tblName
+
+        //根据表头获取 'xxx' --> 别名.字段名 --> 表名.字段名
+        Map<String, FormFieldHead> columnAliasMap = new HashMap<>();
+        for (FormFieldHead formFieldHead : formFieldHeads) {
+            columnAliasMap.put(formFieldHead.getColumnVal(),formFieldHead);
+        }
+
+        if(CollectionUtils.isNotEmpty(columnList)){
+
+            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, user.getCompanyId()));
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+
+            List<FormTransColumn> checkColumns = formTransColumnMapper.selectList(new LambdaQueryWrapper<FormTransColumn>());
+            Map<String, List<FormTransColumn>> tblColumnMap = new HashMap<>();
+            if(CollectionUtils.isNotEmpty(checkColumns)){
+                tblColumnMap = checkColumns.stream()
+                        .collect(Collectors.groupingBy(FormTransColumn::getTblName));
+            }
+
+            try {
+                resColumnList = this.getTransResColumns(columnList, formFieldHeads, columnAliasMap, tableColumnFixTransMap
+                        , tblColumnMap, userList, wxCorpInfo, tableColumnSql, user);
+            } catch (Exception e) {
+                e.printStackTrace();
+                msg.setError(e.getMessage());
+                return msg;
+            }
+
+
+//            Map<String,List<String>> indexMap = new HashMap<>(2);
+//            indexMap.put("userName",new ArrayList<>());
+//            indexMap.put("deptName",new ArrayList<>());
+//            Map<String,String> tableNameAliasMap = new HashMap<>();
+//            Matcher mainMatcher = MAIN_TABLE_PATTERN.matcher(tableColumnSql);
+//            if (mainMatcher.find()) {
+//                tableNameAliasMap.put(mainMatcher.group(1),mainMatcher.group(2));
+//            } else {
+//                msg.setError("主业务表无法识别,请联系管理员");
+//                return msg;
+//            }
+//
+//            Matcher joinMatcher = JOIN_TABLE_PATTERN.matcher(tableColumnSql);
+//            while (joinMatcher.find()){
+//                tableNameAliasMap.put(joinMatcher.group(1),joinMatcher.group(2));
+//            }
+//            for (String tableName : tableNameAliasMap.keySet()) {
+//                List<FormTransColumn> tmpColList = tblColumnMap.get(tableName);
+//                String tableAlias = tableNameAliasMap.get(tableName);
+//                if(CollectionUtils.isNotEmpty(tmpColList)){
+//                    for (FormTransColumn formTransColumn : tmpColList) {
+//                        String col = tableAlias+"."+formTransColumn.getColName();
+//                        if(tableColumnSql.contains(col)){
+//                            if(1 == formTransColumn.getTransType()){
+//                                //当前位置的是人名,需要转义
+//                                for (int i = 0; i < formFieldHeads.size(); i++) {
+//                                    if(formFieldHeads.get(i).getTableName().equals(tableName)
+//                                            &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+//                                    ){
+//                                        List<String> tmpList = indexMap.get("userName");
+//                                        tmpList.add(formFieldHeads.get(i).getColumnVal());
+//                                    }
+//                                }
+//                            }
+//                            else if (2 == formTransColumn.getTransType()) {
+//                                //当前位置是部门,需要转义
+//                                for (int i = 0; i < formFieldHeads.size(); i++) {
+//                                    if(formFieldHeads.get(i).getTableName().equals(tableName)
+//                                            &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+//                                    ){
+//                                        List<String> tmpList = indexMap.get("deptName");
+//                                        tmpList.add(formFieldHeads.get(i).getColumnVal());
+//                                    }
+//                                }
+//                            }
+//                        }
+//                    }
+//                }
+//            }
+//            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, user.getCompanyId()));
+//            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+//            for (Map<String, Object> data : columnList) {
+//                String valRes = "";
+//                Map<String,Object> map = new HashMap<>();
+//                for (String key : columnList.get(0).keySet()) {
+//                    //固定值转换
+//                    FormFieldHead formFieldHead = columnAliasMap.get(key);//字段对应别名和表
+//                    List<ColumnFixTrans> transColList = tableColumnFixTransMap.get(formFieldHead.getTableName());//固定值字段集合
+//                    List<ColumnFixTrans> currentFixValList = new ArrayList<>();
+//                    if(CollectionUtils.isNotEmpty(transColList)){
+//                        currentFixValList = transColList.stream()
+//                                .filter(t -> t.getColName().equals(formFieldHead.getColumnName()))
+//                                .collect(Collectors.toList());//当前字段固定值对照值
+//                    }
+//                    if(CollectionUtils.isNotEmpty(currentFixValList)){
+//                        Map<String, String> valMeanMap = currentFixValList.stream()
+//                                .collect(Collectors.toMap(ColumnFixTrans::getColVal, ColumnFixTrans::getValMean));
+//                        Object value = data.get(key);
+//                        if(null != value){
+//                            String mean = valMeanMap.get(value.toString());
+//                            valRes = mean;
+//                        }
+//                    }else{
+//                        //转义
+//                        List<String> userNameIndexes = indexMap.get("userName");
+//                        List<String> deptNameIndexes = indexMap.get("deptName");
+//                        if(1 == user.getUserNameNeedTranslate()){
+//                            Object value = data.get(key);
+//                            if (value == null) {
+//                            } else {
+//                                String val = value.toString();
+//                                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+//                                    if(CollectionUtils.isNotEmpty(userNameIndexes) && userNameIndexes.contains(key)){
+//                                        String name = val;
+//                                        Optional<User> first = userList.stream().filter(u -> u.getName().equals(name)).findFirst();
+//                                        if(first.isPresent()){
+//                                            val = "$userName="+first.get().getCorpwxUserid()+"$";
+//                                        }else {
+//                                            val = "";
+//                                        }
+//                                    }
+//
+//                                }
+//                                if(CollectionUtils.isNotEmpty(deptNameIndexes) && deptNameIndexes.contains(key)){
+//                                    String name = val;
+//                                    Optional<User> first = userList.stream().filter(u -> u.getName().equals(name)).findFirst();
+//                                    if(first.isPresent()){
+//                                        val = "$departmentName="+first.get().getCorpwxDeptid()+"$";
+//                                    }else {
+//                                        val = "";
+//                                    }
+//                                }
+//                                valRes = val;
+//                            }
+//                        }else{
+//                            Object value = data.get(key);
+//                            if (value == null) {
+//                                valRes = "";
+//                            } else {
+//                                valRes = value.toString();
+//                            }
+//                        }
+//                    }
+//                    map.put(key,valRes);
+//                    valRes = "";
+//                }
+//                resColumnList.add(map);
+//            }
+        }
+
+        msg.setData(resColumnList);
         return msg;
     }
 
@@ -716,18 +911,67 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
     }
 
     @Override
-    public HttpRespMsg getResByFormJson(String formJson, HttpServletRequest request) {
+    public HttpRespMsg getResByFormJson(String formSql,String formTransConditionJson,String formFieldHeads, HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         List<Map<String,Object>> columnList = new ArrayList<>();
-        Matcher deleteMatcher = DELETE_SGIN_PATTERN.matcher(formJson);
-        Matcher updateMatcher = UPDATE_SIGN_PATTERN.matcher(formJson);
-        Matcher insertMatcher = INSERT_SIGN_PATTERN.matcher(formJson);
+        Matcher deleteMatcher = DELETE_SGIN_PATTERN.matcher(formSql);
+        Matcher updateMatcher = UPDATE_SIGN_PATTERN.matcher(formSql);
+        Matcher insertMatcher = INSERT_SIGN_PATTERN.matcher(formSql);
         if (deleteMatcher.find() || updateMatcher.find() || insertMatcher.find()) {
             msg.setError("包含非法字符,无法执行");
             return msg;
         }
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        if(StringUtils.isNotBlank(formTransConditionJson)){
+            if(null != wxCorpInfo && 1 == wxCorpInfo.getSaasSyncContact()){
+                List<FormTransCondition> formTransConditions = JSONObject.parseArray(formTransConditionJson, FormTransCondition.class);
+                for (FormTransCondition formTransCondition : formTransConditions) {
+                    String str = formTransCondition.getTblAlias()+"."+formTransCondition.getColName();
+                    String replaceObj = str+" like concat('%','"+formTransCondition.getUseVal()+"','%')";
+                    if(1 == formTransCondition.getTransType()){
+                        HashMap<String, List> result = null;
+                        try {
+                            result = wxCorpInfoService.getOpenId(wxCorpInfo.getCorpid(), formTransCondition.getUseVal(), null,1,200);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            msg.setError("企微转义有误,请联系管理员");
+                            return msg;
+                        }
+                        List users = result.get("user");
+                        List<User> realUser = userMapper.getUserByDepartment(null, user.getCompanyId(), null,null, null, null, null, users);
+                        String replaceStr = str+" in(";
+                        int count = 0;
+                        for (User tmpUser : realUser) {
+                            replaceStr += "'"+tmpUser.getName()+"'";
+                            count++;
+                            if(count<realUser.size()){
+                                replaceStr += ", ";
+                            }
+                        }
+                        replaceStr +=") ";
+                        formSql.replace(replaceObj,replaceStr);
+                    } else if (2 == formTransCondition.getTransType()) {
+                        Integer deptWxId = null;
+                        try {
+                            deptWxId = wxCorpInfoService.searchCorpWxDeptId(wxCorpInfo.getCorpid(), formTransCondition.getUseVal());
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            msg.setError("企微转义有误,请联系管理员");
+                            return msg;
+                        }
+                        if(null != deptWxId){
+                            String replaceStr = str+" ="+deptWxId+" ";
+                            formSql.replace(replaceObj,replaceStr);
+                        }
+                    }
+                }
+            }
+        }
+
+        List<Map<String,Object>> resColumnList = new ArrayList<>();
         try (Connection connection = dataSource.getConnection()) {
-            PreparedStatement preparedStatement = connection.prepareStatement(formJson);
+            PreparedStatement preparedStatement = connection.prepareStatement(formSql);
             ResultSet resultSet = preparedStatement.executeQuery();
             columnList = this.convertListWithAlias(resultSet);
         }catch (SQLException e) {
@@ -735,7 +979,39 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
             msg.setError("SQL语句有误,请联系管理员");
             return msg;
         }
-        msg.setData(columnList);
+        if(CollectionUtils.isNotEmpty(columnList)){
+            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, user.getCompanyId()));
+            List<FormTransColumn> checkColumns = formTransColumnMapper.selectList(new LambdaQueryWrapper<FormTransColumn>());
+            Map<String, List<FormTransColumn>> tblColumnMap = new HashMap<>();
+            if(CollectionUtils.isNotEmpty(checkColumns)){
+                tblColumnMap = checkColumns.stream()
+                        .collect(Collectors.groupingBy(FormTransColumn::getTblName));
+            }
+            //转换固定值
+            Map<String, List<ColumnFixTrans>> tableColumnFixTransMap = new HashMap<>();
+            List<ColumnFixTrans> columnFixTrans = columnFixTransMapper.selectList(null);
+            tableColumnFixTransMap = columnFixTrans.stream()
+                    .collect(Collectors.groupingBy(ColumnFixTrans::getTblName));// key tblName
+            //根据表头获取 'xxx' --> 别名.字段名 --> 表名.字段名
+            List<FormFieldHead> formFieldHeadList = new ArrayList<>();
+            Map<String, FormFieldHead> columnAliasMap = new HashMap<>();
+            if(StringUtils.isNotBlank(formFieldHeads)){
+                formFieldHeadList = JSONArray.parseArray(formFieldHeads, FormFieldHead.class);
+                for (FormFieldHead formFieldHead : formFieldHeadList) {
+                    columnAliasMap.put(formFieldHead.getColumnVal(),formFieldHead);
+                }
+            }
+
+            try {
+                resColumnList = this.getTransResColumns(columnList, formFieldHeadList, columnAliasMap, tableColumnFixTransMap
+                        , tblColumnMap, userList, wxCorpInfo, formSql, user);
+            } catch (Exception e) {
+                e.printStackTrace();
+                msg.setError(e.getMessage());
+                return msg;
+            }
+        }
+        msg.setData(resColumnList);
         return msg;
     }
 
@@ -777,13 +1053,15 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
 
         List<FormFieldHead> formFieldHeads = JSONArray.parseArray(cusReportForm.getFormFieldHead(), FormFieldHead.class);
 
-        List<Map<String,String>> tableNameAliasList = new ArrayList<>();
+//        List<Map<String,String>> tableNameAliasList = new ArrayList<>();
+        Map<String,String> tableNameAliasMap = new HashMap<>();
         Matcher mainMatcher = MAIN_TABLE_PATTERN.matcher(tableColumnSql);
         if (mainMatcher.find()) {
-            Map<String,String> tableNameMap = new HashMap<>();
-            tableNameMap.put("tableName",mainMatcher.group(1));
-            tableNameMap.put("tableAlias",mainMatcher.group(2));
-            tableNameAliasList.add(tableNameMap);
+//            Map<String,String> tableNameMap = new HashMap<>();
+//            tableNameMap.put("tableName",mainMatcher.group(1));
+//            tableNameMap.put("tableAlias",mainMatcher.group(2));
+//            tableNameAliasList.add(tableNameMap);
+            tableNameAliasMap.put(mainMatcher.group(1),mainMatcher.group(2));
         } else {
             msg.setError("主业务表无法识别,请联系管理员");
             return msg;
@@ -791,19 +1069,23 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
 
         Matcher joinMatcher = JOIN_TABLE_PATTERN.matcher(tableColumnSql);
         while (joinMatcher.find()){
-            Map<String,String> tableNameMap = new HashMap<>();
-            tableNameMap.put("tableName",joinMatcher.group(1));
-            tableNameMap.put("tableAlias",joinMatcher.group(2));
-            tableNameAliasList.add(tableNameMap);
+//            Map<String,String> tableNameMap = new HashMap<>();
+//            tableNameAliasMap.put("tableName",joinMatcher.group(1));
+//            tableNameAliasMap.put("tableAlias",joinMatcher.group(2));
+//            tableNameAliasList.add(tableNameMap);
+            tableNameAliasMap.put(joinMatcher.group(1),joinMatcher.group(2));
         }
 
 
         Map<String,List<String>> indexMap = new HashMap<>(2);
         indexMap.put("userName",new ArrayList<>());
         indexMap.put("deptName",new ArrayList<>());
-        for (Map<String, String> tableNameMap : tableNameAliasList) {
-            List<FormTransColumn> tmpColList = tblColumnMap.get(tableNameMap.get("tableName"));
-            String tableAlias = tableNameMap.get("tableAlias");
+//        for (Map<String, String> tableNameMap : tableNameAliasList) {
+        for (String tableName : tableNameAliasMap.keySet()) {
+            List<FormTransColumn> tmpColList = tblColumnMap.get(tableName);
+            String tableAlias = tableNameAliasMap.get(tableName);
+//            List<FormTransColumn> tmpColList = tblColumnMap.get(tableNameMap.get("tableName"));
+//            String tableAlias = tableNameMap.get("tableAlias");
             if(CollectionUtils.isNotEmpty(tmpColList)){
                 for (FormTransColumn formTransColumn : tmpColList) {
                     String col = tableAlias+"."+formTransColumn.getColName();
@@ -811,23 +1093,35 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
                         if(1 == formTransColumn.getTransType()){
                             //当前位置的是人名,需要转义
                             for (int i = 0; i < formFieldHeads.size(); i++) {
-                                if(formFieldHeads.get(i).getTableName().equals(tableNameMap.get("tableName"))
-                                &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+                                if(formFieldHeads.get(i).getTableName().equals(tableName)
+                                        &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
                                 ){
                                     List<String> tmpList = indexMap.get("userName");
                                     tmpList.add(formFieldHeads.get(i).getColumnVal());
                                 }
+//                                if(formFieldHeads.get(i).getTableName().equals(tableNameMap.get("tableName"))
+//                                &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+//                                ){
+//                                    List<String> tmpList = indexMap.get("userName");
+//                                    tmpList.add(formFieldHeads.get(i).getColumnVal());
+//                                }
                             }
                         }
                         else if (2 == formTransColumn.getTransType()) {
                             //当前位置是部门,需要转义
                             for (int i = 0; i < formFieldHeads.size(); i++) {
-                                if(formFieldHeads.get(i).getTableName().equals(tableNameMap.get("tableName"))
+                                if(formFieldHeads.get(i).getTableName().equals(tableName)
                                         &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
                                 ){
                                     List<String> tmpList = indexMap.get("deptName");
                                     tmpList.add(formFieldHeads.get(i).getColumnVal());
                                 }
+//                                if(formFieldHeads.get(i).getTableName().equals(tableNameMap.get("tableName"))
+//                                        &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+//                                ){
+//                                    List<String> tmpList = indexMap.get("deptName");
+//                                    tmpList.add(formFieldHeads.get(i).getColumnVal());
+//                                }
                             }
                         }
                     }
@@ -837,6 +1131,7 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
             }
         }
 
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
         try (Connection connection = dataSource.getConnection()) {
             PreparedStatement preparedStatement = connection.prepareStatement(tableColumnSql);
             ResultSet resultSet = preparedStatement.executeQuery();
@@ -847,94 +1142,168 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
             return msg;
         }
 
+        //转换固定值
+        List<ColumnFixTrans> columnFixTrans = columnFixTransMapper.selectList(null);
+        Map<String, List<ColumnFixTrans>> tableColumnFixTransMap = columnFixTrans.stream()
+                .collect(Collectors.groupingBy(ColumnFixTrans::getTblName));// key tblName
+
+        //根据表头获取 'xxx' --> 别名.字段名 --> 表名.字段名
+        Map<String, FormFieldHead> columnAliasMap = new HashMap<>();
+        for (FormFieldHead formFieldHead : formFieldHeads) {
+            columnAliasMap.put(formFieldHead.getColumnVal(),formFieldHead);
+        }
+
         if(CollectionUtils.isNotEmpty(dataList)){
+            List<List<String>> resList=new ArrayList<>();
             // 创建工作簿和工作表
-            Workbook workbook = new XSSFWorkbook();
-            Sheet sheet = workbook.createSheet("Sheet01");
+//            Workbook workbook = new XSSFWorkbook();
+//            Sheet sheet = workbook.createSheet("Sheet01");
 
             // 创建表头
-            Row headerRow = sheet.createRow(0);
-            int colNum = 0;
-            for (String key : dataList.get(0).keySet()) {
-                Cell cell = headerRow.createCell(colNum++);
-                cell.setCellValue(key);
+//            Row headerRow = sheet.createRow(0);
+//            int colNum = 0;
+//            for (String key : dataList.get(0).keySet()) {
+//                Cell cell = headerRow.createCell(colNum++);
+//                cell.setCellValue(key);
+//            }
+
+            List<String> titleList=new ArrayList<>();
+            for (String s : dataList.get(0).keySet()) {
+                titleList.add(s);
             }
+            resList.add(titleList);
+
+            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, user.getCompanyId()));
 
             // 填充数据
-            int rowNum = 1;
+//            int rowNum = 1;
             for (Map<String, Object> data : dataList) {
-                Row row = sheet.createRow(rowNum++);
-                colNum = 0;
+                String valRes = "";
+//                Row row = sheet.createRow(rowNum++);
+//                colNum = 0;
+                List<String> item=new ArrayList<>();
+
                 for (String key : dataList.get(0).keySet()) {
-                    List<String> userNameIndexes = indexMap.get("userName");
-                    List<String> deptNameIndexes = indexMap.get("deptName");
-                    if(1 == user.getUserNameNeedTranslate()){
-                        Cell cell = row.createCell(colNum++);
+
+                    //固定值转换
+                    FormFieldHead formFieldHead = columnAliasMap.get(key);//字段对应别名和表
+                    List<ColumnFixTrans> transColList = tableColumnFixTransMap.get(formFieldHead.getTableName());//固定值字段集合
+                    List<ColumnFixTrans> currentFixValList = new ArrayList<>();
+                    if(CollectionUtils.isNotEmpty(transColList)){
+                        currentFixValList = transColList.stream()
+                                .filter(t -> t.getColName().equals(formFieldHead.getColumnName()))
+                                .collect(Collectors.toList());//当前字段固定值对照值
+                    }
+
+                    if(CollectionUtils.isNotEmpty(currentFixValList)){
+                        Map<String, String> valMeanMap = currentFixValList.stream()
+                                .collect(Collectors.toMap(ColumnFixTrans::getColVal, ColumnFixTrans::getValMean));
                         Object value = data.get(key);
-                        if (value == null) {
-                            cell.setCellValue(""); // 将null值替换为空格
-                        } else {
-                            String val = value.toString();
-                            if(CollectionUtils.isNotEmpty(userNameIndexes)){
-                                if(userNameIndexes.contains(key)){
-                                    List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
-                                            .eq(User::getName, val).last(" limit 1 ")
-                                    );
-                                    if(CollectionUtils.isNotEmpty(users)){
-                                        val = "$username="+users.get(0).getCorpwxUserid()+"$";
+                        if(null == value){
+//                            valRes = "";
+                        }else{
+                            String mean = valMeanMap.get(value.toString());
+                            valRes = mean;
+                        }
+                    }else{
+                        //转义
+                        List<String> userNameIndexes = indexMap.get("userName");
+                        List<String> deptNameIndexes = indexMap.get("deptName");
+                        if(1 == user.getUserNameNeedTranslate()){
+//                        Cell cell = row.createCell(colNum++);
+                            Object value = data.get(key);
+                            if (value == null) {
+//                            cell.setCellValue(""); // 将null值替换为空格
+                            } else {
+                                String val = value.toString();
+                                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                                    if(CollectionUtils.isNotEmpty(userNameIndexes) && userNameIndexes.contains(key)){
+//                                    List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
+//                                            .eq(User::getName, val).last(" limit 1 ")
+//                                    );
+//                                    if(CollectionUtils.isNotEmpty(users)){
+//                                        val = "$username="+users.get(0).getCorpwxUserid()+"$";
+//                                    }
+                                        String name = val;
+                                        Optional<User> first = userList.stream().filter(u -> u.getName().equals(name)).findFirst();
+                                        if(first.isPresent()){
+                                            val = "$userName="+first.get().getCorpwxUserid()+"$";
+                                        }else {
+                                            val = "";
+                                        }
                                     }
 
                                 }
-                            }
 
-                            if(CollectionUtils.isNotEmpty(deptNameIndexes)){
-                                if(deptNameIndexes.contains(key)){
-                                    List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
-                                            .eq(User::getName, val).last(" limit 1 ")
-                                    );
-                                    if(CollectionUtils.isNotEmpty(users)){
-                                        val = "$departmentName="+users.get(0).getCorpwxDeptid()+"$";
+
+                                if(CollectionUtils.isNotEmpty(deptNameIndexes) && deptNameIndexes.contains(key)){
+//                                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
+//                                        .eq(User::getName, val).last(" limit 1 ")
+//                                );
+//                                if(CollectionUtils.isNotEmpty(users)){
+//                                    val = "$departmentName="+users.get(0).getCorpwxDeptid()+"$";
+//                                }
+                                    String name = val;
+                                    Optional<User> first = userList.stream().filter(u -> u.getName().equals(name)).findFirst();
+                                    if(first.isPresent()){
+                                        val = "$departmentName="+first.get().getCorpwxDeptid()+"$";
+                                    }else {
+                                        val = "";
                                     }
                                 }
+//                            cell.setCellValue(val);
+                                valRes = val;
                             }
-                            cell.setCellValue(val);
-                        }
 
-                    }else{
-                        Cell cell = row.createCell(colNum++);
-                        Object value = data.get(key);
-                        if (value == null) {
-                            cell.setCellValue(""); // 将null值替换为空格
-                        } else {
-                            cell.setCellValue(value.toString());
+                        }else{
+//                        Cell cell = row.createCell(colNum++);
+                            Object value = data.get(key);
+                            if (value == null) {
+//                            cell.setCellValue(""); // 将null值替换为空格
+                                valRes = "";
+                            } else {
+//                            cell.setCellValue(value.toString());
+                                valRes = value.toString();
+                            }
                         }
                     }
+
+                    item.add(valRes);
+                    valRes = "";
                 }
+                resList.add(item);
             }
 
             // 自动调整列宽
-            for (int i = 0; i < dataList.get(0).size(); i++) {
-                sheet.autoSizeColumn(i);
-            }
+//            for (int i = 0; i < dataList.get(0).size(); i++) {
+//                sheet.autoSizeColumn(i);
+//            }
 
             //生成Excel文件
-            String fileUrlSuffix = cusReportForm.getReportFormName()+System.currentTimeMillis() + ".xlsx";
-            try (FileOutputStream fos = new FileOutputStream(path + fileUrlSuffix)){
-                workbook.write(fos);
-                msg.data = "/upload/" + fileUrlSuffix;
-            } catch (NullPointerException e) {
-                msg.setError(MessageUtils.message("access.verErrorOrDataLack"));
-                return msg;
-            } catch (IOException e) {
-                msg.setError(MessageUtils.message("file.generateError"));
-                return msg;
-            } finally {
-                try {
-                    workbook.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
+            String fileUrlSuffix = cusReportForm.getReportFormName()+System.currentTimeMillis();
+//            try (FileOutputStream fos = new FileOutputStream(path + fileUrlSuffix)){
+//                workbook.write(fos);
+//                msg.data = "/upload/" + fileUrlSuffix;
+//            } catch (NullPointerException e) {
+//                msg.setError(MessageUtils.message("access.verErrorOrDataLack"));
+//                return msg;
+//            } catch (IOException e) {
+//                msg.setError(MessageUtils.message("file.generateError"));
+//                return msg;
+//            } finally {
+//                try {
+//                    workbook.close();
+//                } catch (IOException e) {
+//                    e.printStackTrace();
+//                }
+//            }
+
+            try {
+                return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileUrlSuffix,resList,path);
+            } catch (Exception e) {
+                e.printStackTrace();
             }
+
         }
 
         return msg;
@@ -1016,4 +1385,137 @@ public class CusTableColumnServiceImpl extends ServiceImpl<CusTableColumnMapper,
         return list;
     }
 
+
+    //转换固定值并转义
+    public List<Map<String,Object>> getTransResColumns(List<Map<String,Object>> columnList
+            ,List<FormFieldHead> formFieldHeads
+            ,Map<String, FormFieldHead> columnAliasMap
+            ,Map<String, List<ColumnFixTrans>> tableColumnFixTransMap
+            ,Map<String, List<FormTransColumn>> tblColumnMap
+            ,List<User> companyUsers
+            ,WxCorpInfo wxCorpInfo
+            ,String sql
+            ,User user){
+        List<Map<String,Object>> resColumnList = new ArrayList<>();
+        if(CollectionUtils.isNotEmpty(columnList)){
+            Map<String,List<String>> indexMap = new HashMap<>(2);
+            indexMap.put("userName",new ArrayList<>());
+            indexMap.put("deptName",new ArrayList<>());
+            Map<String,String> tableNameAliasMap = new HashMap<>();
+            Matcher mainMatcher = MAIN_TABLE_PATTERN.matcher(sql);
+            if (mainMatcher.find()) {
+                tableNameAliasMap.put(mainMatcher.group(1),mainMatcher.group(2));
+            } else {
+                throw new RuntimeException("主业务表无法识别,请联系管理员");
+            }
+
+            Matcher joinMatcher = JOIN_TABLE_PATTERN.matcher(sql);
+            while (joinMatcher.find()){
+                tableNameAliasMap.put(joinMatcher.group(1),joinMatcher.group(2));
+            }
+            for (String tableName : tableNameAliasMap.keySet()) {
+                List<FormTransColumn> tmpColList = tblColumnMap.get(tableName);
+                String tableAlias = tableNameAliasMap.get(tableName);
+                if(CollectionUtils.isNotEmpty(tmpColList)){
+                    for (FormTransColumn formTransColumn : tmpColList) {
+                        String col = tableAlias+"."+formTransColumn.getColName();
+                        if(sql.contains(col)){
+                            if(1 == formTransColumn.getTransType()){
+                                //当前位置的是人名,需要转义
+                                for (int i = 0; i < formFieldHeads.size(); i++) {
+                                    if(formFieldHeads.get(i).getTableName().equals(tableName)
+                                            &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+                                    ){
+                                        List<String> tmpList = indexMap.get("userName");
+                                        tmpList.add(formFieldHeads.get(i).getColumnVal());
+                                    }
+                                }
+                            }
+                            else if (2 == formTransColumn.getTransType()) {
+                                //当前位置是部门,需要转义
+                                for (int i = 0; i < formFieldHeads.size(); i++) {
+                                    if(formFieldHeads.get(i).getTableName().equals(tableName)
+                                            &&formFieldHeads.get(i).getColumnName().equals(formTransColumn.getColName())
+                                    ){
+                                        List<String> tmpList = indexMap.get("deptName");
+                                        tmpList.add(formFieldHeads.get(i).getColumnVal());
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            for (Map<String, Object> data : columnList) {
+                String valRes = "";
+                Map<String,Object> map = new HashMap<>();
+                for (String key : columnList.get(0).keySet()) {
+                    //固定值转换
+                    FormFieldHead formFieldHead = columnAliasMap.get(key);//字段对应别名和表
+                    List<ColumnFixTrans> transColList = tableColumnFixTransMap.get(formFieldHead.getTableName());//固定值字段集合
+                    List<ColumnFixTrans> currentFixValList = new ArrayList<>();
+                    if(CollectionUtils.isNotEmpty(transColList)){
+                        currentFixValList = transColList.stream()
+                                .filter(t -> t.getColName().equals(formFieldHead.getColumnName()))
+                                .collect(Collectors.toList());//当前字段固定值对照值
+                    }
+                    if(CollectionUtils.isNotEmpty(currentFixValList)){
+                        Map<String, String> valMeanMap = currentFixValList.stream()
+                                .collect(Collectors.toMap(ColumnFixTrans::getColVal, ColumnFixTrans::getValMean));
+                        Object value = data.get(key);
+                        if(null != value){
+                            String mean = valMeanMap.get(value.toString());
+                            valRes = mean;
+                        }
+                    }else{
+                        //转义
+                        List<String> userNameIndexes = indexMap.get("userName");
+                        List<String> deptNameIndexes = indexMap.get("deptName");
+                        if(1 == user.getUserNameNeedTranslate()){
+                            Object value = data.get(key);
+                            if (value == null) {
+                            } else {
+                                String val = value.toString();
+                                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                                    if(CollectionUtils.isNotEmpty(userNameIndexes) && userNameIndexes.contains(key)){
+                                        String name = val;
+                                        Optional<User> first = companyUsers.stream().filter(u -> u.getName().equals(name)).findFirst();
+                                        if(first.isPresent()){
+                                            val = "$userName="+first.get().getCorpwxUserid()+"$";
+                                        }else {
+                                            val = "";
+                                        }
+                                    }
+
+                                }
+                                if(CollectionUtils.isNotEmpty(deptNameIndexes) && deptNameIndexes.contains(key)){
+                                    String name = val;
+                                    Optional<User> first = companyUsers.stream().filter(u -> u.getName().equals(name)).findFirst();
+                                    if(first.isPresent()){
+                                        val = "$departmentName="+first.get().getCorpwxDeptid()+"$";
+                                    }else {
+                                        val = "";
+                                    }
+                                }
+                                valRes = val;
+                            }
+                        }else{
+                            Object value = data.get(key);
+                            if (value == null) {
+                                valRes = "";
+                            } else {
+                                valRes = value.toString();
+                            }
+                        }
+                    }
+                    map.put(key,valRes);
+                    valRes = "";
+                }
+                resColumnList.add(map);
+            }
+        }
+        return resColumnList;
+    }
+
 }

+ 89 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/util/ExcelConverter.java

@@ -0,0 +1,89 @@
+package com.management.platform.util;
+
+import com.management.platform.entity.ExcelMultipartFile;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ExcelConverter {
+
+    private static void autoSizeColumns(Sheet sheet, int columnCount) {
+        for (int i = 0; i < columnCount; i++) {
+            sheet.autoSizeColumn(i);
+        }
+    }
+
+    public static MultipartFile convertToExcel(
+            List<Map<String, Object>> data,
+            String fileName) throws IOException {
+
+        // 1. 创建工作簿和工作表
+        try (Workbook workbook = new XSSFWorkbook()) {
+            Sheet sheet = workbook.createSheet("Sheet1");
+
+            // 2. 创建表头
+            if (!data.isEmpty()) {
+                createHeaderRow(sheet, data.get(0).keySet());
+
+                // 3. 填充数据行
+                fillDataRows(sheet, data);
+            }
+
+            // 调整列宽
+            autoSizeColumns(sheet, data.get(0).keySet().size());
+
+            // 4. 将工作簿写入字节数组
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            workbook.write(outputStream);
+
+            // 5. 创建并返回MultipartFile
+            return new ExcelMultipartFile(
+                    outputStream.toByteArray(),
+                    fileName.endsWith(".xlsx") ? fileName : fileName + ".xlsx");
+        }
+    }
+
+    private static void createHeaderRow(Sheet sheet, Set<String> headers) {
+        Row headerRow = sheet.createRow(0);
+        int colNum = 0;
+
+        CellStyle headerStyle = sheet.getWorkbook().createCellStyle();
+        Font headerFont = sheet.getWorkbook().createFont();
+        headerFont.setBold(true);
+        headerStyle.setFont(headerFont);
+
+        for (String header : headers) {
+            Cell cell = headerRow.createCell(colNum++);
+            cell.setCellValue(header);
+            cell.setCellStyle(headerStyle);
+        }
+    }
+
+    private static void fillDataRows(Sheet sheet, List<Map<String, Object>> data) {
+        Set<String> headers = data.get(0).keySet();
+        int rowNum = 1;
+
+        for (Map<String, Object> rowData : data) {
+            Row row = sheet.createRow(rowNum++);
+            int colNum = 0;
+
+            for (String header : headers) {
+                Object value = rowData.get(header);
+                Cell cell = row.createCell(colNum++);
+
+                if (value == null) {
+                    cell.setCellValue("");
+                } else {
+                    cell.setCellValue(value.toString());
+                }
+            }
+        }
+    }
+
+}

+ 4 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/resources/application.yml

@@ -182,3 +182,7 @@ supersonic:
   port: 9080
   username: admin
   password: e6+jQ26AESREiBBuKM1u1A==
+
+aiask:
+  fileaskurl: http://192.168.2.5:5000/analyze
+  askurl: http://192.168.2.5:5000/analyzeOnlyQuestion