542 lines
22 KiB
HTML
542 lines
22 KiB
HTML
<row class="meta-list">
|
||
<div class="col-md-12">
|
||
<h3 v-text="cfg.title" class="pull-left"></h3>
|
||
</div>
|
||
|
||
<div class="info">
|
||
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
|
||
</div>
|
||
<!-- info -->
|
||
<div class="modal fade" id="f-info">
|
||
<div class="modal-dialog modal-lg">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>
|
||
<h4 class="modal-title">MetaTable概念模型</h4>
|
||
</div>
|
||
<div class="modal-body" style="text-align: center">
|
||
<img src="../res/img/MetaTable.png">
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-12 col-xs-12">
|
||
|
||
<hr style="margin: 0px 5px 5px">
|
||
</div>
|
||
|
||
<!-- 实体列表 -->
|
||
<div class="col-md-4 col-xs-4">
|
||
<div>
|
||
实体表(Meta-Table) <input v-model="filter" placeholder="筛选实体" class="base-input">
|
||
<button @click="loadImportPage()" class="btn btn-primary pull-right" type="button"> <i class="icon icon-signin"></i>导入实体</button>
|
||
</div>
|
||
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
|
||
<li :class="[{'active':alias==item.alias}]" v-for="item in tables" v-if="dealFilter(item)">
|
||
<a @click="alias=item.alias" :title="dealTableLabel(item)" data-toggle="tooltip" v-text="dealTableLabel(item)" href="javascript:;"></a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="col-md-8 col-xs-8">
|
||
<div class="input-group" style="padding-bottom: 10px">
|
||
<div class="pull-left">
|
||
<span class="input-group-btn">
|
||
|
||
</span>
|
||
</div>
|
||
|
||
<span class="input-group-btn" style="padding-left: 5px">
|
||
<button @click="status=8" :class="['btn',{'btn-primary':status==8}]" type="button"> 实体关系</button>
|
||
</span>
|
||
|
||
<span class="input-group-btn" style="padding-left: 10px">
|
||
<button @click="status=2" :class="['btn',{'btn-primary':status==2}]" type="button"> 字段编辑</button>
|
||
</span>
|
||
<span class="input-group-btn">
|
||
<button @click="status=1" :class="['btn',{'btn-primary':status==1}]" type="button"> 字段排序</button>
|
||
</span>
|
||
|
||
<span class="input-group-btn" style="padding-left: 10px">
|
||
<button @click="status=7;" :class="['btn',{'btn-primary':status==7}]" type="button"> 基本属性</button>
|
||
</span>
|
||
|
||
<span class="input-group-btn" style="padding-left: 20px">
|
||
<button @click="save()" :class="['btn',{'btn-primary':status!=0},{'disabled':status==0}]" type="button"> 保存</button>
|
||
</span>
|
||
</div>
|
||
|
||
<!-- 实体属性列表 -->
|
||
<div class="panel" v-show="status!=7 && status!=8">
|
||
|
||
<!-- baseInfo -->
|
||
<div class="base-info">基本属性</div>
|
||
<!--<div class="panel-heading">基本属性配置</div>-->
|
||
<table :class="['table','table-bordered']">
|
||
<tr>
|
||
<th style="width: 100px">表名</th>
|
||
<td><span class="label label-outline" title="表别名alias">{{row.alias}}</span> {{row.tablename}}</td>
|
||
<th>数据平台</th>
|
||
<td>{{dealDbPlatName(row)}}</td>
|
||
</tr>
|
||
<tr>
|
||
<th>描述</th>
|
||
<td>{{row.comment}}</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
|
||
</table>
|
||
|
||
<div class="base-info"> 字段信息</div>
|
||
<table :class="[{'table':status!=2},'table-bordered']">
|
||
<tr>
|
||
<td v-show="status==3 || status==4 || status==5 || status==6"><input type="checkbox"></td>
|
||
<th v-show="status==1"></th>
|
||
<th>列名</th>
|
||
<th>注释</th>
|
||
<th>数据类型</th>
|
||
<!--
|
||
<th>输入类型</th>
|
||
<th>附加属性</th>
|
||
-->
|
||
<th>非空</th>
|
||
<th>主键</th>
|
||
</tr>
|
||
<tr v-for="(item, index) in meta.items" class="item">
|
||
<td v-show="status==1" class="icon icon-move"></td>
|
||
<td v-show="status!=2" v-text="item.name"></td>
|
||
<td v-show="status!=2" v-text="item.label"></td>
|
||
<td v-show="status!=2" v-text="item.type"></td>
|
||
<!--
|
||
<td v-show="status!=2" v-text="item.inType"></td>
|
||
<td v-show="status!=2" v-text="item.inExt"></td>
|
||
-->
|
||
<td v-show="status!=2">
|
||
<i v-if="item.notNull" class="icon icon-check"></i>
|
||
</td>
|
||
<td v-show="status!=2">
|
||
<i v-if="item.pk" class="icon icon-check"></i>
|
||
</td>
|
||
|
||
<td v-show="status==2">
|
||
<input type="hidden" name="item" :value="JSON.stringify(item)">
|
||
<input v-model="item" type="hidden">
|
||
<input :value="item.name" disabled class="form-control">
|
||
<input v-model="item.name" type="hidden">
|
||
<input name="name" type="hidden" :value="item.name">
|
||
</td>
|
||
<td v-show="status==2"><input v-model="item.label" class="form-control"></td>
|
||
<td v-show="status==2"><input v-model="item.type" class="form-control"></td>
|
||
<!--
|
||
<td v-show="status==2">
|
||
<select v-model="item.inType" class="form-control" style="width: 130px">
|
||
<option></option>
|
||
<option v-for="x in inTypes" :value="x">{{x}}</option>
|
||
</select>
|
||
</td>
|
||
<td v-show="status==2"><input v-model="item.inExt" class="form-control"></td>
|
||
-->
|
||
<td v-show="status==2" style="text-align: center">
|
||
<label>
|
||
<input v-model="item.notNull" type="checkbox">
|
||
</label>
|
||
</td>
|
||
<td v-show="status==2" style="text-align: center">
|
||
<label>
|
||
<input v-model="item.pk" type="checkbox">
|
||
</label>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- baseInfo -->
|
||
<div class="panel" v-show="status==7 ">
|
||
<div class="base-info"> 基本属性配置</div>
|
||
<!--<div class="panel-heading">基本属性配置</div>-->
|
||
<div class="panel-body" style="overflow:auto;">
|
||
<form class="form-horizontal">
|
||
<input type="hidden" v-model="row.key">
|
||
<div class="form-group">
|
||
<label for="name" class="col-md-2">表别名</label>
|
||
<div class="col-sm-4">
|
||
<input v-model="row.alias" class="form-control" readonly>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="name" class="col-md-2">表名</label>
|
||
<div class="col-md-4 col-sm-8">
|
||
<input v-model="row.tablename" class="form-control" id="name" placeholder="请输入Table名称">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="comment" class="col-md-2">描述</label>
|
||
<div class="col-md-4 col-sm-8">
|
||
<input v-model="row.comment" class="form-control" id="comment" placeholder="请输入 Table标题">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="col-md-2">数据平台</label>
|
||
<div class="col-sm-2">
|
||
<select v-model="row.dbid" class="form-control">
|
||
<option></option>
|
||
<option v-for="item in dbPlats" :value="item.dbid" v-text="item.dbname"></option>
|
||
</select>
|
||
</div>
|
||
<div class="col-sm-2">
|
||
<select v-model="row.catalog" class="form-control">
|
||
<option></option>
|
||
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel" v-show="status==8">
|
||
<div class="base-info"> 实体关系</div>
|
||
|
||
<p style="padding: 5px">整理中,【实体关系】放到此处维护</p>
|
||
</div>
|
||
|
||
<textarea class="form-control layui-code" v-if="upsql" v-model="upsql" rows="10" id="content" placeholder="/* 没有提交要执行的查询 */" />
|
||
</div>
|
||
|
||
<div class="col-md-10">
|
||
|
||
</div>
|
||
|
||
</row>
|
||
|
||
<script>
|
||
let {tableList, tableInfo, itemSort, itemUpdate} = meta;
|
||
let {showOk} = red
|
||
let {dbList} = plat
|
||
|
||
let vm = new Vue({
|
||
el: ".meta-list",
|
||
data: {
|
||
cfg: {"title": "实体管理"},
|
||
inTypes: ["INPUT", "SELECT_EXT", "INPUT_DT", "FMT_FUN", "FILE"],
|
||
dataTypes: ["bigint(20)", "varchar(255)", "varchar(64)", "varchar(32)", "varchar(16)", "int(11)", "int(3)", "int(2)", "datetime"],
|
||
filterCate: ["EQUAL", "NOTEQUAL", "LIKE", "IN"],
|
||
tables: [],//所有的业务类型,【测试用】
|
||
meta: {
|
||
items: [],
|
||
},//完整的元数据数据,
|
||
move: false,
|
||
status: 0, //页面默认状态
|
||
table: "", //页面选择的table表名称
|
||
alias: "", //页面选择的table表别名
|
||
metaTable: {},
|
||
|
||
itemSort: [], //待保存的业务属性
|
||
|
||
oldItems: [], //不被修改的字段属性
|
||
itemEdit: {}, //待修改的字段属性
|
||
|
||
dbPlats:[],
|
||
row: {tableid: "", platid: "", dbid:"", catalog: "", tablename:"", comment:"", alias: ""},
|
||
filter: {db: "", catalog: "", name: ""},//tableList 过滤条件
|
||
|
||
upsql: "", // 需要执行的 sql语句
|
||
|
||
filter: "",
|
||
},
|
||
watch: {
|
||
metaTable(v) {
|
||
this.tablename = v.tablename
|
||
this.alias = v.alias
|
||
},
|
||
status: function (v) {
|
||
this.setMove(v)
|
||
this.upsql = ''
|
||
},
|
||
alias: function () {
|
||
this.loadDetail();
|
||
},
|
||
"meta.items": {
|
||
handler: function (nv) {
|
||
let itemNv = nv || [];
|
||
let itemOv = this.oldItems || [];
|
||
if (itemOv.length == 0) return;
|
||
|
||
let attr = ["label", "name", "pk", "type", "inType","inExt", 'notNull'];
|
||
let itemEdit = [];
|
||
a:for (let i = 0; i < itemOv.length; i++) {
|
||
for (let j = 0; j < attr.length; j++) {
|
||
let k = attr[j];
|
||
//console.log(itemOv[i][k], '--', itemNv[i][k])
|
||
if (itemOv[i][k] != itemNv[i][k]) {
|
||
itemEdit.push(itemNv[i]);
|
||
continue a;
|
||
}
|
||
}
|
||
}
|
||
|
||
this.itemEdit = itemEdit;
|
||
},
|
||
deep: true
|
||
},
|
||
"meta.shows": function (v) {
|
||
//console.log(v.length)
|
||
},
|
||
tables: function (v) {
|
||
if(v.length > 0) {
|
||
this.metaTable = v[0]
|
||
//vm.table = v[0]["name"];
|
||
}
|
||
},
|
||
|
||
// 基础信息变更 sql
|
||
row: {
|
||
handler: function (row) {
|
||
//console.log(vm.metaTable.name, " -> ",v.name)
|
||
vm.upsql = ''
|
||
if (vm.metaTable.tablename !== row.tablename) {
|
||
vm.upsql += 'RENAME TABLE `{0}`.`{1}` TO `{2}`.`{3}`;\n'.format(vm.metaTable.catalog, vm.metaTable.tablename, vm.metaTable.catalog, row.tablename)
|
||
}
|
||
if (vm.metaTable.comment !== row.comment) {
|
||
vm.upsql += 'ALTER TABLE `{0}`.`{1}` COMMENT=\'{2}\';\n'.format(vm.metaTable.catalog, vm.metaTable.tablename, row.comment)
|
||
}
|
||
},
|
||
deep: true
|
||
},
|
||
|
||
// 属性表更 sql
|
||
itemEdit: {
|
||
handler: function (items) {
|
||
// vm.upsql = 'ALTER TABLE `{0}`.`{1}'.format()
|
||
/*`
|
||
CHANGE `rankcate` `rankcate` VARCHAR(64) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL COMMENT '[排行类型]',
|
||
CHANGE `remark` `remark1` VARCHAR(128) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL COMMENT '[说明]';*/
|
||
|
||
},
|
||
deep: true
|
||
},
|
||
meta: function (v) {
|
||
this.row = {tableid:v.tableid, dbid: v.dbid, catalog: v.catalog, tablename:v.tablename, comment:v.comment, alias: v.alias};
|
||
let oldItems = v['items'] || []
|
||
this.oldItems = JSON.parse(JSON.stringify(oldItems))
|
||
},
|
||
|
||
},
|
||
methods: {
|
||
loadDetail() {
|
||
tableInfo({alias: this.alias}).then(res => {
|
||
this.metaTable = res
|
||
let row = res;
|
||
vm.meta = row;
|
||
let oldItems = [];
|
||
row.items.forEach(item => {
|
||
oldItems.push({label, name, remark, type, inType} = item)
|
||
});
|
||
vm.oldItems = oldItems;
|
||
})
|
||
},
|
||
tableList() {
|
||
tableList().then(res => {
|
||
this.tables = res
|
||
})
|
||
},
|
||
catalogs: function() {
|
||
let dbPlats = this.dbPlats;
|
||
for (i in dbPlats) {
|
||
if (dbPlats[i].dbid === this.row.dbid) {
|
||
return dbPlats[i]["catalogs"]
|
||
}
|
||
}
|
||
},
|
||
setMove: function () {
|
||
if (this.status == 1) {
|
||
$('#sortableList,table>tbody').sortable({
|
||
selector: '.item', // '.list-group-item, tr',
|
||
finish: function (e) {
|
||
let rows = e.list;
|
||
vm.itemSort = [];
|
||
for (let i = 0; i < rows.length; i++) {
|
||
let item = $(rows[i]).find("input[name='name']").val();
|
||
vm.itemSort.push(item);
|
||
}
|
||
},
|
||
// 设置更多选项...
|
||
});
|
||
}
|
||
else if (this.status == 5) {
|
||
$('#show>table>tbody').sortable({
|
||
selector: 'tr',
|
||
finish: function (e) {
|
||
let rows = e.list;
|
||
let shows = [];
|
||
for (let i = 0; i < rows.length; i++) {
|
||
let item = $(rows[i]).find("input[name='name']").val();
|
||
shows.push(item);
|
||
}
|
||
vm.meta.shows = shows;
|
||
}
|
||
});
|
||
} else if (this.status == 4) {
|
||
$('#import>table>tbody').sortable({
|
||
selector: 'tr',
|
||
finish: function (e) {
|
||
let rows = e.list;
|
||
let shows = [];
|
||
for (let i = 0; i < rows.length; i++) {
|
||
let item = $(rows[i]).find("input[name='name']").val();
|
||
shows.push(item);
|
||
}
|
||
vm.meta.imports = shows;
|
||
}
|
||
});
|
||
} else if (this.status == 3) {
|
||
$('#export>table>tbody').sortable({
|
||
selector: 'tr',
|
||
finish: function (e) {
|
||
let rows = e.list;
|
||
let shows = [];
|
||
for (let i = 0; i < rows.length; i++) {
|
||
let item = $(rows[i]).find("input[name='name']").val();
|
||
shows.push(item);
|
||
}
|
||
vm.meta.exports = shows;
|
||
}
|
||
});
|
||
}
|
||
else if (this.status == 6) {
|
||
$('#filter>table>tbody').sortable({
|
||
selector: 'tr',
|
||
finish: function (e) {
|
||
let rows = e.list;
|
||
let filterArr = [];
|
||
for (let i = 0; i < rows.length; i++) {
|
||
let item = $(rows[i]).find("input[name='name']").val();
|
||
filterArr.push(item);
|
||
}
|
||
vm.filterArr = filterArr;
|
||
}
|
||
});
|
||
}
|
||
|
||
else {
|
||
$('table>tbody').sortable('destroy');
|
||
}
|
||
},
|
||
/**
|
||
* 保存元数据变更:
|
||
* 1、基础数据排序
|
||
* --> 传递元素的顺序,后台对元素顺序重排
|
||
* 2、基础数据属性修改
|
||
* --> 只提交被修改过的元素及属性数据,后端通过属性名称对应修改,
|
||
* 3、导出
|
||
* 导出排序
|
||
* --> 传递元素的顺序,后台对元素的顺利重排,(同基础元素排序)
|
||
* 导出元素加减
|
||
* --> 将元素完整传递到后台,进行覆盖保存
|
||
* 4、导入
|
||
* 导入排序
|
||
* 导入元素加减
|
||
* 5、
|
||
*
|
||
* 7、数据平台
|
||
* 记录元数据,存贮的数据平台
|
||
*
|
||
*/
|
||
save: function () {
|
||
if (vm.status == 1 && vm.itemSort.length > 0) {
|
||
itemSort({alias: this.alias, items: this.itemSort}).then(() => red.showOk())
|
||
|
||
}
|
||
|
||
else if (vm.status == 2 && vm.itemEdit.length > 0) {
|
||
itemUpdate({alias: this.alias, items: this.itemEdit}).then(() => red.showOk())
|
||
}
|
||
else if (vm.status == 5) {
|
||
red.post("/meta/showsort", {
|
||
serviceKey: vm.table,
|
||
items: JSON.stringify(vm.meta.shows)
|
||
}).then(() => showOk())
|
||
}
|
||
|
||
else if (vm.status == 6) {
|
||
console.log(vm.filters);
|
||
red.post("/meta/filter_update", {
|
||
serviceKey: vm.table,
|
||
filters: JSON.stringify(vm.filters)
|
||
})
|
||
|
||
}
|
||
|
||
else if (vm.status == 7) {
|
||
console.log(vm.row);
|
||
red.postX("/meta/dbplatupdate", {metaTable: JSON.stringify(vm.row)}).then(() => showOk())
|
||
}
|
||
|
||
else {
|
||
red.showMsg();
|
||
}
|
||
},
|
||
dealTableLabel(table) {
|
||
// (${table.linkCount})
|
||
return `${table.tablename} [${table.comment}]`
|
||
},
|
||
dealFilter(table) {
|
||
// table.name 中是否包含 thiss.filter 的值
|
||
if (table.tablename.indexOf(this.filter) > -1 || table.comment.indexOf(this.filter) > -1) {
|
||
return true
|
||
} else {
|
||
return false
|
||
}
|
||
},
|
||
getFieldLabel (col) {
|
||
if (!col) {
|
||
return "";
|
||
}
|
||
for (var i = 0; i < vm.oldItems.length; i++) {
|
||
if (vm.oldItems[i].name == col) {
|
||
return vm.oldItems[i].label;
|
||
}
|
||
}
|
||
},
|
||
loadImportPage() {
|
||
$("#main").load('/metadata/metatable/import.html')
|
||
},
|
||
showInfo() {
|
||
$('#f-info').modal({moveable: true})
|
||
},
|
||
buildSql() {
|
||
|
||
},
|
||
dealDbPlatName(row) {
|
||
let name = ""
|
||
this.dbPlats.forEach(function (item) {
|
||
if (item.dbid === row.dbid) {
|
||
name = item.dbname
|
||
}
|
||
})
|
||
name += "." + row.catalog
|
||
return name
|
||
}
|
||
},
|
||
mounted: function (){
|
||
dbList().then(res => {
|
||
this.dbPlats = res.rows;
|
||
})
|
||
this.tableList();
|
||
|
||
setTimeout(function () {
|
||
/*layui.use('code', function(){ //加载code模块
|
||
layui.code({title:"",about: false, height: "500"}); //引用code方法
|
||
});*/
|
||
// 手动初始化工具提示
|
||
$('[data-toggle="tooltip"]').tooltip();
|
||
}, 300)
|
||
}
|
||
});
|
||
</script> |