xushili 2 anni fa
parent
commit
59dc499195

+ 4 - 2
build.gradle.kts

@@ -20,15 +20,17 @@ repositories {
 
 dependencies {
     implementation("org.springframework.boot:spring-boot-starter")
+    implementation("org.springframework.boot:spring-boot-starter-web")
     compileOnly("org.projectlombok:lombok")
     annotationProcessor("org.projectlombok:lombok")
     testImplementation("org.springframework.boot:spring-boot-starter-test")
+    implementation("org.springframework.boot:spring-boot-starter-websocket")
 
     implementation("com.baomidou:mybatis-plus-boot-starter:3.5.3.1")
-    implementation("org.springframework.boot:spring-boot-starter-web")
     implementation("com.alibaba:druid-spring-boot-starter:1.2.15")
     implementation("mysql:mysql-connector-java:8.0.31")
-    implementation("com.alibaba.fastjson2:fastjson2:2.0.22")
+    implementation("com.alibaba:fastjson:2.0.23")
+    implementation("org.apache.commons:commons-lang3:3.12.0")
 }
 
 tasks.withType<Test> {

+ 17 - 0
src/main/java/com/gyee/table/config/WebSocketConfig.java

@@ -0,0 +1,17 @@
+package com.gyee.table.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter(){
+        return new ServerEndpointExporter();
+    }
+
+}

+ 25 - 4
src/main/java/com/gyee/table/controller/TableHeaderController.java

@@ -1,16 +1,19 @@
 package com.gyee.table.controller;
 
 import com.alibaba.fastjson2.JSONObject;
-import com.gyee.table.entity.TableHeaderColumn;
+import com.gyee.table.entity.TableColumnHeader;
 import com.gyee.table.result.Result;
 import com.gyee.table.result.ResultCode;
 import com.gyee.table.service.IObjectService;
+import com.gyee.table.service.ITableColumnHeaderService;
 import com.gyee.table.service.ITableHeaderColumnService;
 import com.gyee.table.service.ITableHeaderService;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -32,21 +35,39 @@ public class TableHeaderController {
     @Resource
     private ITableHeaderColumnService tableHeaderColumnService;
     @Resource
+    private ITableColumnHeaderService tableColumnHeaderService;
+    @Resource
     private IObjectService objectService;
 
     private final static String regex = "#|/\\*|\\*/|--|\\buse\\b|\\binsert\\b|\\bdelete\\b|\\bupdate\\b|\\bcreate\\b|\\bdrop\\b|\\btruncate\\b|\\balter\\b|\\bgrant\\b|\\bexecute\\b|\\bexec\\b|\\bxp_cmdshell\\b|\\bcall\\b|\\bdeclare\\b|\\bsource\\b|\\bsql\\b|\\bchr\\b|\\bmid\\b|\\bmaster\\b|\\bchar\\b|\\bsitename\\b|\\bnet user\\b|;|-|\\+|,|\\btable\\b|\\bgroup_concat\\b|\\bcolumn_name\\b|\\binformation_schema.columns\\b|\\btable_schema\\b|//|/";
 
     @GetMapping("/header/{headername}")
-    private List<TableHeaderColumn> header(@PathVariable String headername){
-        List<TableHeaderColumn> header = tableHeaderService.getHeader(headername);
+    private JSONObject header(@PathVariable String headername){
+        if(StringUtils.isBlank(headername)) return Result.error(ResultCode.PARAM_IS_BLANK);
+        //List<TableHeaderColumn> header = tableHeaderService.getHeader(headername);
+        List<TableColumnHeader> header = tableColumnHeaderService.getHeader(headername);
+        /*Map<String, Object> map = new HashMap<>();
+        map.put("name", headername);
+        List<TableColumnHeader> header = tableColumnHeaderService.listByMap(map);*/
+        tableColumnHeaderService.saveBatch(header);
         //tableHeaderColumnService.saveBatch(header);
-        return header;
+        return Result.successData(ResultCode.SUCCESS,header);
     }
     @PostMapping("/data")
     private JSONObject getData(@RequestBody Map map){
         return objectService.selectBySql(map);
     }
 
+    @PutMapping("/header/update")
+    private JSONObject updateTable(@RequestBody List<TableColumnHeader> tableHeader){
+        boolean b = tableColumnHeaderService.updateBatchById(tableHeader);
+        if(b){
+            return Result.success();
+        }else {
+            return Result.error();
+        }
+    }
+
     @GetMapping("/test")
     private JSONObject test(){
         //List<TableHeaderColumn> list = tableHeaderColumnService.list();

+ 12 - 0
src/main/java/com/gyee/table/entity/Table.java

@@ -0,0 +1,12 @@
+package com.gyee.table.entity;
+
+import lombok.Data;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+@Data
+public class Table {
+    private List<TableColumnHeader> tableHeader;
+    private List<LinkedHashMap<String, Object>> tableData;
+}

+ 66 - 0
src/main/java/com/gyee/table/entity/TableColumnHeader.java

@@ -0,0 +1,66 @@
+package com.gyee.table.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.handlers.FastjsonTypeHandler;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-01-17
+ */
+@Data
+@TableName("table_column_header")
+public class TableColumnHeader implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long tid;
+
+    private String name;
+
+    @TableId(type = IdType.ASSIGN_ID)
+    private String id;
+
+    private String type;
+
+    private String label;
+
+    private String width;
+
+    private String minwidth;
+
+    private String prop;
+
+    private String align;
+
+    private Boolean showoverflowtooltip;
+
+    private Boolean sortable;
+
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private String[] operations;
+
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private String[] children;
+
+    private Boolean showfilters;
+
+    private String filterstype;
+
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private String[] filters;
+
+    private String formattype;
+
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private String[] format;
+}

+ 16 - 0
src/main/java/com/gyee/table/mapper/TableColumnHeaderMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.table.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.table.entity.TableColumnHeader;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-01-17
+ */
+public interface TableColumnHeaderMapper extends BaseMapper<TableColumnHeader> {
+
+}

+ 19 - 0
src/main/java/com/gyee/table/service/ITableColumnHeaderService.java

@@ -0,0 +1,19 @@
+package com.gyee.table.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.gyee.table.entity.TableColumnHeader;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-01-17
+ */
+public interface ITableColumnHeaderService extends IService<TableColumnHeader> {
+
+    List<TableColumnHeader> getHeader(String headername);
+}

+ 3 - 0
src/main/java/com/gyee/table/service/ITableHeaderService.java

@@ -1,6 +1,7 @@
 package com.gyee.table.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.gyee.table.entity.TableColumnHeader;
 import com.gyee.table.entity.TableHeader;
 import com.gyee.table.entity.TableHeaderColumn;
 
@@ -17,4 +18,6 @@ import java.util.List;
 public interface ITableHeaderService extends IService<TableHeader> {
 
     List<TableHeaderColumn> getHeader(String headername);
+
+    List<TableColumnHeader> getHeader2(String headername);
 }

+ 74 - 2
src/main/java/com/gyee/table/service/impl/ObjectServiceImpl.java

@@ -1,13 +1,20 @@
 package com.gyee.table.service.impl;
 
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.gyee.table.entity.Table;
+import com.gyee.table.entity.TableColumnHeader;
 import com.gyee.table.mapper.ObjectAllMapper;
+import com.gyee.table.mapper.TableColumnHeaderMapper;
 import com.gyee.table.result.Result;
 import com.gyee.table.result.ResultCode;
 import com.gyee.table.service.IObjectService;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -26,24 +33,89 @@ import java.util.regex.Pattern;
 public class ObjectServiceImpl implements IObjectService {
 
     private final static String regex = "#|/\\*|\\*/|--|\\buse\\b|\\binsert\\b|\\bdelete\\b|\\bupdate\\b|\\bcreate\\b|\\bdrop\\b|\\btruncate\\b|\\balter\\b|\\bgrant\\b|\\bexecute\\b|\\bexec\\b|\\bxp_cmdshell\\b|\\bcall\\b|\\bdeclare\\b|\\bsource\\b|\\bsql\\b|\\bchr\\b|\\bmid\\b|\\bmaster\\b|\\bchar\\b|\\bsitename\\b|\\bnet user\\b|;|-|\\+|,|\\btable\\b|\\bgroup_concat\\b|\\bcolumn_name\\b|\\binformation_schema.columns\\b|\\btable_schema\\b|//|/";
-    private Pattern compile = null;
+    private final Pattern compile;
     {
         compile = Pattern.compile(regex);
     }
 
+    private final String[] emptyArray = {};
+
     @Resource
     private ObjectAllMapper objectMapper;
+    @Resource
+    private TableColumnHeaderMapper tableColumnHeaderMapper;
 
+    /**
+     * 根据表名查表头,根据sql查数据
+     * @param map tablenae,sql
+     * @return
+     */
     @Override
     public JSONObject selectBySql(Map map) {
 
         String sql = (String) map.get("sql");
+        if(StringUtils.isBlank(sql)) return Result.error(ResultCode.PARAM_IS_BLANK);
+
         Matcher matcher = compile.matcher(sql);
         if(matcher.find()){
             String group = matcher.group(0);
             return Result.error(ResultCode.ERROR_UNSUPPORTED_SQL,"查看字符:"+group);
         }
+
         List<LinkedHashMap<String, Object>> lms = objectMapper.selectAll(sql);
-        return Result.successData(ResultCode.SUCCESS,lms);
+
+        String tablename = (String) map.get("tablename");
+        if(StringUtils.isBlank(tablename))
+            //tablename = StringUtils.substringBetween("from ", " ");
+            return Result.successData(ResultCode.SUCCESS,lms);
+
+        QueryWrapper<TableColumnHeader> wrapper = new QueryWrapper<>();
+        wrapper.eq("name", tablename);
+        boolean tableExist = tableColumnHeaderMapper.exists(wrapper);
+
+        List<TableColumnHeader> tableColumnHeader;
+        if(!tableExist && lms.size()>0){
+            tableColumnHeader = createTableColumnHeader(tablename, lms.get(0));
+        }else {
+            tableColumnHeader = tableColumnHeaderMapper.selectList(wrapper);
+        }
+        Table table = new Table();
+        table.setTableHeader(tableColumnHeader);
+        table.setTableData(lms);
+        return Result.successData(ResultCode.SUCCESS,table);
+    }
+
+    /**
+     * 根据表头和数据生成默认表头
+     * @param tablename
+     * @param solhm
+     * @return
+     */
+    private List<TableColumnHeader> createTableColumnHeader(String tablename, LinkedHashMap<String, Object> solhm) {
+        List<TableColumnHeader> tableHeaderColumns = new ArrayList<>();
+        long tableId = tableColumnHeaderMapper.selectCount(Wrappers.emptyWrapper()) + 1;
+        for (String s : solhm.keySet()) {
+            TableColumnHeader tch = new TableColumnHeader();
+            tch.setTid(tableId);
+            tch.setName(tablename);
+            tch.setType("");
+            tch.setLabel(s);
+            tch.setWidth("");
+            tch.setMinwidth("");
+            tch.setProp(s);
+            tch.setAlign("center");
+            tch.setShowoverflowtooltip(true);
+            tch.setSortable(false);
+            tch.setOperations(emptyArray);
+            tch.setChildren(emptyArray);
+            tch.setShowfilters(false);
+            tch.setFilterstype("basic");
+            tch.setFilters(emptyArray);
+            tch.setFormattype("");
+            tch.setFormat(emptyArray);
+
+            tableHeaderColumns.add(tch);
+        }
+        return tableHeaderColumns;
     }
 }

+ 72 - 0
src/main/java/com/gyee/table/service/impl/TableColumnHeaderServiceImpl.java

@@ -0,0 +1,72 @@
+package com.gyee.table.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gyee.table.entity.TableColumnHeader;
+import com.gyee.table.mapper.TableColumnHeaderMapper;
+import com.gyee.table.service.ITableColumnHeaderService;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-01-17
+ */
+@Service
+public class TableColumnHeaderServiceImpl extends ServiceImpl<TableColumnHeaderMapper, TableColumnHeader> implements ITableColumnHeaderService {
+
+    // 列类型
+    private String[] llx = {"index", "operations",""};
+    // 列对齐方式
+    private String[] ldqfs = {"left", "center", "right"};
+    // 列是否溢出隐藏\开启排序\开启筛选
+    private Boolean[] arrayb = {true,false};
+    // 列筛选的类型
+    private String[] lsxlx = {"basic", "current"};
+    private Random random = new Random();
+    private String[] kun = {};
+    private String[] glc = {"过滤词"};
+
+    @Override
+    public List<TableColumnHeader> getHeader(String headername) {
+        List<TableColumnHeader> tableHeaderColumns = new ArrayList<>();
+        long tableId = baseMapper.selectCount(Wrappers.emptyWrapper()) + 1;
+        int j = random.nextInt(15) + 3;
+        for (int i = 0; i < j; i++) {
+            TableColumnHeader thc = new TableColumnHeader();
+            //thc.setId(idWorker.nextIdStr());
+            thc.setTid(tableId);
+            thc.setName(headername);
+            thc.setType(llx[random.nextInt(3)]);
+            thc.setLabel("新表头");
+            thc.setWidth("");
+            thc.setMinwidth("");
+            thc.setAlign(ldqfs[random.nextInt(3)]);
+            thc.setShowoverflowtooltip(arrayb[random.nextInt(2)]);
+            thc.setSortable(arrayb[random.nextInt(2)]);
+            thc.setOperations(kun);
+            thc.setChildren(kun);
+            thc.setShowfilters(arrayb[random.nextInt(2)]);
+            thc.setFilterstype(lsxlx[random.nextInt(2)]);
+            thc.setFormat(kun);
+            thc.setFormattype("");
+
+            if("".equals(thc.getType()) && Arrays.equals(kun,thc.getChildren())){
+                thc.setProp("newtableheader");
+            }else {
+                thc.setProp("");
+            }
+            thc.setFilters("current".equals(thc.getFilterstype())?glc:kun);
+            tableHeaderColumns.add(thc);
+        }
+        return tableHeaderColumns;
+    }
+}

+ 38 - 10
src/main/java/com/gyee/table/service/impl/TableHeaderServiceImpl.java

@@ -1,8 +1,8 @@
 package com.gyee.table.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gyee.table.entity.TableColumnHeader;
 import com.gyee.table.entity.TableHeader;
 import com.gyee.table.entity.TableHeaderColumn;
 import com.gyee.table.mapper.TableHeaderMapper;
@@ -36,8 +36,8 @@ public class TableHeaderServiceImpl extends ServiceImpl<TableHeaderMapper, Table
     // 列筛选的类型
     private String[] lsxlx = {"basic", "current"};
     private Random random = new Random();
-    private ObjectMapper objectMapper=new ObjectMapper();
     private String[] kun = {};
+    private String[] glc = {"过滤词"};
 
     @Resource
     private IdWorker idWorker;
@@ -69,14 +69,42 @@ public class TableHeaderServiceImpl extends ServiceImpl<TableHeaderMapper, Table
                 thc.setProp("");
             }
 
-            String[] nihao = {"你好"};
-            String s = "";
-            try {
-                s = objectMapper.writeValueAsString(nihao);
-            } catch (JsonProcessingException e) {
-                e.printStackTrace();
+            thc.setFilters("current".equals(thc.getFilterstype())?glc:kun);
+            tableHeaderColumns.add(thc);
+        }
+        return tableHeaderColumns;
+    }
+
+    @Override
+    public List<TableColumnHeader> getHeader2(String headername) {
+        List<TableColumnHeader> tableHeaderColumns = new ArrayList<>();
+        long tableId = baseMapper.selectCount(Wrappers.emptyWrapper()) + 1;
+        int j = random.nextInt(15) + 3;
+        for (int i = 0; i < j; i++) {
+            TableColumnHeader thc = new TableColumnHeader();
+            //thc.setId(idWorker.nextIdStr());
+            thc.setTid(tableId);
+            thc.setName(headername);
+            thc.setType(llx[random.nextInt(3)]);
+            thc.setLabel("新表头");
+            thc.setWidth("");
+            thc.setMinwidth("");
+            thc.setAlign(ldqfs[random.nextInt(3)]);
+            thc.setShowoverflowtooltip(arrayb[random.nextInt(2)]);
+            thc.setSortable(arrayb[random.nextInt(2)]);
+            thc.setOperations(kun);
+            thc.setChildren(kun);
+            thc.setShowfilters(arrayb[random.nextInt(2)]);
+            thc.setFilterstype(lsxlx[random.nextInt(2)]);
+            thc.setFormat(kun);
+            thc.setFormattype("");
+
+            if("".equals(thc.getType()) && Arrays.equals(kun,thc.getChildren())){
+                thc.setProp("newtableheader");
+            }else {
+                thc.setProp("");
             }
-            thc.setFilters("current".equals(thc.getFilterstype())?nihao:kun);
+            thc.setFilters("current".equals(thc.getFilterstype())?glc:kun);
             tableHeaderColumns.add(thc);
         }
         return tableHeaderColumns;

+ 134 - 0
src/main/java/com/gyee/table/websocket/WebSocketImpl.java

@@ -0,0 +1,134 @@
+package com.gyee.table.websocket;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@Component
+@ServerEndpoint(value = "/refresh")
+public class WebSocketImpl {
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+     */
+
+    private static int onlineCount = 0;
+
+    /**
+     * concurrent包的线程安全Map,用来存放每个客户端对应的MyWebSocket对象
+     */
+    private static ConcurrentHashMap<String, WebSocketImpl> webSocketMap = new ConcurrentHashMap<>();
+
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+
+    private Session session;
+
+
+    /**
+     * 连接建立成功调用的方法
+     */
+    @OnOpen
+    public void onOpen(Session session) {
+        this.session = session;
+        //加入map
+        webSocketMap.put(session.getId(), this);
+        addOnlineCount();           //在线数加1
+        log.info("用户{}连接成功,当前在线人数为{}", session.getId(), getOnlineCount());
+        try {
+            sendMessage("连接成功");
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 连接关闭调用的方法
+     */
+    @OnClose
+    public void onClose() {
+        //从map中删除
+        webSocketMap.remove(session.getId());
+        subOnlineCount();           //在线数减1
+        log.info("用户{}关闭连接!当前在线人数为{}", session.getId(), getOnlineCount());
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("来自客户端用户:{} 消息:{}",session.getId(), message);
+
+        //群发消息
+        /*for (String item : webSocketMap.keySet()) {
+            try {
+                webSocketMap.get(item).sendMessage(message);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }*/
+    }
+
+    /**
+     * 发生错误时调用
+     *
+     * @OnError
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + session.getId() + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 向客户端发送消息
+     */
+    public void sendMessage(String message) throws IOException {
+        this.session.getBasicRemote().sendText(message);
+        //this.session.getAsyncRemote().sendText(message);
+    }
+
+    /**
+     * 通过userId向客户端发送消息
+     */
+    public void sendMessageByUserId(String userId, String message) throws IOException {
+        log.info("服务端发送消息到{},消息:{}",userId,message);
+        if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
+            webSocketMap.get(userId).sendMessage(message);
+        }else{
+            log.error("用户{}不在线",userId);
+        }
+
+    }
+
+    /**
+     * 群发自定义消息
+     */
+    public static void sendInfo(String message) throws IOException {
+        for (String item : webSocketMap.keySet()) {
+            webSocketMap.get(item).sendMessage(message);
+        }
+    }
+
+    public static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    public static synchronized void addOnlineCount() {
+        WebSocketImpl.onlineCount++;
+    }
+
+    public static synchronized void subOnlineCount() {
+        WebSocketImpl.onlineCount--;
+    }
+}

+ 5 - 3
src/main/resources/application.yml

@@ -16,11 +16,13 @@ mybatis-plus:
 logging:
   level:
     #root: info
-    com.gyee: warn
+    com.gyee: info
+    web: WARN
+    sql: info
   file:
     name: server.log
     path: ./log
   logback:
     rollingpolicy:
-      max-file-size: 3MB
-      file-name-pattern: server.%d{yyyy-MM-dd}.%i.log
+      #max-file-size: 9MB
+      file-name-pattern: server.%d{yyyy-MM-dd}.%i.gz