Ver código fonte

Merge remote-tracking branch 'origin/dev-V0.4.5-postgre' into dev-V0.4.5

jay 1 ano atrás
pai
commit
bc9e5abb77

+ 1 - 1
data/components/750da259-ff77-4869-a5a5-12a5433b0e4c/component.js

@@ -331,7 +331,7 @@ this.onReceive = function (head, type, payload) {
                 payload: payload
             }
         },
-        action: action
+        action: {}
     }
 }
 

+ 75 - 0
docker-compose.yml

@@ -0,0 +1,75 @@
+version: "3.4"
+
+services:
+  mysql:
+    container_name: iot-mysql
+    image: mysql:8
+    restart: unless-stopped
+    tty: true
+    ports:
+      - "3306:3306"
+    environment:
+      MYSQL_DATABASE: ${MYSQL_DATABASE:-iotkit}
+      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456}
+    volumes:
+      - mysql:/var/lib/mysql/
+
+
+  redis:
+    container_name: iot-redis
+    image: redis:6-alpine
+    restart: unless-stopped
+    ports:
+      - "6379:6379"
+    volumes:
+      - redis:/data
+
+  server:
+    container_name: iot-server
+    build:
+      context: ./
+    image: iot-server
+    restart: unless-stopped
+    ports:
+      - "8086:8086"
+    environment:
+      # https://github.com/polovyivan/docker-pass-configs-to-container
+      SPRING_PROFILES_ACTIVE: local
+      JAVA_OPTS:
+        ${JAVA_OPTS:-
+          -Xms512m
+          -Xmx512m
+          -Djava.security.egd=file:/dev/./urandom
+        }
+      ARGS:
+        --spring.datasource.dynamic.datasource.master.url=${MASTER_DATASOURCE_URL:-jdbc:mysql://iot-mysql:3306/iotkit?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true}
+        --spring.datasource.dynamic.datasource.master.username=${MASTER_DATASOURCE_USERNAME:-root}
+        --spring.datasource.dynamic.datasource.master.password=${MASTER_DATASOURCE_PASSWORD:-123456}
+        --spring.datasource.dynamic.datasource.slave.url=${SLAVE_DATASOURCE_URL:-jdbc:mysql://iot-mysql:3306/iotkit?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true}
+        --spring.datasource.dynamic.datasource.slave.username=${SLAVE_DATASOURCE_USERNAME:-root}
+        --spring.datasource.dynamic.datasource.slave.password=${SLAVE_DATASOURCE_PASSWORD:-123456}
+        --spring.redis.host=${REDIS_HOST:-iot-redis}
+    depends_on:
+      - redis
+
+  admin:
+    container_name: iot-admin
+    build:
+      context: ./iot-ui-admin
+      args:
+        NODE_ENV:
+          ENV=${NODE_ENV:-production}
+          PUBLIC_PATH=${PUBLIC_PATH:-/}
+          VUE_APP_TITLE=${VUE_APP_TITLE:-openiita管理系统}
+    image: iot-admin
+    restart: unless-stopped
+    ports:
+      - "8080:80"
+    depends_on:
+      - server
+
+volumes:
+  mysql:
+    driver: local
+  redis:
+    driver: local

+ 2 - 1
docker-compose/docker-compose-iita.yml

@@ -14,7 +14,8 @@ services:
     network_mode: "host"
     volumes:
 #      - ./admin-service.jar:/admin-service.jar
-      - /app/data:/app/data/
+      - /app/data/components:/app/data/components
+      - /app/data/converters:/app/data/converters
       - /app/config:/app/config/
       - /app/log:/app/log/
     command:

+ 19 - 0
docker.env

@@ -0,0 +1,19 @@
+## mysql
+MYSQL_DATABASE=iotkit
+MYSQL_ROOT_PASSWORD=123456
+
+## server
+JAVA_OPTS=-Xms512m -Xmx512m -Djava.security.egd=file:/dev/./urandom
+
+MASTER_DATASOURCE_URL=jdbc:mysql://iot-mysql:3306/${MYSQL_DATABASE}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
+MASTER_DATASOURCE_USERNAME=root
+MASTER_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
+SLAVE_DATASOURCE_URL=${MASTER_DATASOURCE_URL}
+SLAVE_DATASOURCE_USERNAME=${MASTER_DATASOURCE_USERNAME}
+SLAVE_DATASOURCE_PASSWORD=${MASTER_DATASOURCE_PASSWORD}
+REDIS_HOST=iot-redis
+
+## admin
+NODE_ENV=production
+PUBLIC_PATH=/
+VUE_APP_TITLE=iot管理系统

+ 2 - 1
iot-common/iot-common-core/src/main/java/cc/iotkit/common/enums/ErrCode.java

@@ -104,7 +104,8 @@ public enum ErrCode implements IEnum {
     RECORD_NOT_FOUND(00000000, "记录不存在"),
     ADD_PLATFORM_USER_ERROR(00000000, "添加平台用户失败"),
     UPLOAD_FILE_ERROR(00000000, "上传文件失败"),
-    FILE_NAME_IS_NULL(00000000, "文件名为空,获取文件名失败");
+    FILE_NAME_IS_NULL(00000000, "文件名为空,获取文件名失败"),
+    PRODUCT_KEY_EXIST(00000000, "ProductKey已存在");
 
 
 

+ 14 - 8
iot-common/iot-common-dao/iot-data-serviceImpl-rdb/pom.xml

@@ -48,17 +48,23 @@
             <artifactId>yitter-idgenerator</artifactId>
         </dependency>
 
+<!--        <dependency>-->
+<!--            <groupId>com.h2database</groupId>-->
+<!--            <artifactId>h2</artifactId>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>mysql</groupId>-->
+<!--            <artifactId>mysql-connector-java</artifactId>-->
+<!--            <version>8.0.32</version>-->
+<!--        </dependency>-->
+<!--        -->
         <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>42.2.9</version>
         </dependency>
 
-        <!--        <dependency>-->
-        <!--            <groupId>mysql</groupId>-->
-        <!--            <artifactId>mysql-connector-java</artifactId>-->
-        <!--            <version>8.0.32</version>-->
-        <!--        </dependency>-->
-
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>

+ 1 - 1
iot-common/iot-common-satoken/src/main/java/cc/iotkit/common/satoken/config/SaTokenConfig.java

@@ -46,7 +46,7 @@ public class SaTokenConfig implements WebMvcConfigurer {
         List<String> swaggerUrls = List.of("/doc.html","/favicon.ico", "/webjars/**", "/resources/**"
                 , "/swagger-resources/**", "/swagger-ui.html/**");
 
-        List loginUrls = List.of("/code", "/auth/tenant/list", "/auth/login");
+        List loginUrls = List.of("/code", "/auth/tenant/list", "/auth/login", "/auth/logout");
         List<String> openApiUrls = List.of( "/openapi/v1/getToken");
 
         List<String> excludeUrls = new ArrayList<>();

+ 7 - 1
iot-common/iot-common-satoken/src/main/java/cc/iotkit/common/satoken/utils/LoginHelper.java

@@ -4,10 +4,12 @@ import cc.iotkit.common.constant.TenantConstants;
 import cc.iotkit.common.constant.UserConstants;
 import cc.iotkit.common.enums.DeviceType;
 import cc.iotkit.common.enums.UserType;
+import cc.iotkit.common.exception.BizException;
 import cc.iotkit.common.undefined.LoginUser;
 import cn.dev33.satoken.context.SaHolder;
 import cn.dev33.satoken.context.model.SaStorage;
 import cn.dev33.satoken.exception.InvalidContextException;
+import cn.dev33.satoken.session.SaSession;
 import cn.dev33.satoken.stp.SaLoginModel;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -76,7 +78,11 @@ public class LoginHelper {
         if (loginUser != null) {
             return loginUser;
         }
-        loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);
+        SaSession tokenSession = StpUtil.getTokenSession();
+        if(tokenSession == null){
+            return null;
+        }
+        loginUser = (LoginUser) tokenSession.get(LOGIN_USER_KEY);
         SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
         return loginUser;
     }

+ 25 - 1
iot-components/iot-nb-component/src/main/java/cc/iotkit/comp/nb/NBVerticle.java

@@ -22,6 +22,7 @@ import io.vertx.core.Future;
 import io.vertx.core.buffer.Buffer;
 import io.vertx.core.net.PemKeyCertOptions;
 import io.vertx.mqtt.*;
+import io.vertx.mqtt.messages.codes.MqttDisconnectReasonCode;
 import io.vertx.mqtt.messages.codes.MqttSubAckReasonCode;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.binary.Hex;
@@ -107,15 +108,19 @@ public class NBVerticle extends AbstractVerticle {
             endpoint.accept(false);
             endpoint.closeHandler((v) -> {
                 log.warn("client connection closed,clientId:{}", clientId);
-                if (Boolean.FALSE.equals(mqttConnectPool.get(clientId))) {
+                if (!mqttConnectPool.get(clientId)) {
                     return;
                 }
                 executor.onReceive(new HashMap<>(), "disconnect", clientId, (r) -> {
                     //删除设备与连接关系
                     endpointMap.remove(getEndpointKey(r));
+                    mqttConnectPool.put(clientId, false);
                 });
             }).disconnectMessageHandler(disconnectMessage -> {
                 log.info("Received disconnect from client, reason code = {}", disconnectMessage.code());
+                if (!mqttConnectPool.get(clientId)) {
+                    return;
+                }
                 executor.onReceive(new HashMap<>(), "disconnect", clientId, (r) -> {
                     //删除设备与连接关系
                     endpointMap.remove(getEndpointKey(r));
@@ -158,6 +163,15 @@ public class NBVerticle extends AbstractVerticle {
                 if (StringUtils.isBlank(payload)) {
                     return;
                 }
+                if(! mqttConnectPool.get(clientId)){
+                    executor.onReceive(null, "online", clientId);
+                    //保存设备与连接关系
+                    String productKey = getProductKey(clientId);
+                    String deviceName = getDeviceName(clientId);
+                    endpointMap.put(getEndpointKey(productKey,deviceName ), endpoint);
+                    mqttConnectPool.put(clientId, true);
+                    log.info("mqtt client reconnect success,clientId:{}",clientId);
+                }
 
                 try {
                     Map<String, Object> head = new HashMap<>();
@@ -186,6 +200,16 @@ public class NBVerticle extends AbstractVerticle {
         });
     }
 
+    private String getDeviceName(String clientId) {
+        String[] s = clientId.split("_");
+        return s[0];
+    }
+
+    private String getProductKey(String clientId) {
+        String[] s = clientId.split("_");
+        return s[1];
+    }
+
     @Override
     public void stop() throws Exception {
         for (MqttEndpoint endpoint : endpointMap.values()) {

+ 1 - 1
iot-components/iot-nb-component/src/main/resources/component.js

@@ -331,7 +331,7 @@ this.onReceive = function (head, type, payload) {
                 payload: payload
             }
         },
-        action: action
+        action: {}
     }
 }
 

+ 5 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProductServiceImpl.java

@@ -87,6 +87,11 @@ public class ProductServiceImpl implements IProductService {
 
         String secret = UUID.randomUUID().toString(true);
         product.setProductSecret(secret);
+        String productKey = data.getProductKey();
+        Product oldProduct = productData.findByProductKey(productKey);
+        if(oldProduct != null){
+            throw new BizException(ErrCode.PRODUCT_KEY_EXIST);
+        }
 
         productData.save(product);
         return MapstructUtils.convert(product, ProductVo.class);

+ 6 - 3
iot-starter/src/main/java/cc/iotkit/web/service/SysLoginService.java

@@ -63,13 +63,13 @@ public class SysLoginService {
     @Value("${user.password.lockTime}")
     private Integer lockTime;
 
-    @Value("${weixin.appid}")
+    @Value("${weixin.appid:}")
     private String appid;
 
-    @Value("${weixin.secret}")
+    @Value("${weixin.secret:}")
     private String secret;
 
-    @Value("${weixin.authUrl}")
+    @Value("${weixin.authUrl:}")
     private String authUrl;
 
     /**
@@ -174,6 +174,9 @@ public class SysLoginService {
     public void logout() {
         try {
             LoginUser loginUser = LoginHelper.getLoginUser();
+            if(loginUser==null){
+                return;
+            }
             if (LoginHelper.isSuperAdmin()) {
                 // 超级管理员 登出清除动态租户
                 TenantHelper.clearDynamic();

+ 2 - 187
iot-starter/src/main/resources/application.yml

@@ -7,9 +7,9 @@ spring:
       enabled: true
       max-file-size: 10MB
       max-request-size: 12MB
+  profiles:
+    active: postgres
 
-  #注: 切换数据库时需要将项目根目录中的.init文件删除再重启
-  # <<=======内置H2数据库连接设置开始==========
   jpa:
     show-sql: true
     hibernate:
@@ -17,186 +17,7 @@ spring:
     properties:
       hibernate:
         format_sql: true
-  sql:
-    init:
-      schema-locations: classpath:sql/schema.sql
-      mode: ALWAYS
-  datasource:
-    url: jdbc:h2:./data/iotkit;MODE=MySQL
-    username: sa
-    password: 123456
-    driverClassName: org.h2.Driver
-    type: com.zaxxer.hikari.HikariDataSource
-    # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
-    dynamic:
-      hikari:
-        connection-timeout: 5000
-        idle-timeout: 30000 # 经过idle-timeout时间如果连接还处于空闲状态, 该连接会被回收
-        min-idle: 5 # 池中维护的最小空闲连接数, 默认为 10 个
-        max-pool-size: 16 # 池中最大连接数, 包括闲置和使用中的连接, 默认为 10 个
-        max-lifetime: 60000 # 如果一个连接超过了时长,且没有被使用, 连接会被回收
-        is-auto-commit: true
-      primary: master #设置默认的数据源或者数据源组,默认值即为master
-      strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
-      datasource:
-        # 主库数据源
-        master:
-          type: ${spring.datasource.type}
-          driverClassName: org.h2.Driver
-          # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
-          # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
-          url: jdbc:h2:./data/iotkit;MODE=MySQL
-          username: sa
-          password: 123456
-        # 从库数据源
-        slave:
-          lazy: true
-          type: ${spring.datasource.type}
-          driverClassName: org.h2.Driver
-          url: jdbc:h2:./data/iotkit;MODE=MySQL
-          username: sa
-          password: 123456
 
-    # 内置h2 web console设置
-    platform: h2
-  h2:
-    console:
-      enabled: true
-      path: /h2
-      settings:
-        web-allow-others: true
-  #=======内置H2数据库连接设置结束==========>>
-
-  # <<==========mysql配置开始==============
-#  jpa:
-#    database: MySQL
-#    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
-#    show-sql: true
-#    hibernate:
-#      ddl-auto: update
-#    properties:
-#      hibernate:
-#        format_sql: true
-#  datasource:
-#    type: com.zaxxer.hikari.HikariDataSource
-#    dynamic:
-#      hikari:
-#        connection-timeout: 5000
-#        idle-timeout: 30000 # 经过idle-timeout时间如果连接还处于空闲状态, 该连接会被回收
-#        min-idle: 5 # 池中维护的最小空闲连接数, 默认为 10 个
-#        max-pool-size: 16 # 池中最大连接数, 包括闲置和使用中的连接, 默认为 10 个
-#        max-lifetime: 60000 # 如果一个连接超过了时长,且没有被使用, 连接会被回收
-#        is-auto-commit: true
-#      primary: master #设置默认的数据源或者数据源组,默认值即为master
-#      strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
-#      datasource:
-#        # 主库数据源
-#        master:
-#          type: ${spring.datasource.type}
-#          driverClassName: com.mysql.cj.jdbc.Driver
-#          # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
-#          url: jdbc:mysql://192.168.31.136:3306/iotkit?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
-#          username: root
-#          password: 123456
-  # ============mysql配置结束============>>
-
-  #<<================es时序数据配置开始===============
-  elasticsearch:
-    rest:
-      #使用内置es的配置
-      #uris: http://elasticsearch:9200
-      uris: http://127.0.0.1:9200
-      username:
-      password:
-      connection-timeout: 10s
-  #================es时序数据配置结束===============>>
-
-  #<<===========tdengine时序数据库配置开始============
-#  td-datasource:
-#    url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8
-#    username: root
-#    password: taosdata
-#    driverClassName: com.taosdata.jdbc.rs.RestfulDriver
-  #===========tdengine时序数据库配置开始============>>
-
-  redis:
-    #使用内置redis的配置
-    #host: redis
-    host: 127.0.0.1
-    port: 6379
-    database: 0
-
-  mvc:
-    pathmatch:
-      matching-strategy: ant_path_matcher
-#  profiles:
-#    active: mysql
-
-#application.yml中打开注释支持rocketMq作为消息总线,pom.xml中打开注释使用rocketmq消息总线
-#rocketmq:
-#  name-server: 172.16.1.113:9876
-#  producer:
-#        group: iotkit
-
-#图片存储用的是阿里云oss,如果需要上传产品图片才需要配置
-aliyun:
-  bucketId:
-  endpoint:
-  accessKeyId:
-  accessKeySecret:
-
-sa-token:
-  # token名称 (同时也是cookie名称)
-  token-name: token
-  # token有效期,单位s 默认30天, -1代表永不过期
-  timeout: 2592000
-  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
-  activity-timeout: -1
-  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
-  is-concurrent: true
-  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
-  is-share: false
-  # token风格
-  token-style: uuid
-  # 是否输出操作日志
-  is-log: false
-
-captcha:
-  enable: true
-  # 页面 <参数设置> 可开启关闭 验证码校验
-  # 验证码类型 math 数组计算 char 字符验证
-  type: MATH
-  # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
-  category: CIRCLE
-  # 数字验证码位数
-  numberLength: 1
-  # 字符验证码长度
-  charLength: 4
-
-# 用户配置
-user:
-  password:
-    # 密码最大错误次数
-    maxRetryCount: 5
-    # 密码锁定时间(默认10分钟)
-    lockTime: 10
-
-# openapi配置
-openapi:
-  appid: 123456789
-  password: 123456
-
-oss:
-  region: xxxxx
-  endpoint: xxxxx
-  accessKey: xxxxx
-  secretKey: xxxxx
-  buckName: xxxx
-baetyl:
-  api-type: feign
-  service-url: http://116.168.30.140:30004
-
-# MyBatisPlus配置
 # https://baomidou.com/config/
 mybatis-plus:
   # 不支持多包, 如有需要可在注解配置 或 提升扫包等级
@@ -212,9 +33,3 @@ mybatis-plus:
       # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
       # 如需改为自增 需要将数据库表全部设置为自增
       idType: ASSIGN_ID
-
-#微信小程序配置
-weixin:
-  appid: xx
-  secret: xx
-  authUrl: xx

+ 112 - 0
iot-starter/src/main/resources/sql/schema-postgre.sql

@@ -0,0 +1,112 @@
+
+-- ----------------------------
+-- 18、代码生成业务表
+-- ----------------------------
+drop table if exists gen_table;
+create table if not exists gen_table
+(
+    table_id          int8,
+    data_name         varchar(200)  default ''::varchar,
+    table_name        varchar(200)  default ''::varchar,
+    table_comment     varchar(500)  default ''::varchar,
+    sub_table_name    varchar(64)   default ''::varchar,
+    sub_table_fk_name varchar(64)   default ''::varchar,
+    class_name        varchar(100)  default ''::varchar,
+    tpl_category      varchar(200)  default 'crud'::varchar,
+    package_name      varchar(100)  default null::varchar,
+    module_name       varchar(30)   default null::varchar,
+    business_name     varchar(30)   default null::varchar,
+    function_name     varchar(50)   default null::varchar,
+    function_author   varchar(50)   default null::varchar,
+    gen_type          char          default '0'::bpchar not null,
+    gen_path          varchar(200)  default '/'::varchar,
+    options           varchar(1000) default null::varchar,
+    create_dept       int8,
+    create_by         int8,
+    create_time       timestamp,
+    update_by         int8,
+    update_time       timestamp,
+    remark            varchar(500)  default null::varchar,
+    constraint gen_table_pk primary key (table_id)
+    );
+
+comment on table gen_table is '代码生成业务表';
+comment on column gen_table.table_id is '编号';
+comment on column gen_table.data_name is '数据源名称';
+comment on column gen_table.table_name is '表名称';
+comment on column gen_table.table_comment is '表描述';
+comment on column gen_table.sub_table_name is '关联子表的表名';
+comment on column gen_table.sub_table_fk_name is '子表关联的外键名';
+comment on column gen_table.class_name is '实体类名称';
+comment on column gen_table.tpl_category is '使用的模板(CRUD单表操作 TREE树表操作)';
+comment on column gen_table.package_name is '生成包路径';
+comment on column gen_table.module_name is '生成模块名';
+comment on column gen_table.business_name is '生成业务名';
+comment on column gen_table.function_name is '生成功能名';
+comment on column gen_table.function_author is '生成功能作者';
+comment on column gen_table.gen_type is '生成代码方式(0zip压缩包 1自定义路径)';
+comment on column gen_table.gen_path is '生成路径(不填默认项目路径)';
+comment on column gen_table.options is '其它生成选项';
+comment on column gen_table.create_dept is '创建部门';
+comment on column gen_table.create_by is '创建者';
+comment on column gen_table.create_time is '创建时间';
+comment on column gen_table.update_by is '更新者';
+comment on column gen_table.update_time is '更新时间';
+comment on column gen_table.remark is '备注';
+
+-- ----------------------------
+-- 19、代码生成业务表字段
+-- ----------------------------
+drop table if exists gen_table_column;
+create table if not exists gen_table_column
+(
+    column_id      int8,
+    table_id       int8,
+    column_name    varchar(200) default null::varchar,
+    column_comment varchar(500) default null::varchar,
+    column_type    varchar(100) default null::varchar,
+    java_type      varchar(500) default null::varchar,
+    java_field     varchar(200) default null::varchar,
+    is_pk          char         default null::bpchar,
+    is_increment   char         default null::bpchar,
+    is_required    char         default null::bpchar,
+    is_insert      char         default null::bpchar,
+    is_edit        char         default null::bpchar,
+    is_list        char         default null::bpchar,
+    is_query       char         default null::bpchar,
+    query_type     varchar(200) default 'EQ'::varchar,
+    html_type      varchar(200) default null::varchar,
+    dict_type      varchar(200) default ''::varchar,
+    sort           int4,
+    create_dept    int8,
+    create_by      int8,
+    create_time    timestamp,
+    update_by      int8,
+    update_time    timestamp,
+    constraint gen_table_column_pk primary key (column_id)
+    );
+
+comment on table gen_table_column is '代码生成业务表字段';
+comment on column gen_table_column.column_id is '编号';
+comment on column gen_table_column.table_id is '归属表编号';
+comment on column gen_table_column.column_name is '列名称';
+comment on column gen_table_column.column_comment is '列描述';
+comment on column gen_table_column.column_type is '列类型';
+comment on column gen_table_column.java_type is 'JAVA类型';
+comment on column gen_table_column.java_field is 'JAVA字段名';
+comment on column gen_table_column.is_pk is '是否主键(1是)';
+comment on column gen_table_column.is_increment is '是否自增(1是)';
+comment on column gen_table_column.is_required is '是否必填(1是)';
+comment on column gen_table_column.is_insert is '是否为插入字段(1是)';
+comment on column gen_table_column.is_edit is '是否编辑字段(1是)';
+comment on column gen_table_column.is_list is '是否列表字段(1是)';
+comment on column gen_table_column.is_query is '是否查询字段(1是)';
+comment on column gen_table_column.query_type is '查询方式(等于、不等于、大于、小于、范围)';
+comment on column gen_table_column.html_type is '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)';
+comment on column gen_table_column.dict_type is '字典类型';
+comment on column gen_table_column.sort is '排序';
+comment on column gen_table_column.create_dept is '创建部门';
+comment on column gen_table_column.create_by is '创建者';
+comment on column gen_table_column.create_time is '创建时间';
+comment on column gen_table_column.update_by is '更新者';
+comment on column gen_table_column.update_time is '更新时间';