tanghc 3 years ago
parent
commit
ce5fe5d0bb
48 changed files with 1246 additions and 511 deletions
  1. 7 0
      changelog.md
  2. 4 1
      db/mysql.sql
  3. 1 1
      front/src/router/index.js
  4. 427 0
      front/src/views/generate/GenerateConfig/index.vue
  5. 112 0
      front/src/views/generate/GenerateHistory/index.vue
  6. 15 414
      front/src/views/generate/index.vue
  7. 10 14
      front/src/views/template/edit.vue
  8. 1 1
      front/src/views/template/index.vue
  9. 5 0
      gen/pom.xml
  10. 11 0
      gen/src/main/java/com/gitee/gen/common/GeneratorParam.java
  11. 80 0
      gen/src/main/java/com/gitee/gen/controller/GenerateHistoryController.java
  12. 66 0
      gen/src/main/java/com/gitee/gen/controller/vo/GenerateHistoryVO.java
  13. 67 0
      gen/src/main/java/com/gitee/gen/entity/GenerateHistory.java
  14. 76 0
      gen/src/main/java/com/gitee/gen/mapper/GenerateHistoryMapper.java
  15. 3 0
      gen/src/main/java/com/gitee/gen/mapper/TemplateConfigMapper.java
  16. 5 0
      gen/src/main/java/com/gitee/gen/service/DatasourceConfigService.java
  17. 107 0
      gen/src/main/java/com/gitee/gen/service/GenerateHistoryService.java
  18. 11 0
      gen/src/main/java/com/gitee/gen/service/GeneratorService.java
  19. 9 0
      gen/src/main/java/com/gitee/gen/service/TemplateConfigService.java
  20. 4 2
      gen/src/main/java/com/gitee/gen/service/UpgradeService.java
  21. 1 1
      gen/src/main/resources/application.properties
  22. 127 0
      gen/src/main/resources/mybatis/GenerateHistoryMapper.xml
  23. 10 0
      gen/src/main/resources/mybatis/TemplateConfigMapper.xml
  24. 1 1
      gen/src/main/resources/public/index.html
  25. 0 0
      gen/src/main/resources/public/static/css/app.e2731d09.css
  26. 0 0
      gen/src/main/resources/public/static/css/chunk-70c97e3b.a254e507.css
  27. 0 0
      gen/src/main/resources/public/static/css/chunk-7618706a.e2948cc9.css
  28. 1 1
      gen/src/main/resources/public/static/css/chunk-libs.dc0bbd27.css
  29. 0 1
      gen/src/main/resources/public/static/js/app.0cd732f6.js
  30. 1 0
      gen/src/main/resources/public/static/js/app.1704855b.js
  31. 0 0
      gen/src/main/resources/public/static/js/chunk-2d0efd67.cc616833.js
  32. 1 1
      gen/src/main/resources/public/static/js/chunk-2d228903.4316af3a.js
  33. 1 0
      gen/src/main/resources/public/static/js/chunk-34242e28.4dcbeb1e.js
  34. 0 1
      gen/src/main/resources/public/static/js/chunk-34242e28.ce617928.js
  35. 0 1
      gen/src/main/resources/public/static/js/chunk-4295c974.c99d0862.js
  36. 0 1
      gen/src/main/resources/public/static/js/chunk-44188c88.3620cd3a.js
  37. 1 0
      gen/src/main/resources/public/static/js/chunk-4de1c2b6.92c42749.js
  38. 0 1
      gen/src/main/resources/public/static/js/chunk-4de1c2b6.9c50e0a4.js
  39. 2 4
      gen/src/main/resources/public/static/js/chunk-53ca05b2.017ee717.js
  40. 0 0
      gen/src/main/resources/public/static/js/chunk-5fb3a2ba.37de9787.js
  41. 1 0
      gen/src/main/resources/public/static/js/chunk-70c97e3b.8b16cf31.js
  42. 0 0
      gen/src/main/resources/public/static/js/chunk-74aeca77.ffdf8285.js
  43. 60 0
      gen/src/main/resources/public/static/js/chunk-libs.3c441178.js
  44. 0 60
      gen/src/main/resources/public/static/js/chunk-libs.62e97045.js
  45. 7 0
      gen/src/main/resources/upgrade/ddl_generate_history_mysql.txt
  46. 6 0
      gen/src/main/resources/upgrade/ddl_generate_history_sqlite.txt
  47. 1 1
      gen/src/main/resources/upgrade/ddl_template_group_sqlite.txt
  48. 4 4
      readme.md

+ 7 - 0
changelog.md

@@ -1,5 +1,12 @@
 # changelog
 
+## 1.4.0
+
+- 增加模板组,可以根据需求选择不同的组的模板
+- 可以给数据源配置默认的包名、删除前缀、以及模板组
+- 表名检索忽略大小写
+- 新增生成历史,可以对历史配置再次生成代码
+
 ## 1.3.5
 
 - 修复mybatis的jdbcType隐射BIGINT错误

+ 4 - 1
db/mysql.sql

@@ -6,13 +6,16 @@ USE `gen`;
 CREATE TABLE `datasource_config` (
   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
   `db_type` int(11) NOT NULL DEFAULT '0' COMMENT '数据库类型,1:MySql, 2:Oracle, 3:sqlserver',
-  `driver_class` varchar(64) NOT NULL DEFAULT '' COMMENT '数据库驱动',
+  `driver_class` varchar(64) DEFAULT '' COMMENT '数据库驱动',
   `db_name` varchar(64) NOT NULL DEFAULT '' COMMENT '数据库名称',
   `host` varchar(64) NOT NULL DEFAULT '' COMMENT '数据库host',
   `port` int(11) NOT NULL DEFAULT '0' COMMENT '数据库端口',
   `username` varchar(64) NOT NULL DEFAULT '' COMMENT '数据库用户名',
   `password` varchar(64) NOT NULL DEFAULT '' COMMENT '数据库密码',
   `is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否已删除,1:已删除,0:未删除',
+  `package_name` varchar(100) DEFAULT NULL,
+  `del_prefix` varchar(200) DEFAULT NULL,
+  `group_id` int(11) DEFAULT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数据源配置表';
 

+ 1 - 1
front/src/router/index.js

@@ -72,7 +72,7 @@ export const constantRoutes = [
   {
     path: '/group',
     component: Layout,
-    meta: { title: '模板组管理', icon: 'table' },
+    meta: { title: '模板组管理', icon: 'example' },
     redirect: '/group/list',
     children: [
       {

+ 427 - 0
front/src/views/generate/GenerateConfig/index.vue

@@ -0,0 +1,427 @@
+<template>
+  <div class="code-gen">
+    <el-form ref="genForm" class="gen-form" :model="clientParam" size="mini" label-width="150px">
+      <el-form-item label="选择数据源" prop="datasourceConfigId" :rules="{required: true, message: '请选择数据源'}">
+        <el-select
+          v-model="clientParam.datasourceConfigId"
+          placeholder="选择数据源"
+          @change="onDataSourceChange"
+        >
+          <el-option
+            v-for="item in datasourceConfigList"
+            :key="item.id"
+            :label="`${item.dbName}(${item.host})`"
+            :value="item.id"
+          >
+            <span style="float: left">{{ `${item.dbName}(${item.host})` }} </span>
+            <span style="float: right; color: #8492a6; font-size: 13px">
+              <el-tooltip placement="top" content="Duplicate">
+                <el-link type="primary" icon="el-icon-document-copy" style="margin-right: 20px;" @click.stop="onDataSourceDuplicate(item)"></el-link>
+              </el-tooltip>
+              <el-link type="primary" icon="el-icon-edit" style="margin-right: 20px;" @click.stop="onDataSourceUpdate(item)"></el-link>
+              <el-link type="danger" icon="el-icon-delete" @click.stop="onDataSourceDelete(item)"></el-link>
+            </span>
+          </el-option>
+        </el-select>
+        <el-button type="text" @click="onDataSourceAdd">新建数据源</el-button>
+      </el-form-item>
+      <el-form-item v-show="showTable" label="包名(package)">
+        <el-input v-model="clientParam.packageName" placeholder="可选,如:cn.studyjava.xxx" show-word-limit maxlength="100" />
+      </el-form-item>
+      <el-form-item v-show="showTable" label="删除前缀">
+        <el-input v-model="clientParam.delPrefix" placeholder="可选,如:sys_user对应Java类为User(多前缀逗号隔开)" show-word-limit maxlength="100" />
+      </el-form-item>
+    </el-form>
+    <el-row v-show="showTable" :gutter="20">
+      <el-col :span="12">
+        <h4>选择表</h4>
+        <el-input
+          v-model="tableSearch"
+          prefix-icon="el-icon-search"
+          clearable
+          size="mini"
+          placeholder="过滤表"
+          style="margin-bottom: 10px;width: 100%;"
+        />
+        <el-table
+          :data="tableListData"
+          border
+          :cell-style="cellStyleSmall()"
+          :header-cell-style="headCellStyleSmall()"
+          :row-class-name="tableRowClassName"
+          @selection-change="onTableListSelect"
+        >
+          <el-table-column
+            type="selection"
+          />
+          <el-table-column
+            prop="tableName"
+            label="表名"
+          />
+        </el-table>
+      </el-col>
+      <el-col :span="12" id="templateSelect">
+        <h4>选择模板</h4>
+        <el-select
+          v-model="clientParam.groupName"
+          placeholder="选择模板所在组"
+          size="mini"
+          @change="onDataGroupChange"
+          style="margin-bottom: 10px; width: 100%;"
+        >
+          <el-option
+            v-for="item in groupData"
+            :key="item.id"
+            :label="`${item.groupName}`"
+            :value="item.id"
+          >
+          </el-option>
+        </el-select>
+        <el-table
+          :data="templateListData"
+          border
+          :cell-style="cellStyleSmall()"
+          :header-cell-style="headCellStyleSmall()"
+          :row-class-name="templateTableRowClassName"
+          @selection-change="onTemplateListSelect"
+        >
+          <el-table-column
+            type="selection"
+          />
+          <el-table-column
+            prop="name"
+            label="模板名称"
+          >
+            <span slot-scope="scope">
+<!--              {{scope.row.groupName}}-{{scope.row.name}}-->
+              {{scope.row.name}}
+            </span>
+          </el-table-column>
+        </el-table>
+        <el-button v-show="showTable" type="primary" @click="onGenerate">生成代码</el-button>
+      </el-col>
+    </el-row>
+
+    <el-dialog
+      :title="datasourceTitle"
+      :visible.sync="datasourceDlgShow"
+    >
+      <el-form
+        ref="datasourceForm"
+        :model="datasourceFormData"
+        :rules="datasourceRule"
+        size="mini"
+        label-width="120px"
+      >
+        <el-form-item label="数据库类型">
+          <el-select
+            v-model="datasourceFormData.dbType"
+            filterable
+            default-first-option
+          >
+            <el-option
+              v-for="item in dbTypeConfig"
+              :key="item.dbType"
+              :label="item.label"
+              :value="item.dbType"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="Host" prop="host">
+          <el-input v-model="datasourceFormData.host" placeholder="地址" show-word-limit maxlength="100" />
+        </el-form-item>
+        <el-form-item label="Port" prop="port">
+          <el-input v-model="datasourceFormData.port" placeholder="端口" show-word-limit maxlength="10" />
+        </el-form-item>
+        <el-form-item label="Database" prop="dbName">
+          <el-input v-model="datasourceFormData.dbName" placeholder="数据库" show-word-limit maxlength="64" />
+        </el-form-item>
+        <el-form-item label="Username" prop="username">
+          <el-input v-model="datasourceFormData.username" placeholder="用户名" show-word-limit maxlength="100" />
+        </el-form-item>
+        <el-form-item label="Password" prop="password">
+          <el-input v-model="datasourceFormData.password" type="password" placeholder="密码" show-word-limit maxlength="100" />
+        </el-form-item>
+        <el-form-item label="包名" prop="packageName">
+          <el-input v-model="datasourceFormData.packageName" placeholder="包名(package)" show-word-limit maxlength="100" />
+        </el-form-item>
+        <el-form-item label="删除前缀" prop="delPrefix">
+          <el-input v-model="datasourceFormData.delPrefix" placeholder="删除前缀(表名sys_user删除前缀sys_对应bean为User)多前缀逗号隔开" show-word-limit maxlength="200" />
+        </el-form-item>
+        <el-form-item label="代码生成器模板" prop="delPrefix">
+          <el-select
+            v-model="datasourceFormData.groupName"
+            placeholder="选择模板所在组"
+            size="mini"
+            @change="onDataGroupChange"
+            style="margin-bottom: 10px; width: 100%;"
+          >
+            <el-option
+              v-for="item in groupData"
+              :key="item.id"
+              :label="`${item.groupName}`"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="success" @click="onDatasourceTest">测试连接</el-button>
+          <el-button type="primary" @click="onDatasourceSave">保存</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+
+  </div>
+</template>
+<style lang="scss">
+  .code-gen {
+    margin: 0 auto;
+    width: 70%;
+      .el-input { width: 450px;}
+      .el-row h4 {
+        text-align: center;
+      }
+      .el-row .el-button {
+        margin-top: 20px;
+      }
+  }
+  .el-table .hidden-row {
+    display: none;
+  }
+  #templateSelect {
+    .el-input { width: 100%;}
+  }
+</style>
+<script>
+export default {
+  name: 'GenerateConfig',
+  data() {
+    return {
+      groupId: '',
+      groupData: {},
+      showTable: false,
+      clientParam: {
+        datasourceConfigId: '',
+        tableNames: [],
+        templateConfigIdList: [],
+        packageName: null,
+        delPrefix: null,
+        groupId: '',
+        groupName: ''
+      },
+      tableSearch: '',
+      datasourceConfigList: [],
+      tableListData: [],
+      templateListData: [],
+      // add datasource
+      datasourceTitle: '新建连接',
+      datasourceDlgShow: false,
+      datasourceFormData: {
+        id: 0,
+        dbType: 1,
+        host: '',
+        port: '',
+        username: '',
+        password: '',
+        dbName: '',
+        packageName: '',
+        delPrefix: '',
+        groupId: '',
+        groupName: ''
+      },
+      dbTypeConfig: [],
+      datasourceRule: {
+        host: [
+          { required: true, message: '不能为空', trigger: 'blur' }
+        ],
+        port: [
+          { required: true, message: '不能为空', trigger: 'blur' }
+        ],
+        username: [
+          { required: true, message: '不能为空', trigger: 'blur' }
+        ],
+        password: [
+          { required: true, message: '不能为空', trigger: 'blur' }
+        ],
+        dbName: [
+          { required: true, message: '不能为空', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  created() {
+    this.loadDataSource()
+    this.loadTemplate()
+    this.loadDbType()
+    this.loadGroups()
+  },
+  methods: {
+    tableRowClassName: function ({row, index}) {
+      // console.log("tablerow="+row.tableName+","+index)
+      row.hidden = false
+      if (this.tableSearch.length === 0) {
+        return ''
+      }
+      // console.log("tablerow="+row.tableName +","+ row.tableName.indexOf(this.tableName)+","+(!(row.tableName && row.tableName.indexOf(this.tableSearch) > -1)))
+      if (!(row.tableName && row.tableName.toLowerCase().indexOf(this.tableSearch.toLowerCase()) > -1)) {
+        row.hidden = true
+        return 'hidden-row';
+      }
+      return ''
+    },
+    templateTableRowClassName: function ({row, index}) {
+      // console.log("temprow="+row.id+",rowGroupId="+row.groupId+", this.groupId="+ this.groupId)
+      row.hidden = false
+      if (this.groupId == '' || this.groupId <= 0) {
+        return ''
+      }
+      // console.log("temprow="+row.groupId +","+(row.groupId && row.groupId == this.groupId))
+      if (row.groupId && row.groupId == this.groupId) {
+        return ''
+      }
+      row.hidden = true
+      return 'hidden-row';
+    },
+    loadGroups() {
+      this.post(`/group/list/`, {}, function(resp) {
+        this.groupData = resp.data
+      })
+    },
+    loadDataSource() {
+      this.post('/datasource/list', {}, resp => {
+        this.datasourceConfigList = resp.data
+      })
+    },
+    loadTemplate() {
+      this.post('/template/list', {}, resp => {
+        this.templateListData = resp.data
+      })
+    },
+    loadDbType() {
+      this.post('/datasource/dbtype', {}, resp => {
+        this.dbTypeConfig = resp.data
+      })
+    },
+    onDataSourceAdd() {
+      this.datasourceTitle = '新建连接'
+      Object.keys(this.datasourceFormData).forEach(key=>{this.datasourceFormData[key]=''})
+      this.datasourceFormData.id = 0
+      this.datasourceDlgShow = true
+    },
+    onTableListSelect(selectedRows) {
+      this.clientParam.tableNames = selectedRows
+        .filter(row => row.hidden === undefined || row.hidden === false)
+        .map(row => row.tableName)
+    },
+    onTemplateListSelect(selectedRows) {
+      this.clientParam.templateConfigIdList = selectedRows
+        .filter(row => row.hidden === undefined || row.hidden === false)
+        .map(row => row.id)
+    },
+    onDataSourceChange(datasourceConfigId) {
+      this.clientParam.datasourceConfigId = datasourceConfigId
+      this.datasourceConfigList.find((item)=>{
+        if(item.id === datasourceConfigId){
+          this.clientParam.packageName = item.packageName;
+          this.clientParam.delPrefix = item.delPrefix;
+          this.groupId = item.groupId;
+          this.groupData.find((gitem)=>{
+            // console.log("gid="+gitem.id+",datasourceConfigGroupId="+item.groupId+","+(gitem.id == item.groupId))
+            if(gitem.id == item.groupId){
+              this.clientParam.groupName = gitem.groupName
+            }
+          });
+
+          console.log("this.clientParam.groupName="+this.clientParam.groupName)
+        }
+      });
+
+      this.post(`/datasource/table/${datasourceConfigId}`, {}, resp => {
+        this.showTable = true
+        this.tableListData = resp.data
+      })
+    },
+    onDataSourceUpdate(item) {
+      this.datasourceTitle = '修改连接'
+      Object.assign(this.datasourceFormData, item)
+      this.groupData.find((gitem)=>{
+        // console.log("gid="+gitem.id+",datasourceConfigGroupId="+item.groupId+","+(gitem.id == this.datasourceFormData.groupId))
+        if(gitem.id == item.groupId){
+          this.datasourceFormData.groupName = gitem.groupName
+        }
+      });
+      this.datasourceDlgShow = true
+    },
+    onDataSourceDuplicate(item) {
+      this.datasourceTitle = `${item.host} Copy`
+      Object.assign(this.datasourceFormData, item)
+      this.datasourceFormData.id = 0
+      this.datasourceDlgShow = true
+    },
+    onDataSourceDelete(row) {
+      this.confirm(`确认要删除 ${row.dbName} 吗?`, function(done) {
+        const data = {
+          id: row.id
+        }
+        this.post('/datasource/del', data, function() {
+          done()
+          location.reload()
+        })
+      })
+    },
+    onGenerate() {
+      this.$refs.genForm.validate((valid) => {
+        if (valid) {
+          if (this.clientParam.tableNames.length === 0) {
+            this.tip('请勾选表', 'error')
+            return
+          }
+          if (this.clientParam.templateConfigIdList.length === 0) {
+            this.tip('请勾选模板', 'error')
+            return
+          }
+          const config = JSON.stringify(this.clientParam)
+          this.goRoute(`result/${config}`)
+        }
+      })
+    },
+    onDatasourceTest() {
+      this.$refs.datasourceForm.validate((valid) => {
+        if (valid) {
+          this.post('/datasource/test', this.datasourceFormData, resp => {
+            this.tip('连接成功')
+          })
+        }
+      })
+    },
+    onDataGroupChange(groupId){
+      // console.log(groupId)
+      if(groupId != ''){
+        this.groupId = groupId
+        this.datasourceFormData.groupId = groupId
+      }
+    },
+    onDatasourceSave() {
+      this.$refs.datasourceForm.validate((valid) => {
+        if (valid) {
+          this.post('/datasource/test', this.datasourceFormData, resp => {
+            if (this.datasourceFormData.id) {
+              this.post('/datasource/update', this.datasourceFormData, resp => {
+                location.reload()
+              })
+            } else {
+              this.post('/datasource/add', this.datasourceFormData, resp => {
+                this.tip('添加成功')
+                this.loadDataSource()
+                this.datasourceDlgShow = false
+              })
+            }
+          })
+        }
+      })
+    }
+  }
+}
+</script>
+

+ 112 - 0
front/src/views/generate/GenerateHistory/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <div>
+    <el-table
+      :data="tableData"
+      border
+      highlight-current-row
+    >
+      <el-table-column
+        prop="generateTime"
+        label="生成时间"
+        width="160"
+      />
+      <el-table-column
+        prop="datasource"
+        label="数据源"
+        width="200"
+      />
+      <el-table-column
+        label="packageName"
+        width="200"
+      >
+        <template slot-scope="scope">
+          {{ scope.row.configContent.packageName }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="删除前缀"
+        width="100"
+        show-overflow-tooltip
+      >
+        <template slot-scope="scope">
+          {{ scope.row.configContent.delPrefix }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="表名"
+      >
+        <template slot-scope="scope">
+          <div v-if="scope.row.configContent.tableNames.length <= 5">
+            {{ scope.row.configContent.tableNames.join('、') }}
+          </div>
+          <div v-else>
+            {{ showArray(scope.row.configContent.tableNames, 3, '、') }}
+            <el-popover
+              placement="left"
+              width="400"
+              trigger="click">
+              <el-table :data="scope.row.configContent.tableNames" max-height="400px">
+                <el-table-column label="表名">
+                  <template slot-scope="scope">{{ scope.row }}</template>
+                </el-table-column>
+              </el-table>
+              <el-button type="text" slot="reference">更多</el-button>
+            </el-popover>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="templateNames"
+        label="模板"
+        show-overflow-tooltip
+      >
+        <template slot-scope="scope">
+          {{ scope.row.templateNames && scope.row.templateNames.join('、') }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="操作"
+        width="100"
+      >
+        <template slot-scope="scope">
+          <el-button type="text" @click="onGenerate(scope.row)">再次生成</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'GenerateHistory',
+  data() {
+    return {
+      tableData: []
+    }
+  },
+  created() {
+    this.loadTable()
+  },
+  methods: {
+    loadTable: function() {
+      this.post('/history/list', {}, function(resp) {
+        this.tableData = resp.data
+      })
+    },
+    onGenerate(row) {
+      const config = JSON.stringify(row.configContent)
+      this.goRoute(`result/${config}`)
+    },
+    showArray(array, limit, split) {
+      if (!array || array.length === 0) {
+        return ''
+      }
+      const ret = []
+      for (let i = 0; i < Math.min(limit, array.length); i++) {
+        ret.push(array[i])
+      }
+      return ret.join(split)
+    }
+  }
+}
+</script>

+ 15 - 414
front/src/views/generate/index.vue

@@ -1,424 +1,25 @@
 <template>
-  <div class="app-container code-gen">
-    <el-form ref="genForm" class="gen-form" :model="clientParam" size="mini" label-width="150px">
-      <el-form-item label="选择数据源" prop="datasourceConfigId" :rules="{required: true, message: '请选择数据源'}">
-        <el-select
-          v-model="clientParam.datasourceConfigId"
-          placeholder="选择数据源"
-          @change="onDataSourceChange"
-        >
-          <el-option
-            v-for="item in datasourceConfigList"
-            :key="item.id"
-            :label="`${item.dbName}(${item.host})`"
-            :value="item.id"
-          >
-            <span style="float: left">{{ `${item.dbName}(${item.host})` }} </span>
-            <span style="float: right; color: #8492a6; font-size: 13px">
-              <el-tooltip placement="top" content="Duplicate">
-                <el-link type="primary" icon="el-icon-document-copy" style="margin-right: 20px;" @click.stop="onDataSourceDuplicate(item)"></el-link>
-              </el-tooltip>
-              <el-link type="primary" icon="el-icon-edit" style="margin-right: 20px;" @click.stop="onDataSourceUpdate(item)"></el-link>
-              <el-link type="danger" icon="el-icon-delete" @click.stop="onDataSourceDelete(item)"></el-link>
-            </span>
-          </el-option>
-        </el-select>
-        <el-button type="text" @click="onDataSourceAdd">新建数据源</el-button>
-      </el-form-item>
-      <el-form-item v-show="showTable" label="包名(package)">
-        <el-input v-model="clientParam.packageName" placeholder="可选,如:cn.studyjava.xxx" show-word-limit maxlength="100" />
-      </el-form-item>
-      <el-form-item v-show="showTable" label="删除前缀">
-        <el-input v-model="clientParam.delPrefix" placeholder="可选,如:sys_user对应Java类为User(多前缀逗号隔开)" show-word-limit maxlength="100" />
-      </el-form-item>
-    </el-form>
-    <el-row v-show="showTable" :gutter="20">
-      <el-col :span="12">
-        <h4>选择表</h4>
-        <el-input
-          v-model="tableSearch"
-          prefix-icon="el-icon-search"
-          clearable
-          size="mini"
-          placeholder="过滤表"
-          style="margin-bottom: 10px;width: 100%;"
-        />
-        <el-table
-          :data="tableListData"
-          border
-          :cell-style="cellStyleSmall()"
-          :header-cell-style="headCellStyleSmall()"
-          :row-class-name="tableRowClassName"
-          @selection-change="onTableListSelect"
-        >
-          <el-table-column
-            type="selection"
-          />
-          <el-table-column
-            prop="tableName"
-            label="表名"
-          />
-        </el-table>
-      </el-col>
-      <el-col :span="12" id="templateSelect">
-        <h4>选择模板</h4>
-        <el-select
-          v-model="clientParam.groupName"
-          placeholder="选择模板所在组"
-          size="mini"
-          @change="onDataGroupChange"
-          style="margin-bottom: 10px; width: 100%;"
-        >
-          <el-option
-            v-for="item in groupData"
-            :key="item.id"
-            :label="`${item.groupName}`"
-            :value="item.id"
-          >
-          </el-option>
-        </el-select>
-        <el-table
-          :data="templateListData"
-          border
-          :cell-style="cellStyleSmall()"
-          :header-cell-style="headCellStyleSmall()"
-          :row-class-name="templateTableRowClassName"
-          @selection-change="onTemplateListSelect"
-        >
-          <el-table-column
-            type="selection"
-          />
-          <el-table-column
-            prop="name"
-            label="模板名称"
-          >
-            <span slot-scope="scope">
-<!--              {{scope.row.groupName}}-{{scope.row.name}}-->
-              {{scope.row.name}}
-            </span>
-          </el-table-column>
-        </el-table>
-        <el-button v-show="showTable" type="primary" @click="onGenerate">生成代码</el-button>
-      </el-col>
-    </el-row>
-
-    <el-dialog
-      :title="datasourceTitle"
-      :visible.sync="datasourceDlgShow"
-    >
-      <el-form
-        ref="datasourceForm"
-        :model="datasourceFormData"
-        :rules="datasourceRule"
-        size="mini"
-        label-width="120px"
-      >
-        <el-form-item label="数据库类型">
-          <el-select
-            v-model="datasourceFormData.dbType"
-            filterable
-            default-first-option
-          >
-            <el-option
-              v-for="item in dbTypeConfig"
-              :key="item.dbType"
-              :label="item.label"
-              :value="item.dbType"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="Host" prop="host">
-          <el-input v-model="datasourceFormData.host" placeholder="地址" show-word-limit maxlength="100" />
-        </el-form-item>
-        <el-form-item label="Port" prop="port">
-          <el-input v-model="datasourceFormData.port" placeholder="端口" show-word-limit maxlength="10" />
-        </el-form-item>
-        <el-form-item label="Database" prop="dbName">
-          <el-input v-model="datasourceFormData.dbName" placeholder="数据库" show-word-limit maxlength="64" />
-        </el-form-item>
-        <el-form-item label="Username" prop="username">
-          <el-input v-model="datasourceFormData.username" placeholder="用户名" show-word-limit maxlength="100" />
-        </el-form-item>
-        <el-form-item label="Password" prop="password">
-          <el-input v-model="datasourceFormData.password" type="password" placeholder="密码" show-word-limit maxlength="100" />
-        </el-form-item>
-        <el-form-item label="包名" prop="packageName">
-          <el-input v-model="datasourceFormData.packageName" placeholder="包名(package)" show-word-limit maxlength="100" />
-        </el-form-item>
-        <el-form-item label="删除前缀" prop="delPrefix">
-          <el-input v-model="datasourceFormData.delPrefix" placeholder="删除前缀(表名sys_user删除前缀sys_对应bean为User)多前缀逗号隔开" show-word-limit maxlength="200" />
-        </el-form-item>
-        <el-form-item label="代码生成器模板" prop="delPrefix">
-          <el-select
-            v-model="datasourceFormData.groupName"
-            placeholder="选择模板所在组"
-            size="mini"
-            @change="onDataGroupChange"
-            style="margin-bottom: 10px; width: 100%;"
-          >
-            <el-option
-              v-for="item in groupData"
-              :key="item.id"
-              :label="`${item.groupName}`"
-              :value="item.id"
-            >
-            </el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item>
-          <el-button type="success" @click="onDatasourceTest">测试连接</el-button>
-          <el-button type="primary" @click="onDatasourceSave">保存</el-button>
-        </el-form-item>
-      </el-form>
-    </el-dialog>
-
+  <div class="app-container">
+    <el-tabs v-model="activeName" type="card">
+      <el-tab-pane name="first">
+        <span slot="label"><i class="el-icon-edit-outline"></i> 生成代码</span>
+        <generate-config />
+      </el-tab-pane>
+      <el-tab-pane name="second">
+        <span slot="label"><i class="el-icon-date"></i> 生成历史</span>
+        <generate-history />
+      </el-tab-pane>
+    </el-tabs>
   </div>
 </template>
-<style lang="scss">
-  .code-gen {
-    margin: 0 auto;
-    width: 70%;
-      .el-input { width: 450px;}
-      .el-row h4 {
-        text-align: center;
-      }
-      .el-row .el-button {
-        margin-top: 20px;
-      }
-  }
-  .el-table .hidden-row {
-    display: none;
-  }
-  #templateSelect {
-    .el-input { width: 100%;}
-  }
-</style>
 <script>
+import GenerateConfig from './GenerateConfig'
+import GenerateHistory from './GenerateHistory'
 export default {
+  components: { GenerateConfig, GenerateHistory },
   data() {
     return {
-      groupId: '',
-      groupData: {},
-      showTable: true,
-      clientParam: {
-        datasourceConfigId: '',
-        tableNames: [],
-        templateConfigIdList: [],
-        packageName: null,
-        delPrefix: null,
-        groupId: '',
-        groupName: ''
-      },
-      tableSearch: '',
-      datasourceConfigList: [],
-      tableListData: [],
-      templateListData: [],
-      // add datasource
-      datasourceTitle: '新建连接',
-      datasourceDlgShow: false,
-      datasourceFormData: {
-        id: 0,
-        dbType: 1,
-        host: '',
-        port: '',
-        username: '',
-        password: '',
-        dbName: '',
-        packageName: '',
-        delPrefix: '',
-        groupId: '',
-        groupName: ''
-      },
-      dbTypeConfig: [],
-      datasourceRule: {
-        host: [
-          { required: true, message: '不能为空', trigger: 'blur' }
-        ],
-        port: [
-          { required: true, message: '不能为空', trigger: 'blur' }
-        ],
-        username: [
-          { required: true, message: '不能为空', trigger: 'blur' }
-        ],
-        password: [
-          { required: true, message: '不能为空', trigger: 'blur' }
-        ],
-        dbName: [
-          { required: true, message: '不能为空', trigger: 'blur' }
-        ]
-      }
-    }
-  },
-  created() {
-    this.loadDataSource()
-    this.loadTemplate()
-    this.loadDbType()
-    this.loadGroups()
-  },
-  methods: {
-    tableRowClassName: function ({row, index}) {
-      // console.log("tablerow="+row.tableName+","+index)
-      row.hidden = false
-      if (this.tableSearch.length === 0) {
-        return ''
-      }
-      // console.log("tablerow="+row.tableName +","+ row.tableName.indexOf(this.tableName)+","+(!(row.tableName && row.tableName.indexOf(this.tableSearch) > -1)))
-      if (!(row.tableName && row.tableName.toLowerCase().indexOf(this.tableSearch.toLowerCase()) > -1)) {
-        row.hidden = true
-        return 'hidden-row';
-      }
-      return ''
-    },
-    templateTableRowClassName: function ({row, index}) {
-      // console.log("temprow="+row.id+",rowGroupId="+row.groupId+", this.groupId="+ this.groupId)
-      row.hidden = false
-      if (this.groupId == '' || this.groupId <= 0) {
-        return ''
-      }
-      // console.log("temprow="+row.groupId +","+(row.groupId && row.groupId == this.groupId))
-      if (row.groupId && row.groupId == this.groupId) {
-        return ''
-      }
-      row.hidden = true
-      return 'hidden-row';
-    },
-    loadGroups() {
-      this.post(`/group/list/`, {}, function(resp) {
-        this.groupData = resp.data
-      })
-    },
-    loadDataSource() {
-      this.post('/datasource/list', {}, resp => {
-        this.datasourceConfigList = resp.data
-      })
-    },
-    loadTemplate() {
-      this.post('/template/list', {}, resp => {
-        this.templateListData = resp.data
-      })
-    },
-    loadDbType() {
-      this.post('/datasource/dbtype', {}, resp => {
-        this.dbTypeConfig = resp.data
-      })
-    },
-    onDataSourceAdd() {
-      this.datasourceTitle = '新建连接'
-      Object.keys(this.datasourceFormData).forEach(key=>{this.datasourceFormData[key]=''})
-      this.datasourceFormData.id = 0
-      this.datasourceDlgShow = true
-    },
-    onTableListSelect(selectedRows) {
-      this.clientParam.tableNames = selectedRows
-        .filter(row => row.hidden === undefined || row.hidden === false)
-        .map(row => row.tableName)
-    },
-    onTemplateListSelect(selectedRows) {
-      this.clientParam.templateConfigIdList = selectedRows
-        .filter(row => row.hidden === undefined || row.hidden === false)
-        .map(row => row.id)
-    },
-    onDataSourceChange(datasourceConfigId) {
-      this.clientParam.datasourceConfigId = datasourceConfigId
-      this.datasourceConfigList.find((item)=>{
-        if(item.id === datasourceConfigId){
-          this.clientParam.packageName = item.packageName;
-          this.clientParam.delPrefix = item.delPrefix;
-          this.groupId = item.groupId;
-          this.groupData.find((gitem)=>{
-            // console.log("gid="+gitem.id+",datasourceConfigGroupId="+item.groupId+","+(gitem.id == item.groupId))
-            if(gitem.id == item.groupId){
-              this.clientParam.groupName = gitem.groupName
-            }
-          });
-
-          console.log("this.clientParam.groupName="+this.clientParam.groupName)
-        }
-      });
-
-      this.post(`/datasource/table/${datasourceConfigId}`, {}, resp => {
-        this.showTable = true
-        this.tableListData = resp.data
-      })
-    },
-    onDataSourceUpdate(item) {
-      this.datasourceTitle = '修改连接'
-      Object.assign(this.datasourceFormData, item)
-      this.groupData.find((gitem)=>{
-        // console.log("gid="+gitem.id+",datasourceConfigGroupId="+item.groupId+","+(gitem.id == this.datasourceFormData.groupId))
-        if(gitem.id == item.groupId){
-          this.datasourceFormData.groupName = gitem.groupName
-        }
-      });
-      this.datasourceDlgShow = true
-    },
-    onDataSourceDuplicate(item) {
-      this.datasourceTitle = `${item.host} Copy`
-      Object.assign(this.datasourceFormData, item)
-      this.datasourceFormData.id = 0
-      this.datasourceDlgShow = true
-    },
-    onDataSourceDelete(row) {
-      this.confirm(`确认要删除 ${row.dbName} 吗?`, function(done) {
-        const data = {
-          id: row.id
-        }
-        this.post('/datasource/del', data, function() {
-          done()
-          location.reload()
-        })
-      })
-    },
-    onGenerate() {
-      this.$refs.genForm.validate((valid) => {
-        if (valid) {
-          if (this.clientParam.tableNames.length === 0) {
-            this.tip('请勾选表', 'error')
-            return
-          }
-          if (this.clientParam.templateConfigIdList.length === 0) {
-            this.tip('请勾选模板', 'error')
-            return
-          }
-          const config = JSON.stringify(this.clientParam)
-          this.goRoute(`result/${config}`)
-        }
-      })
-    },
-    onDatasourceTest() {
-      this.$refs.datasourceForm.validate((valid) => {
-        if (valid) {
-          this.post('/datasource/test', this.datasourceFormData, resp => {
-            this.tip('连接成功')
-          })
-        }
-      })
-    },
-    onDataGroupChange(groupId){
-      // console.log(groupId)
-      if(groupId != ''){
-        this.groupId = groupId
-        this.datasourceFormData.groupId = groupId
-      }
-    },
-    onDatasourceSave() {
-      this.$refs.datasourceForm.validate((valid) => {
-        if (valid) {
-          this.post('/datasource/test', this.datasourceFormData, resp => {
-            if (this.datasourceFormData.id) {
-              this.post('/datasource/update', this.datasourceFormData, resp => {
-                location.reload()
-              })
-            } else {
-              this.post('/datasource/add', this.datasourceFormData, resp => {
-                this.tip('添加成功')
-                this.loadDataSource()
-                this.datasourceDlgShow = false
-              })
-            }
-          })
-        }
-      })
+      activeName: 'first'
     }
   }
 }

+ 10 - 14
front/src/views/template/edit.vue

@@ -14,14 +14,14 @@
             <el-select
               v-model="formData.groupId"
               placeholder="选择模板所在组"
-              @change="onDataGroupChange"
             >
               <el-option
                 v-for="item in groupData"
                 :key="item.id"
-                :label="`${item.groupName}`"
+                :label="item.groupName"
                 :value="item.id"
               >
+                {{ item.groupName }}
               </el-option>
             </el-select>
           </el-form-item>
@@ -153,7 +153,7 @@ export default {
       })
     }
     this.loadVelocityVar()
-    this.loadGroups()
+    this.loadGroups(this.$route.query.groupId)
   },
   methods: {
     loadVelocityVar() {
@@ -173,20 +173,16 @@ export default {
         })
       })
     },
-    loadGroups() {
+    loadGroups(groupId) {
       this.post(`/group/list/`, {}, function(resp) {
         this.groupData = resp.data
-      })
-    },
-    onDataGroupChange(groupId){
-      console.log(groupId)
-      this.formData.groupId = groupId;
-      this.groupData.find((item)=>{
-        if(item.id === groupId){
-          this.formData.groupName = item.groupName
+        if (!groupId && this.groupData.length > 0) {
+          groupId = this.groupData[0].id
         }
-      });
-      console.log(this.formData.groupName)
+        if (groupId) {
+          this.formData.groupId = parseInt(groupId);
+        }
+      })
     },
     onExpressionClick(exp) {
       const codemirror = this.$refs.editor.codemirror

+ 1 - 1
front/src/views/template/index.vue

@@ -66,7 +66,7 @@ export default {
       })
     },
     onAdd: function() {
-      this.goRoute('edit/0')
+      this.goRoute(`edit/0?groupId=${this.groupId}`)
     }
   }
 }

+ 5 - 0
gen/pom.xml

@@ -68,6 +68,11 @@
             <artifactId>ojdbc6</artifactId>
             <version>12.1.0.1-atlassian-hosted</version>
         </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.74</version>
+        </dependency>
         <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
         <dependency>
             <groupId>org.postgresql</groupId>

+ 11 - 0
gen/src/main/java/com/gitee/gen/common/GeneratorParam.java

@@ -66,4 +66,15 @@ public class GeneratorParam {
 		this.charset = charset;
 	}
 
+	@Override
+	public String toString() {
+		return "GeneratorParam{" +
+				"datasourceConfigId=" + datasourceConfigId +
+				", tableNames=" + tableNames +
+				", templateConfigIdList=" + templateConfigIdList +
+				", packageName='" + packageName + '\'' +
+				", delPrefix='" + delPrefix + '\'' +
+				", charset='" + charset + '\'' +
+				'}';
+	}
 }

+ 80 - 0
gen/src/main/java/com/gitee/gen/controller/GenerateHistoryController.java

@@ -0,0 +1,80 @@
+package com.gitee.gen.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.gitee.gen.common.Action;
+import com.gitee.gen.common.GeneratorParam;
+import com.gitee.gen.common.Result;
+import com.gitee.gen.controller.vo.GenerateHistoryVO;
+import com.gitee.gen.entity.DatasourceConfig;
+import com.gitee.gen.entity.GenerateHistory;
+import com.gitee.gen.entity.TemplateConfig;
+import com.gitee.gen.service.DatasourceConfigService;
+import com.gitee.gen.service.GenerateHistoryService;
+import com.gitee.gen.service.TemplateConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("history")
+public class GenerateHistoryController {
+
+    @Autowired
+    private GenerateHistoryService generateHistoryService;
+
+    @Autowired
+    private DatasourceConfigService datasourceConfigService;
+
+    @Autowired
+    private TemplateConfigService templateConfigService;
+
+    /**
+     * 查询所有记录
+     *
+     * @return 返回集合,没有返回空List
+     */
+    @RequestMapping("list")
+    public Result listAll() {
+        List<GenerateHistory> generateHistories = generateHistoryService.listAll();
+        List<GenerateHistoryVO> generateHistoryVOS = generateHistories.stream()
+                .map(generateHistory -> {
+                    GenerateHistoryVO generateHistoryVO = new GenerateHistoryVO();
+                    GeneratorParam generatorParam = JSON.parseObject(generateHistory.getConfigContent(), GeneratorParam.class);
+                    String datasourceInfo = getDatasourceInfo(generatorParam.getDatasourceConfigId());
+                    if (datasourceInfo == null) {
+                        return null;
+                    }
+                    List<String> templateNames = this.listTemplateNames(generatorParam.getTemplateConfigIdList());
+                    generateHistoryVO.setGenerateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(generateHistory.getGenerateTime()));
+                    generateHistoryVO.setConfigContent(generatorParam);
+                    generateHistoryVO.setDatasource(datasourceInfo);
+                    generateHistoryVO.setTemplateNames(templateNames);
+                    return generateHistoryVO;
+                })
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+        return Action.ok(generateHistoryVOS);
+    }
+
+    private String getDatasourceInfo(int datasourceConfigId) {
+        DatasourceConfig datasourceConfig = datasourceConfigService.getById(datasourceConfigId);
+        if (datasourceConfig == null) {
+            return null;
+        }
+        String tpl = "%s(%s:%s)";
+        return String.format(tpl, datasourceConfig.getDbName(), datasourceConfig.getHost(), datasourceConfig.getPort());
+    }
+
+    private List<String> listTemplateNames(List<Integer> idList) {
+        return templateConfigService.listTemplate(idList)
+                .stream()
+                .map(TemplateConfig::getName)
+                .collect(Collectors.toList());
+    }
+
+}

+ 66 - 0
gen/src/main/java/com/gitee/gen/controller/vo/GenerateHistoryVO.java

@@ -0,0 +1,66 @@
+package com.gitee.gen.controller.vo;
+
+import com.gitee.gen.common.GeneratorParam;
+
+import java.util.List;
+
+/**
+ * @author tanghc
+ */
+public class GenerateHistoryVO {
+
+    /*
+    {
+    "datasourceConfigId": 1,
+    "tableNames": [
+        "datasource_config",
+        "generate_history"
+    ],
+    "templateConfigIdList": [
+        1
+    ],
+    "packageName": "com.gitee.gen",
+    "delPrefix": "template_",
+    "groupId": "",
+    "groupName": "JPA"
+}
+     */
+    private GeneratorParam configContent;
+
+    private String generateTime;
+
+    private String datasource;
+    private List<String> templateNames;
+
+    public GeneratorParam getConfigContent() {
+        return configContent;
+    }
+
+    public void setConfigContent(GeneratorParam configContent) {
+        this.configContent = configContent;
+    }
+
+    public String getGenerateTime() {
+        return generateTime;
+    }
+
+    public void setGenerateTime(String generateTime) {
+        this.generateTime = generateTime;
+    }
+
+    public String getDatasource() {
+        return datasource;
+    }
+
+    public void setDatasource(String datasource) {
+        this.datasource = datasource;
+    }
+
+    public List<String> getTemplateNames() {
+        return templateNames;
+    }
+
+    public void setTemplateNames(List<String> templateNames) {
+        this.templateNames = templateNames;
+    }
+}

+ 67 - 0
gen/src/main/java/com/gitee/gen/entity/GenerateHistory.java

@@ -0,0 +1,67 @@
+package com.gitee.gen.entity;
+
+
+import java.util.Date;
+
+public class GenerateHistory {
+	private Integer id;
+	private String configContent;
+	private String md5Value;
+	private Date generateTime;
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public Integer getId() {
+		return this.id;
+	}
+
+	public void setConfigContent(String configContent) {
+		this.configContent = configContent;
+	}
+
+	public String getConfigContent() {
+		return this.configContent;
+	}
+
+	public void setMd5Value(String md5Value) {
+		this.md5Value = md5Value;
+	}
+
+	public String getMd5Value() {
+		return this.md5Value;
+	}
+
+	public Date getGenerateTime() {
+		return generateTime;
+	}
+
+	public void setGenerateTime(Date generateTime) {
+		this.generateTime = generateTime;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) { return true; }
+		if (o == null || getClass() != o.getClass()) {return false;}
+		GenerateHistory that = (GenerateHistory) o;
+		return id.equals(that.id);
+	}
+
+	@Override
+	public int hashCode() {
+		return java.util.Objects.hash(id);
+	}
+
+	@Override
+	public String toString() {
+		return "GenerateHistory{" +
+				"id=" + id +
+				",configContent='" + configContent + "'" +
+				",md5Value='" + md5Value + "'" +
+				",generateTime='" + generateTime + "'" +
+				'}';
+	}
+
+}

+ 76 - 0
gen/src/main/java/com/gitee/gen/mapper/GenerateHistoryMapper.java

@@ -0,0 +1,76 @@
+package com.gitee.gen.mapper;
+
+import com.gitee.gen.entity.GenerateHistory;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface GenerateHistoryMapper {
+
+	/**
+     * 查询所有记录
+     *
+     * @return 返回集合,没有返回空List
+     */
+	List<GenerateHistory> listAll();
+
+
+	/**
+     * 根据主键查询
+     *
+     * @param id 主键
+     * @return 返回记录,没有返回null
+     */
+	GenerateHistory getById(Integer id);
+	
+	/**
+     * 新增,插入所有字段
+     *
+     * @param generateHistory 新增的记录
+     * @return 返回影响行数
+     */
+	int insert(GenerateHistory generateHistory);
+	
+	/**
+     * 新增,忽略null字段
+     *
+     * @param generateHistory 新增的记录
+     * @return 返回影响行数
+     */
+	int insertIgnoreNull(GenerateHistory generateHistory);
+	
+	/**
+     * 修改,修改所有字段
+     *
+     * @param generateHistory 修改的记录
+     * @return 返回影响行数
+     */
+	int update(GenerateHistory generateHistory);
+	
+	/**
+     * 修改,忽略null字段
+     *
+     * @param generateHistory 修改的记录
+     * @return 返回影响行数
+     */
+	int updateIgnoreNull(GenerateHistory generateHistory);
+	
+	/**
+     * 删除记录
+     *
+     * @param generateHistory 待删除的记录
+     * @return 返回影响行数
+     */
+	int delete(GenerateHistory generateHistory);
+
+
+	/**
+	 * 根据md5查询
+	 *
+	 * @param md5 md5
+	 * @return 返回记录,没有返回null
+	 */
+	GenerateHistory getByMd5(@Param("md5") String md5);
+}

+ 3 - 0
gen/src/main/java/com/gitee/gen/mapper/TemplateConfigMapper.java

@@ -2,6 +2,7 @@ package com.gitee.gen.mapper;
 
 import com.gitee.gen.entity.TemplateConfig;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -71,4 +72,6 @@ public interface TemplateConfigMapper {
     int updateGroupNameByGroupId(Integer groupId, String groupName);
 
     int deleteByGroupId(Integer id);
+
+    List<TemplateConfig> listTemplate(@Param("idList") List<Integer> idList);
 }

+ 5 - 0
gen/src/main/java/com/gitee/gen/service/DatasourceConfigService.java

@@ -1,6 +1,7 @@
 package com.gitee.gen.service;
 
 import com.gitee.gen.entity.DatasourceConfig;
+import com.gitee.gen.gen.DbType;
 import com.gitee.gen.mapper.DatasourceConfigMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -26,6 +27,10 @@ public class DatasourceConfigService {
 
     public void insert(DatasourceConfig templateConfig) {
         templateConfig.setIsDeleted(0);
+        DbType dbType = DbType.of(templateConfig.getDbType());
+        if (dbType != null) {
+            templateConfig.setDriverClass(dbType.getDriverClass());
+        }
         datasourceConfigMapper.insert(templateConfig);
     }
 

+ 107 - 0
gen/src/main/java/com/gitee/gen/service/GenerateHistoryService.java

@@ -0,0 +1,107 @@
+package com.gitee.gen.service;
+
+import com.alibaba.fastjson.JSON;
+import com.gitee.gen.common.GeneratorParam;
+import com.gitee.gen.entity.GenerateHistory;
+import com.gitee.gen.mapper.GenerateHistoryMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class GenerateHistoryService {
+
+    @Autowired
+    private GenerateHistoryMapper generateHistoryMapper;
+
+    public void saveHistory(GeneratorParam param) {
+        String content = JSON.toJSONString(param);
+        String md5 = DigestUtils.md5DigestAsHex(content.getBytes(StandardCharsets.UTF_8));
+        GenerateHistory history = generateHistoryMapper.getByMd5(md5);
+        if (history != null) {
+            history.setGenerateTime(new Date());
+            generateHistoryMapper.updateIgnoreNull(history);
+            return;
+        }
+        GenerateHistory generateHistory = new GenerateHistory();
+        generateHistory.setConfigContent(content);
+        generateHistory.setMd5Value(md5);
+        generateHistory.setGenerateTime(new Date());
+        this.insertIgnoreNull(generateHistory);
+    }
+
+    /**
+     * 查询所有记录
+     *
+     * @return 返回集合,没有返回空List
+     */
+    public List<GenerateHistory> listAll() {
+    	return generateHistoryMapper.listAll();
+    }
+
+
+    /**
+     * 根据主键查询
+     *
+     * @param id 主键
+     * @return 返回记录,没有返回null
+     */
+    public GenerateHistory getById(Integer id) {
+    	return generateHistoryMapper.getById(id);
+    }
+	
+    /**
+     * 新增,插入所有字段
+     *
+     * @param generateHistory 新增的记录
+     * @return 返回影响行数
+     */
+    public int insert(GenerateHistory generateHistory) {
+    	return generateHistoryMapper.insert(generateHistory);
+    }
+	
+    /**
+     * 新增,忽略null字段
+     *
+     * @param generateHistory 新增的记录
+     * @return 返回影响行数
+     */
+    public int insertIgnoreNull(GenerateHistory generateHistory) {
+    	return generateHistoryMapper.insertIgnoreNull(generateHistory);
+    }
+	
+    /**
+     * 修改,修改所有字段
+     *
+     * @param generateHistory 修改的记录
+     * @return 返回影响行数
+     */
+    public int update(GenerateHistory generateHistory) {
+    	return generateHistoryMapper.update(generateHistory);
+    }
+	
+    /**
+     * 修改,忽略null字段
+     *
+     * @param generateHistory 修改的记录
+     * @return 返回影响行数
+     */
+    public int updateIgnoreNull(GenerateHistory generateHistory) {
+    	return generateHistoryMapper.updateIgnoreNull(generateHistory);
+    }
+	
+    /**
+     * 删除记录
+     *
+     * @param generateHistory 待删除的记录
+     * @return 返回影响行数
+     */
+    public int delete(GenerateHistory generateHistory) {
+    	return generateHistoryMapper.delete(generateHistory);
+    }
+	
+}

+ 11 - 0
gen/src/main/java/com/gitee/gen/service/GeneratorService.java

@@ -17,6 +17,8 @@ import org.springframework.util.StringUtils;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * 生成代码逻辑
@@ -27,6 +29,11 @@ public class GeneratorService {
     @Autowired
     private TemplateConfigService templateConfigService;
 
+    @Autowired
+    private GenerateHistoryService generateHistoryService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(2);
+
     /**
      * 生成代码内容,map的
      *
@@ -54,6 +61,10 @@ public class GeneratorService {
             }
         }
 
+        executorService.execute(() -> {
+            generateHistoryService.saveHistory(generatorParam);
+        });
+
         return codeFileList;
     }
 

+ 9 - 0
gen/src/main/java/com/gitee/gen/service/TemplateConfigService.java

@@ -4,7 +4,9 @@ import com.gitee.gen.entity.TemplateConfig;
 import com.gitee.gen.mapper.TemplateConfigMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
@@ -17,6 +19,13 @@ public class TemplateConfigService {
     @Autowired
     private TemplateConfigMapper templateConfigMapper;
 
+    public List<TemplateConfig> listTemplate(List<Integer> idList) {
+        if (CollectionUtils.isEmpty(idList)) {
+            return Collections.emptyList();
+        }
+        return templateConfigMapper.listTemplate(idList);
+    }
+
     public TemplateConfig getById(int id) {
         return templateConfigMapper.getById(id);
     }

+ 4 - 2
gen/src/main/java/com/gitee/gen/service/UpgradeService.java

@@ -24,6 +24,7 @@ public class UpgradeService {
     public static final String TABLE_DATASOURCE_CONFIG = "datasource_config";
     public static final String TABLE_TEMPLATE_CONFIG = "template_config";
     public static final String TABLE_TEMPLATE_GROUP = "template_group";
+    public static final String TABLE_GENERATE_HISTORY = "generate_history";
 
     @Autowired
     private UpgradeMapper upgradeMapper;
@@ -56,18 +57,19 @@ public class UpgradeService {
      * 升级v1.4.0
      */
     private void upgradeV1_4_0() {
+        this.createTable(TABLE_GENERATE_HISTORY);
         boolean isCreate = this.createTable(TABLE_TEMPLATE_GROUP);
         if (isCreate) {
             runSql("INSERT INTO `template_group` (`id`, `group_name`, `is_deleted`) VALUES (1,'default',0)");
         }
 
         this.addColumn(TABLE_DATASOURCE_CONFIG, "package_name", "varchar(100)");
-        this.addColumn(TABLE_DATASOURCE_CONFIG, "del_prefix", "varchar(100)");
+        this.addColumn(TABLE_DATASOURCE_CONFIG, "del_prefix", "varchar(200)");
         this.addColumn(TABLE_DATASOURCE_CONFIG, "group_id", "int");
 
         this.addColumn(TABLE_TEMPLATE_CONFIG, "group_id", "int");
         this.addColumn(TABLE_TEMPLATE_CONFIG, "group_name", "varchar(100)");
-        runSql("update template_config set group_id=1,group_name='default' where group_id = NULL");
+        runSql("update template_config set group_id=1,group_name='default' where group_id IS NULL");
     }
 
     private void runSql(String sql) {

+ 1 - 1
gen/src/main/resources/application.properties

@@ -1,5 +1,5 @@
 spring.application.name=gen
-server.port=9999
+server.port=6969
 
 spring.datasource.driver-class-name=org.sqlite.JDBC
 spring.datasource.url=jdbc:sqlite:gen.db

+ 127 - 0
gen/src/main/resources/mybatis/GenerateHistoryMapper.xml

@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.gitee.gen.mapper.GenerateHistoryMapper">
+    <resultMap id="BaseResultMap" type="com.gitee.gen.entity.GenerateHistory">
+        <result column="id" property="id" />
+        <result column="config_content" property="configContent" />
+        <result column="md5_value" property="md5Value" />
+        <result column="generate_time" property="generateTime" />
+    </resultMap>
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id
+        , t.config_content
+        , t.md5_value
+        , t.generate_time
+        </sql>
+
+    <!-- 查询全部 -->
+    <select id="listAll" resultMap="BaseResultMap">
+        SELECT
+        <include refid="baseColumns" />
+        FROM generate_history t
+        ORDER BY id desc
+    </select>
+
+    <!-- 根据主键获取单条记录 -->
+    <select id="getById" resultMap="BaseResultMap" parameterType="Integer">
+        SELECT
+        <include refid="baseColumns" />
+        FROM generate_history t
+        WHERE id = #{id}
+    </select>
+
+    <!-- 插入全部字段 -->
+    <insert id="insert" parameterType="com.gitee.gen.entity.GenerateHistory"
+            keyProperty="id" keyColumn="id" useGeneratedKeys="true"
+    >
+        INSERT INTO generate_history
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            config_content,
+            md5_value,
+            generate_time,
+        </trim>
+        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
+            #{configContent},
+            #{md5Value},
+            #{generateTime},
+        </trim>
+    </insert>
+
+    <!-- 插入不为NULL的字段 -->
+    <insert id="insertIgnoreNull" parameterType="com.gitee.gen.entity.GenerateHistory"
+            keyProperty="id" keyColumn="id" useGeneratedKeys="true"
+    >
+        INSERT INTO generate_history
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+
+            <if test="configContent != null">
+                config_content,
+            </if>
+            <if test="md5Value != null">
+                md5_value,
+            </if>
+            <if test="generateTime != null">
+                generate_time,
+            </if>
+        </trim>
+        <trim prefix="VALUES (" suffix=")" suffixOverrides=",">
+            <if test="configContent != null" >
+                #{configContent},
+            </if>
+            <if test="md5Value != null" >
+                #{md5Value},
+            </if>
+            <if test="generateTime != null" >
+                #{generateTime},
+            </if>
+        </trim>
+    </insert>
+
+    <!-- 更新,更新全部字段 -->
+    <update id="update" parameterType="com.gitee.gen.entity.GenerateHistory">
+        UPDATE generate_history
+        <set>
+            config_content=#{configContent},
+            md5_value=#{md5Value},
+            generate_time=#{generateTime},
+        </set>
+        WHERE id = #{id}
+    </update>
+
+
+    <!-- 更新不为NULL的字段 -->
+    <update id="updateIgnoreNull" parameterType="com.gitee.gen.entity.GenerateHistory">
+        UPDATE generate_history
+        <set>
+            <if test="configContent != null" >
+                config_content=#{configContent},
+            </if>
+            <if test="md5Value != null" >
+                md5_value=#{md5Value},
+            </if>
+            <if test="generateTime != null" >
+                generate_time=#{generateTime},
+            </if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+
+    <!-- 根据主键删除记录 -->
+    <delete id="delete" parameterType="com.gitee.gen.entity.GenerateHistory">
+		UPDATE generate_history
+		SET is_deleted=1
+		WHERE id = #{id}
+	</delete>
+
+    <select id="getByMd5" resultMap="BaseResultMap">
+        SELECT
+        <include refid="baseColumns" />
+        FROM generate_history t
+        WHERE md5_value = #{md5}
+        LIMIT 1
+    </select>
+
+</mapper>

+ 10 - 0
gen/src/main/resources/mybatis/TemplateConfigMapper.xml

@@ -184,4 +184,14 @@
         WHERE group_id = #{groupId}
     </update>
 
+    <select id="listTemplate" resultMap="BaseResultMap">
+        SELECT
+        <include refid="baseColumns" />
+        FROM template_config t
+        WHERE id in
+        <foreach collection="idList" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
 </mapper>

File diff suppressed because it is too large
+ 1 - 1
gen/src/main/resources/public/index.html


gen/src/main/resources/public/static/css/app.aa6ee3c8.css → gen/src/main/resources/public/static/css/app.e2731d09.css


gen/src/main/resources/public/static/css/chunk-44188c88.a254e507.css → gen/src/main/resources/public/static/css/chunk-70c97e3b.a254e507.css


gen/src/main/resources/public/static/css/chunk-4295c974.e2948cc9.css → gen/src/main/resources/public/static/css/chunk-7618706a.e2948cc9.css


File diff suppressed because it is too large
+ 1 - 1
gen/src/main/resources/public/static/css/chunk-libs.dc0bbd27.css


File diff suppressed because it is too large
+ 0 - 1
gen/src/main/resources/public/static/js/app.0cd732f6.js


File diff suppressed because it is too large
+ 1 - 0
gen/src/main/resources/public/static/js/app.1704855b.js


gen/src/main/resources/public/static/js/chunk-2d0efd67.7dba06b9.js → gen/src/main/resources/public/static/js/chunk-2d0efd67.cc616833.js


File diff suppressed because it is too large
+ 1 - 1
gen/src/main/resources/public/static/js/chunk-2d228903.4316af3a.js


File diff suppressed because it is too large
+ 1 - 0
gen/src/main/resources/public/static/js/chunk-34242e28.4dcbeb1e.js


File diff suppressed because it is too large
+ 0 - 1
gen/src/main/resources/public/static/js/chunk-34242e28.ce617928.js


File diff suppressed because it is too large
+ 0 - 1
gen/src/main/resources/public/static/js/chunk-4295c974.c99d0862.js


File diff suppressed because it is too large
+ 0 - 1
gen/src/main/resources/public/static/js/chunk-44188c88.3620cd3a.js


File diff suppressed because it is too large
+ 1 - 0
gen/src/main/resources/public/static/js/chunk-4de1c2b6.92c42749.js


File diff suppressed because it is too large
+ 0 - 1
gen/src/main/resources/public/static/js/chunk-4de1c2b6.9c50e0a4.js


File diff suppressed because it is too large
+ 2 - 4
gen/src/main/resources/public/static/js/chunk-53ca05b2.017ee717.js


+ 0 - 0
gen/src/main/resources/public/static/js/chunk-5fb3a2ba.37de9787.js


File diff suppressed because it is too large
+ 1 - 0
gen/src/main/resources/public/static/js/chunk-70c97e3b.8b16cf31.js


gen/src/main/resources/public/static/js/chunk-74aeca77.f3100fa9.js → gen/src/main/resources/public/static/js/chunk-74aeca77.ffdf8285.js


File diff suppressed because it is too large
+ 60 - 0
gen/src/main/resources/public/static/js/chunk-libs.3c441178.js


File diff suppressed because it is too large
+ 0 - 60
gen/src/main/resources/public/static/js/chunk-libs.62e97045.js


+ 7 - 0
gen/src/main/resources/upgrade/ddl_generate_history_mysql.txt

@@ -0,0 +1,7 @@
+CREATE TABLE `generate_history` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `config_content` text,
+  `md5_value` varchar(64) DEFAULT NULL,
+  `generate_time` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8

+ 6 - 0
gen/src/main/resources/upgrade/ddl_generate_history_sqlite.txt

@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS generate_history (
+  id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
+  config_content text NOT NULL,
+  md5_value varchar(64) DEFAULT NULL,
+  generate_time datetime NOT NULL
+)

+ 1 - 1
gen/src/main/resources/upgrade/ddl_template_group_sqlite.txt

@@ -2,4 +2,4 @@ CREATE TABLE IF NOT EXISTS template_group (
   id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
   group_name varchar(128) NOT NULL,
   is_deleted integer NOT NULL
-);
+)

+ 4 - 4
readme.md

@@ -12,7 +12,7 @@
 
 - 前往[发行版页面](https://gitee.com/durcframework/code-gen/releases),下载最新版本zip文件
 - 解压zip,如果是Mac/Linux操作系统,运行`startup.sh`文件启动,Windows操作系统运行cmd输入`java -jar gen.jar`启动
-- 浏览器访问`http://localhost:9999/`
+- 浏览器访问`http://localhost:6969/`
 
 默认端口是6969,更改端口号按如下方式:
 
@@ -25,7 +25,7 @@
 
 `docker pull tanghc2020/gen:latest`
 
-下载完毕后,执行`docker run --name gen -p 9999:9999 -d <镜像ID>`
+下载完毕后,执行`docker run --name gen -p 6969:6969 -d <镜像ID>`
 
 浏览器访问`http://ip:6969/`
 
@@ -33,7 +33,7 @@
 
 clone代码,然后执行`docker-build.sh`脚本
 
-执行`docker run --name gen -p 9999:9999 -d <镜像ID>`
+执行`docker run --name gen -p 6969:6969 -d <镜像ID>`
 
 ## 其它
 
@@ -67,7 +67,7 @@ Mac/Linux系统可直接执行`build.sh`进行构建,构建结果在`dist`文
     - 执行`mvn clean package`,在`gen/target`下会生成一个`gen-xx-SNAPSHOT.jar`(xx表示本号)
     - 将`gen-xx-SNAPSHOT.jar`和db下的`gen.db`放在同一个文件夹下
     - 执行`java -jar gen-xx-SNAPSHOT.jar`
-    - 浏览器访问`http://localhost:9999/`
+    - 浏览器访问`http://localhost:6969/`
 
 ## 效果图