数据库文档增加oracle支持,前端交互优化
This commit is contained in:
@@ -69,7 +69,7 @@
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>11.2.0.1.0</version>
|
||||
<version>12.1.0.1-atlassian-hosted</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -67,8 +67,8 @@ public class DbSqlExecutorController {
|
||||
if (StringUtils.isBlank(sqlItem)) {
|
||||
continue;
|
||||
}
|
||||
sqlItem = sqlItem.trim();
|
||||
try {
|
||||
sqlItem = sqlItem.trim();
|
||||
Map<String, Object> paramMap = JSON.parseObject(params);
|
||||
ExecuteType executeType = (!manageAuth && select) ? ExecuteType.SELECT : ExecuteType.ALL;
|
||||
ExecuteResult executeResult = sqlExecutor.execute(sourceId, executeId, executeType, sqlItem, paramMap);
|
||||
@@ -78,7 +78,7 @@ public class DbSqlExecutorController {
|
||||
String resultJsonStr = JSON.toJSONString(executeResult, mapping, SerializerFeature.WriteMapNullValue);
|
||||
resultList.add(resultJsonStr);
|
||||
} catch (Exception e) {
|
||||
ExecuteResult executeResult = ExecuteResult.error(StringUtil.getException(e));
|
||||
ExecuteResult executeResult = ExecuteResult.error(StringUtil.getException(e), sqlItem);
|
||||
resultList.add(JSON.toJSONString(executeResult));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@ public class ExecuteResult {
|
||||
private String sql;
|
||||
private List<Map<String, Object>> result;
|
||||
|
||||
public ExecuteResult() {
|
||||
public ExecuteResult(String sql) {
|
||||
this.updateCount = -1;
|
||||
this.useTime = 0;
|
||||
this.result = Collections.emptyList();
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public ExecuteResult(int updateCount, List<Map<String, Object>> result, long useTime, String sql) {
|
||||
@@ -62,8 +63,8 @@ public class ExecuteResult {
|
||||
this.errMsg = errMsg;
|
||||
}
|
||||
|
||||
public static ExecuteResult error(String errMsg) {
|
||||
ExecuteResult executeResult = new ExecuteResult();
|
||||
public static ExecuteResult error(String errMsg, String sql) {
|
||||
ExecuteResult executeResult = new ExecuteResult(sql);
|
||||
executeResult.setErrMsg(errMsg);
|
||||
return executeResult;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class SqlExecutor {
|
||||
*/
|
||||
public ExecuteResult execute(DatabaseFactoryBean factoryBean, String executeId, ExecuteType executeType, String sqlStr, Map<String, Object> paramMap, ResultHandler handler) {
|
||||
if (factoryBean == null) {
|
||||
return new ExecuteResult();
|
||||
return ExecuteResult.error("未找到数据库连接", sqlStr);
|
||||
}
|
||||
// BoundSql boundSql = getBoundSql(sql, paramMap);
|
||||
// sql = boundSql.getSql();
|
||||
|
||||
@@ -1,60 +1,74 @@
|
||||
<?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.zyplayer.doc.db.framework.db.mapper.base.BaseMapper">
|
||||
|
||||
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto" >
|
||||
<result column="NAME" property="name" jdbcType="VARCHAR" />
|
||||
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR" />
|
||||
<result column="TYPE" property="type" jdbcType="VARCHAR" />
|
||||
|
||||
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto" >
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="name" jdbcType="VARCHAR" />
|
||||
<result column="DATA_TYPE" property="type" jdbcType="VARCHAR" />
|
||||
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
|
||||
<result column="LENGTH" property="length" jdbcType="VARCHAR" />
|
||||
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR" />
|
||||
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
|
||||
<result column="COMMENTS" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="QueryTableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto" >
|
||||
|
||||
<resultMap id="QueryTableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto" >
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="columnName" jdbcType="VARCHAR" />
|
||||
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
|
||||
<result column="COMMENTS" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
<!--想用的话就来补充下方法体吧~-->
|
||||
|
||||
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
|
||||
SELECT 1
|
||||
</select>
|
||||
|
||||
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
|
||||
select 1
|
||||
</select>
|
||||
|
||||
<!-- 获取用户列表 -->
|
||||
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
|
||||
select USERNAME dbName db from all_users
|
||||
</select>
|
||||
|
||||
<!-- 获取表列表 -->
|
||||
<select id="getTableList" resultType="com.zyplayer.doc.db.framework.db.dto.TableInfoDto">
|
||||
SELECT 1
|
||||
select t.OWNER as dbName,t.TABLE_NAME as tableName,c.COMMENTS as tableComment from all_tables t left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
<if test="dbName != null"> where t.owner = #{dbName}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 获取表字段集合 -->
|
||||
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
|
||||
select 1
|
||||
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then 1 when 'N' then 0 end NULLABLE, c.COMMENTS
|
||||
from user_tab_columns t left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
t.table_name in (select table_name from all_tables where owner = #{dbName} )
|
||||
<if test="tableName != null"> and t.TABLE_NAME = #{tableName}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
|
||||
select 1
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 条件查询表字段 -->
|
||||
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
|
||||
select 1
|
||||
select t.TABLE_NAME,t.COLUMN_NAME,t.DATA_TYPE,case t.NULLABLE when 'Y' then 1 when 'N' then 0 end NULLABLE, c.COMMENTS
|
||||
from user_tab_columns t
|
||||
left join user_col_comments c on t.COLUMN_NAME = c.COLUMN_NAME and t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
<if test="tableName != null">and t.TABLE_NAME = #{tableName}</if>
|
||||
AND (t.COLUMN_NAME like #{searchText} or c.COMMENTS like #{searchText})
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 条件查询表 -->
|
||||
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
|
||||
select 1
|
||||
select t.OWNER,t.TABLE_NAME as tableName,c.COMMENTS as description
|
||||
from all_tables t
|
||||
left join user_tab_comments c on t.TABLE_NAME = c.TABLE_NAME
|
||||
<where>
|
||||
t.owner = #{owner}
|
||||
<if test="tableName != null">and t.TABLE_NAME = #{tableName}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 增加表注释 -->
|
||||
<insert id="updateTableDesc">
|
||||
select 1
|
||||
comment on table ${dbName}.${tableName} is #{new Desc}
|
||||
</insert>
|
||||
|
||||
<!-- 增加表字段注释 -->
|
||||
<insert id="updateTableColumnDesc">
|
||||
select 1
|
||||
comment on column ${dbName}.${tableName}.${columnName} is #{new Desc}
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var a,i,f,l=0,s=[];l<t.length;l++)i=t[l],o[i]&&s.push(o[i][0]),o[i]=0;for(a in c)Object.prototype.hasOwnProperty.call(c,a)&&(e[a]=c[a]);for(r&&r(t,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=n(n.s=u[l]);return f};var t={},o={2:0};n.e=function(e){function r(){a.onerror=a.onload=null,clearTimeout(i);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var u=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,n.nc&&a.setAttribute("nonce",n.nc),a.src=n.p+""+e+".js?"+{0:"5d425f5ff6468241aa32",1:"0a0403eb1820498dc9bc"}[e];var i=setTimeout(r,12e4);return a.onerror=a.onload=r,u.appendChild(a),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=doc-db-manifest.js.map?81df142ebcf20d4f7a22
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(r&&r(t,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=n(n.s=u[l]);return f};var t={},o={2:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var u=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"818d42fe33c0417cf71b",1:"0a0403eb1820498dc9bc"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,u.appendChild(i),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=doc-db-manifest.js.map?6030633352579ae553ba
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript" src="doc-db-manifest.js?81df142ebcf20d4f7a22"></script><script type="text/javascript" src="doc-db-vendor.js?0a0403eb1820498dc9bc"></script><script type="text/javascript" src="doc-db-index.js?5d425f5ff6468241aa32"></script></body>
|
||||
<script type="text/javascript" src="doc-db-manifest.js?6030633352579ae553ba"></script><script type="text/javascript" src="doc-db-vendor.js?0a0403eb1820498dc9bc"></script><script type="text/javascript" src="doc-db-index.js?818d42fe33c0417cf71b"></script></body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<springfox.swagger.ui.version>2.9.2</springfox.swagger.ui.version>
|
||||
<swagger.bootstrap.ui.version>1.9.4</swagger.bootstrap.ui.version>
|
||||
<zyplayer.doc.version>1.0.4</zyplayer.doc.version>
|
||||
<elasticsearch.version>7.2.0</elasticsearch.version>
|
||||
@@ -89,12 +90,23 @@
|
||||
<artifactId>zyplayer-doc-es</artifactId>
|
||||
<version>${zyplayer.doc.version}</version>
|
||||
</dependency>
|
||||
<!--springfox-swagger-ui-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${springfox.swagger.ui.version}</version>
|
||||
</dependency>
|
||||
<!--swagger-bootstrap-ui-->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
<version>${swagger.bootstrap.ui.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -35,7 +35,10 @@
|
||||
<span v-else>暂未开放</span>
|
||||
</td>
|
||||
<td>{{item.rewriteDomainUrl}}</td>
|
||||
<td>{{item.disabled==1?'已禁用':'已启用'}}</td>
|
||||
<td>
|
||||
<span class="label" v-if="item.disabled==1">已禁用</span>
|
||||
<span class="label label-success" v-else>启用中</span>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-primary" type="button" @click="disableDocUrl(item.location, 0)" v-if="item.disabled==1">启用</button>
|
||||
<button class="btn btn-primary" type="button" @click="disableDocUrl(item.location, 1)" v-else>禁用</button>
|
||||
|
||||
@@ -12,19 +12,22 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<el-menu :router="true" class="el-menu-vertical" style="height: auto;">
|
||||
<el-menu-item index="/"><i class="el-icon-s-home"></i>控制台</el-menu-item>
|
||||
<el-submenu index="1">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-platform"></i>
|
||||
<span slot="title">系统管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/data/datasourceManage"><i class="el-icon-coin"></i>数据源管理</el-menu-item>
|
||||
<el-menu-item index="/data/executor"><i class="el-icon-video-play"></i>SQL执行器</el-menu-item>
|
||||
<el-menu-item index="/data/export"><i class="el-icon-finished"></i>数据库表导出</el-menu-item>
|
||||
</el-submenu>
|
||||
<!-- <el-menu-item index="/"><i class="el-icon-s-home"></i>控制台</el-menu-item>-->
|
||||
<!-- <el-submenu index="1">-->
|
||||
<!-- <template slot="title">-->
|
||||
<!-- <i class="el-icon-s-platform"></i>-->
|
||||
<!-- <span slot="title">系统管理</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <el-menu-item index="/data/datasourceManage"><i class="el-icon-coin"></i>数据源管理</el-menu-item>-->
|
||||
<!-- <el-menu-item index="/data/executor"><i class="el-icon-video-play"></i>SQL执行器</el-menu-item>-->
|
||||
<!-- <el-menu-item index="/data/export"><i class="el-icon-finished"></i>数据库表导出</el-menu-item>-->
|
||||
<!-- </el-submenu>-->
|
||||
<el-menu-item index="/data/datasourceManage"><i class="el-icon-coin"></i>数据源管理</el-menu-item>
|
||||
<el-menu-item index="/data/executor"><i class="el-icon-video-play"></i>SQL执行器</el-menu-item>
|
||||
<el-menu-item index="/data/export"><i class="el-icon-finished"></i>数据库表导出</el-menu-item>
|
||||
</el-menu>
|
||||
<el-tree :props="defaultProps" :data="databaseList" @node-click="handleNodeClick"
|
||||
ref="databaseTree" highlight-current
|
||||
ref="databaseTree" highlight-current empty-text=""
|
||||
:default-expanded-keys="databaseExpandedKeys"
|
||||
node-key="id" @node-expand="handleNodeExpand"
|
||||
style="background-color: #fafafa;">
|
||||
@@ -198,6 +201,7 @@
|
||||
});
|
||||
},
|
||||
loadDatabaseList(sourceId, host, callback) {
|
||||
app.databaseList = [];
|
||||
this.common.post(this.apilist1.databaseList, {sourceId: sourceId}, function (json) {
|
||||
var result = json.data || [];
|
||||
var pathIndex = [];
|
||||
|
||||
@@ -204,8 +204,8 @@
|
||||
}).catch(()=>{});
|
||||
},
|
||||
saveDatasource() {
|
||||
app.datasourceDialogVisible = false;
|
||||
this.common.post(this.apilist1.manageUpdateDatasource, this.newDatasource, function (json) {
|
||||
app.datasourceDialogVisible = false;
|
||||
app.$message.success("保存成功!");
|
||||
app.getDatasourceList();
|
||||
});
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
<div style="padding: 10px;height: 100%;box-sizing: border-box;background: #fafafa;">
|
||||
<el-card style="margin-bottom: 10px;">
|
||||
<div>
|
||||
<el-select v-model="choiceDatasourceId" @change="datasourceChangeEvents" filterable placeholder="请选择数据源" style="width: 400px;">
|
||||
<el-option v-for="item in datasourceList" :key="item.id" :label="item.cnName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
<!-- <el-select v-model="choiceDatabase" @change="databaseChangeEvents" filterable placeholder="请选择数据库">-->
|
||||
<!-- <el-option v-for="item in databaseList" :key="item.dbName" :label="item.dbName" :value="item.dbName"></el-option>-->
|
||||
<!-- </el-select>-->
|
||||
@@ -16,9 +13,13 @@
|
||||
<el-tooltip v-else effect="dark" content="Ctrl+R、Ctrl+Enter" placement="top">
|
||||
<el-button v-on:click="doExecutorSql" type="primary" plain size="small" icon="el-icon-video-play">执行</el-button>
|
||||
</el-tooltip>
|
||||
<div style="float: right;">
|
||||
<el-button v-on:click="addFavorite('')" plain size="small" icon="el-icon-star-off">收藏</el-button>
|
||||
<el-button v-on:click="loadHistoryAndFavoriteList" plain size="small" icon="el-icon-tickets">收藏及历史</el-button>
|
||||
<el-button v-on:click="addFavorite('')" plain size="small" icon="el-icon-star-off">收藏</el-button>
|
||||
<el-button v-on:click="loadHistoryAndFavoriteList" plain size="small" icon="el-icon-tickets">收藏及历史</el-button>
|
||||
<div style="float: right;margin-top: -5px;">
|
||||
数据源:
|
||||
<el-select v-model="choiceDatasourceId" @change="datasourceChangeEvents" filterable placeholder="请选择数据源" style="width: 400px;">
|
||||
<el-option v-for="item in datasourceList" :key="item.id" :label="item.cnName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -38,7 +39,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column v-for="item in resultItem.dataCols" :prop="item.prop" :label="item.prop" :width="item.width">
|
||||
<template slot-scope="scope">
|
||||
<el-input :value="scope.row[item.prop]" :readonly="true"></el-input>
|
||||
<el-input type="textarea" :rows="1" :value="scope.row[item.prop]" :readonly="true" resize="none"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -406,6 +407,11 @@
|
||||
line-height: 25px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.data-executor-vue .execute-result-table .el-textarea__inner{
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.data-executor-vue .execute-use-time{
|
||||
font-size: 12px;margin-right: 10px;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,12 @@
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-card style="margin: 10px;">
|
||||
<div slot="header" class="clearfix">字段信息</div>
|
||||
<div slot="header" class="clearfix">
|
||||
字段信息
|
||||
<el-tooltip effect="dark" content="点击注释列可编辑字段注释" placement="top">
|
||||
<i class="el-icon-info" style="color: #999;"></i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div style="padding: 10px;" v-loading="columnListLoading">
|
||||
<el-table :data="columnList" stripe border style="width: 100%; margin-bottom: 5px;">
|
||||
<el-table-column prop="name" label="字段名" width="200"></el-table-column>
|
||||
|
||||
Reference in New Issue
Block a user