1、修改Mysql线程池逻辑
2、新增数据表信息查询接口 3、优化前端代码逻辑 4、新增业面业务功能提示信息窗口
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,4 +9,6 @@
|
||||
/.idea/
|
||||
/out/
|
||||
/tmp/
|
||||
/libs/
|
||||
/libs/
|
||||
|
||||
apidoc.*
|
||||
6
pom.xml
6
pom.xml
@@ -35,6 +35,12 @@
|
||||
<version>5.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.lxyer</groupId>
|
||||
<artifactId>excel</artifactId>
|
||||
<version>0.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>MySql数据库表结构导出</title>
|
||||
<!-- zui -->
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/css/zui.min.css">
|
||||
<link rel="stylesheet" href="../res/css/zui-theme.css">
|
||||
<link rel="stylesheet" href="../res/css/red-kit.css">
|
||||
<style>
|
||||
.input-group {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container-fixed">
|
||||
<row>
|
||||
<div class="col-md-8">
|
||||
<h3>导出数据库表结构(导出后使用wps打开)</h3>
|
||||
<form>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">jdbc.url</button>
|
||||
</span>
|
||||
<input id="url" type="text" class="form-control" placeholder="jdbc:mysql://127.0.0.1:3306" v-model="jdbc.url">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">jdbc.user</button>
|
||||
</span>
|
||||
<input id="user" type="text" class="form-control" placeholder="请输入数据库用户" v-model="jdbc.user">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">jdbc.pwd</button>
|
||||
</span>
|
||||
<input id="pwd" type="text" class="form-control" placeholder="请输入数据库密码" v-model="jdbc.pwd">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">Database</button>
|
||||
</span>
|
||||
<input id="database" type="text" class="form-control" placeholder="请输入Database" v-model="jdbc.database">
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" v-model="cate" value="word" checked> 导出表结构到word
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" v-model="cate" value="excel"> 导出表结构到excel
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="export" data-toggle="button" class="btn btn-primary" data-cate="word" type="button">导出表结构</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4" v-show="logs.total">
|
||||
<h3>最近使用记录 <small>共 {{logs.total}} 条记录</small></h3>
|
||||
<table class="table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP</th>
|
||||
<th>时间</th>
|
||||
<th>导出数据类型</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in logs.rows">
|
||||
<td v-text="row.remoteAddr"></td>
|
||||
<td v-text="timeFmt(new Date(row.time*1), 'yyyy-MM-dd HH:mm:ss')"></td>
|
||||
<td v-text="row.cate"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</row>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- jQuery (ZUI中的Javascript组件依赖于jQuery) -->
|
||||
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<!-- ZUI Javascript组件 -->
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/js/zui.min.js"></script>
|
||||
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
function getData(key, defaultValue) {
|
||||
var v = localStorage.getItem(key) || defaultValue || "";
|
||||
if (typeof(v) == "string" && v.startsWith("{") && v.endsWith("}")) {
|
||||
v = JSON.parse(v);
|
||||
} else if (typeof(v) == "string" && v.startsWith("[") && v.endsWith("]")) {
|
||||
v = JSON.parse(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
var vm = new Vue({
|
||||
el:".container-fixed",
|
||||
data:{
|
||||
jdbc:getData("jdbc", {url: "jdbc:mysql://192.168.202.11:3306/", user: "root"}),
|
||||
cate: getData("cate", "word"),
|
||||
logs: {}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
loadLog: function() {
|
||||
$.getJSON("/ddl/ddllist",function (json) {
|
||||
vm.logs = json;
|
||||
});
|
||||
},
|
||||
timeFmt: function (date,fmt){
|
||||
var o = {
|
||||
"M+" : date.getMonth()+1, //月份
|
||||
"d+" : date.getDate(), //日
|
||||
"H+" : date.getHours(), //小时
|
||||
"m+" : date.getMinutes(), //分
|
||||
"s+" : date.getSeconds(), //秒
|
||||
"q+" : Math.floor((date.getMonth()+3)/3), //季度
|
||||
"S" : date.getMilliseconds() //毫秒
|
||||
};
|
||||
if(/(y+)/.test(fmt))
|
||||
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
|
||||
for(var k in o)
|
||||
if(new RegExp("("+ k +")").test(fmt))
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
|
||||
return fmt;
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.loadLog();
|
||||
}
|
||||
});
|
||||
|
||||
$("#export").click(function () {
|
||||
localStorage.setItem("jdbc", JSON.stringify(vm.jdbc));
|
||||
localStorage.setItem("cate", vm.cate);
|
||||
$.post("/"+ vm.cate +"/build", {account:JSON.stringify(vm.jdbc)}, function (json) {
|
||||
console.log(json)
|
||||
if (json.code == 0) {
|
||||
location.href = "/"+ vm.cate +"/download";
|
||||
} else {
|
||||
alert(json.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,321 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>高级查询</title>
|
||||
<!-- zui -->
|
||||
<link rel="stylesheet" href="../res/zui/css/zui.min.css">
|
||||
<link rel="stylesheet" href="../res/css/zui-theme.css">
|
||||
<link rel="stylesheet" href="../res/css/red-kit.css">
|
||||
<style>
|
||||
.item {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.table > thead > tr > th.sort:after{
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
font-family: ZenIcon;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
line-height: 1;
|
||||
color: #808080;
|
||||
text-transform: none;
|
||||
content: '\e6bd';
|
||||
speak: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.table > thead > tr > th.sort-up:after {
|
||||
color: #145ccd;
|
||||
content: '\e6b9';
|
||||
}
|
||||
.table > thead > tr > th.sort-down:after {
|
||||
color: #145ccd;
|
||||
content: '\e6b8';
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fixed">
|
||||
<h3>高级查询 - [测试用例]</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" v-model="table" style="width: 300px;">
|
||||
<option v-for="t in tables" :value="t.name">{{t.comment}} [{{t.name}}]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="input-group pull-left">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">添加过滤条件</button>
|
||||
</span>
|
||||
<select class="form-control" v-model="addFilter" style="width: 130px;">
|
||||
<option></option>
|
||||
<option v-for="f in cfg.filters" :value="f.name" :disabled="f.add">{{f.label}}</option>
|
||||
</select>
|
||||
|
||||
|
||||
<span class="input-group-btn">
|
||||
<button @click="findList" class="btn btn-primary" type="button"> 查询</button>
|
||||
</span>
|
||||
<span class="input-group-btn" style="padding-left: 10px">
|
||||
<button @click="exportExcel" class="btn" type="button"> 导出</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="input-group item" v-for="(x,index) in formFilter">
|
||||
<span class="input-group-addon" style="width: 130px">{{x.label}}</span>
|
||||
<select class="form-control" :name="formFilter[index].name + '_cate'" style="width: 100px">
|
||||
<option v-for="t in x.filterType" :value="t.name">{{t.remark}}</option>
|
||||
</select>
|
||||
<span class="input-group-addon fix-border fix-padding"></span>
|
||||
<input type="text" class="form-control" v-model="para[formFilter[index].name]">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-12" style="padding-top: 10px;overflow:auto;">
|
||||
<table class="table table-bordered table-hover" style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="field in cfg.cols"
|
||||
v-text="field.label"
|
||||
:class="{'sort':field.order>0, 'sort-up':field.col==order.col && order.desc==1, 'sort-down':field.col==order.col && order.desc!=1}"
|
||||
@click="sortEvent(field.col)"
|
||||
>
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in list.rows">
|
||||
<td v-for="field in cfg.cols" v-title="dealField(row, field.col)" v-text="dealField(row, field.col)"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<!--<tfoot>
|
||||
<tr>
|
||||
<td :colspan="meta.field_label.length">
|
||||
<ul class="pager pull-right">
|
||||
<li class="previous">
|
||||
<a>{{list.total}}条数据</a>
|
||||
</li>
|
||||
<li :class="['previous', {'disabled':limit.pn==1}]">
|
||||
<a @click="findList(-- limit.pn)" href="javascript:;">«上一页</a>
|
||||
</li>
|
||||
<li :class="['next', {'disabled':limit.pn >= limit.total}]">
|
||||
<a @click="findList(limit.pn = ++limit.pn )" href="javascript:;">»下一页</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>-->
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<ul class="pager pull-right" style="margin: 5px 10px">
|
||||
|
||||
<li class="previous">
|
||||
<a style="border: 0;">共{{list.total}}条数据</a>
|
||||
</li>
|
||||
<li :class="['previous', {'disabled':limit.pn==1}]">
|
||||
<a @click="findList(-- limit.pn)" href="javascript:;">«上一页</a>
|
||||
</li>
|
||||
<li :class="['next', {'disabled':limit.pn >= limit.total}]">
|
||||
<a @click="findList(limit.pn = ++limit.pn )" href="javascript:;">»下一页</a>
|
||||
</li>
|
||||
|
||||
<li class="previous">
|
||||
<a style="border-bottom: 0;border-right: 0;border-top: 0;">到第<input v-model="limit.pn" style="width: 30px;height: 21px;">/ {{limit.total}}页</a>
|
||||
</li>
|
||||
<li class="previous">
|
||||
<a @click="findList(limit.pn)" href="javascript:;">确定</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script src="../res/zui/lib/jquery/jquery.js"></script>
|
||||
<script src="../res/zui/js/zui.js"></script>
|
||||
<script src="../res/zui/lib/sortable/zui.sortable.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
|
||||
<script>
|
||||
var vm = new Vue({
|
||||
el:".row",
|
||||
data: {
|
||||
cfg:{
|
||||
cols: [],
|
||||
filters: []
|
||||
},
|
||||
tables: [],
|
||||
table: "",
|
||||
filters: [],
|
||||
formFilter: [
|
||||
|
||||
],
|
||||
addFilter: "recompany",
|
||||
para: {},
|
||||
list: {},
|
||||
limit: {pn: 1, ps: 10, total: 0},
|
||||
order:{col:"", desc:1}
|
||||
},
|
||||
watch: {
|
||||
addFilter: function (v) {
|
||||
vm.cfg.filters.forEach(function (f) {
|
||||
if (f.name == v) {
|
||||
f["add"] = 1;
|
||||
vm.add = "";
|
||||
vm.formFilter.push(f);
|
||||
}
|
||||
})
|
||||
},
|
||||
table: function (v) {
|
||||
vm.loadCfg();
|
||||
vm.formFilter = [];
|
||||
vm.findList();
|
||||
},
|
||||
list: function () {
|
||||
var limit = vm.limit;
|
||||
var list = vm.list;
|
||||
var total = parseInt(list.total/limit.ps) + (list.total%limit.ps > 0 ? 1 : 0);
|
||||
vm.limit["total"] = total;
|
||||
},
|
||||
limit: {
|
||||
handler(a, b) {
|
||||
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
findList: function (n) {
|
||||
var data = [];
|
||||
for (k in vm.para) {
|
||||
if (vm.para[k] != ''){
|
||||
var d = {};
|
||||
d["col"] = k;
|
||||
d["value"] = vm.para[k];
|
||||
d["type"] = $("select[name="+ k +"_cate]").val();
|
||||
data.push(d);
|
||||
}
|
||||
}
|
||||
|
||||
data.push({col:"status", value: 9, type: "NOTEQUAL"});
|
||||
|
||||
var orders = [];
|
||||
if (vm.order.col) {
|
||||
orders.push(vm.order);
|
||||
}
|
||||
var fBean = {
|
||||
keyService: vm.table,
|
||||
filters: data,
|
||||
orders: orders,
|
||||
limit: vm.limit
|
||||
}
|
||||
$.post("/db/list", {fBean: JSON.stringify(fBean)}, function (json) {
|
||||
vm.list = json.body;
|
||||
});
|
||||
},
|
||||
exportExcel: function() {
|
||||
var data = [];
|
||||
for (k in vm.para) {
|
||||
if (vm.para[k] != ''){
|
||||
var d = {};
|
||||
d["col"] = k;
|
||||
d["value"] = vm.para[k];
|
||||
d["type"] = $("select[name="+ k +"_cate]").val();
|
||||
data.push(d);
|
||||
}
|
||||
}
|
||||
data.push({col:"status", value: 9, type: "NOTEQUAL"});
|
||||
|
||||
var fBean = {
|
||||
keyService: vm.table,
|
||||
filters: data,
|
||||
orders: [{col: "status", desc: -1}],
|
||||
limit:{ps: 5}
|
||||
}
|
||||
location.href = "/export/data?fBean=" + JSON.stringify(fBean);
|
||||
return;
|
||||
},
|
||||
loadTables: function() {
|
||||
$.getJSON("/meta/alltable",function (json) {
|
||||
vm.tables = json;
|
||||
if (!vm.table) {
|
||||
//vm.table = vm.tables[0].name;
|
||||
vm.table = "basic_platform";
|
||||
}
|
||||
});
|
||||
},
|
||||
loadCfg: function () {
|
||||
$.getJSON("/meta/listcfg", {key: vm.table}, function (json) {
|
||||
vm.cfg = json;
|
||||
});
|
||||
},
|
||||
dealField: function (bean, field) {
|
||||
var str = "";
|
||||
if (!bean || !field){
|
||||
|
||||
}else if (typeof(field) === 'function'){
|
||||
str = field(bean);
|
||||
}else if (field.indexOf("||") > 0){//处理字典数据
|
||||
var dic_type = field.split("||")[1];
|
||||
var v = bean[field.split("||")[0]];
|
||||
str = kvExtDeal(dic_type, v);
|
||||
}else if (field.indexOf("|") > 0){//处理字典数据
|
||||
var dic_type = field.split("|")[1];
|
||||
var v = bean[field.split("|")[0]];
|
||||
str = v;//kvDeal(dic_type, v);
|
||||
}
|
||||
else if (field.indexOf("=") > 0){//处理字典数据
|
||||
var fun = field.split("=")[1];
|
||||
var v = bean[field.split("=")[0]];
|
||||
return v;
|
||||
//eval("str =$funs."+ fun +"('"+ v +"')");
|
||||
}
|
||||
else if (field.indexOf("-") > 0){
|
||||
var name = field.split("-")[0];
|
||||
var path = field.split("-")[1];
|
||||
if (bean[name]){
|
||||
var href = config.services.issct+"/downLoadFdfs?fileId="+encodeURI(bean[path])+"&filename="+encodeURI(bean[name]);
|
||||
str = "<a href='"+ href +"' target='_blank'>"+ bean[name] +"</a>";
|
||||
}
|
||||
}else if (bean[field] === 0) { //特殊值 "0" 处理
|
||||
str = "0";
|
||||
}else if (bean[field] == "unknown") { //特殊值处理
|
||||
str = "";
|
||||
}else {
|
||||
str = bean[field] || "";
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
sortEvent: function (col) {
|
||||
if(vm.order.col == col){
|
||||
vm.order.desc = - vm.order.desc
|
||||
}else{
|
||||
vm.order.col = col;
|
||||
vm.order.desc = 1;
|
||||
}
|
||||
vm.findList();
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.loadTables();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,511 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<!-- zui -->
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/zui/1.8.1/css/zui.min.css">
|
||||
<link rel="stylesheet" href="../res/css/zui-theme.css">
|
||||
<link rel="stylesheet" href="../res/css/red-kit.css">
|
||||
<style>
|
||||
.row {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.panel-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.icon-move{
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fixed">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="input-group list-head">
|
||||
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">选择业务类型</button>
|
||||
</span>
|
||||
<select class="form-control" v-model="table" style="width: 300px;">
|
||||
<option v-for="t in tables" :value="t.name">{{t.comment}} [{{t.name}}]</option>
|
||||
</select>
|
||||
|
||||
|
||||
<span class="input-group-btn">
|
||||
<button @click="status=1" :class="['btn',{'btn-primary':status==1}]" type="button"> 排序</button>
|
||||
</span>
|
||||
<span class="input-group-btn">
|
||||
<button @click="status=2" :class="['btn',{'btn-primary':status==2}]" type="button"> 编辑属性</button>
|
||||
</span>
|
||||
|
||||
<span class="input-group-btn" style="padding-left: 20px">
|
||||
<button @click="status=5" :class="['btn',{'btn-primary':status==5}]" type="button"> 列表配置</button>
|
||||
</span>
|
||||
<span class="input-group-btn">
|
||||
<button @click="status=6" :class="['btn',{'btn-primary':status==6}]" type="button"> 查询配置</button>
|
||||
</span>
|
||||
|
||||
<span class="input-group-btn" style="padding-left: 20px">
|
||||
<button @click="status=3" :class="['btn',{'btn-primary':status==3}]" type="button"> 导出配置</button>
|
||||
</span>
|
||||
<span class="input-group-btn">
|
||||
<button @click="status=4" :class="['btn',{'btn-primary':status==4}]" type="button"> 导入配置</button>
|
||||
</span>
|
||||
|
||||
|
||||
<span class="input-group-btn" style="padding-left: 30px">
|
||||
<button @click="metaSave()" :class="['btn',{'btn-primary':status!=0}]" type="button"> 保存修改</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<table class="table-bordered">
|
||||
<thead>
|
||||
<tr style="background-color: #f1f1f1">
|
||||
<td v-show="status==3 || status==4 || status==5"><input type="checkbox"></td>
|
||||
<th v-show="status==1"></th>
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<th>数据类型</th>
|
||||
<th>输入类型</th>
|
||||
<th>附加属性</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in meta.items">
|
||||
<td v-show="status==3"><input type="checkbox" v-model="meta.exports" :value="item.name" class="form-control"></td>
|
||||
<td v-show="status==4"><input type="checkbox" v-model="meta.imports" :value="item.name" class="form-control"></td>
|
||||
<td v-show="status==5"><input type="checkbox" v-model="meta.shows" :value="item.name" class="form-control"></td>
|
||||
<td v-show="status==1" class="icon icon-move"></td>
|
||||
<td v-show="status!=2" v-text="item.name" style="background-color: rgb(235, 235, 228);"></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" v-text="item.remark"></td>
|
||||
|
||||
<td v-show="status==2">
|
||||
<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"><!--<input v-model="item.inType">-->
|
||||
<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"><input v-model="item.remark" class="form-control"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4" v-show="false">
|
||||
<table class="table-bordered table-auto">
|
||||
<thead>
|
||||
<tr style="background-color: #f1f1f1">
|
||||
<th></th>
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<th>展示名</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in meta.items">
|
||||
<td v-show="status!=2" class="icon icon-move"></td>
|
||||
<td v-show="status!=2" v-text="item.name" style="background-color: rgb(235, 235, 228);"></td>
|
||||
<td v-show="status!=2" v-text="item.label"></td>
|
||||
<td v-show="status!=2"><input v-model="item.label" style="width: 100px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-4" v-show="status==5">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
列表展示的属性
|
||||
</div>
|
||||
<div id="show" class="panel-body">
|
||||
<table class="table-bordered table-auto" style="width: 100%">
|
||||
<tr style="background-color: #f1f1f1">
|
||||
<th></th>
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<th>支持排序</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in meta.shows">
|
||||
<td class="icon icon-move">
|
||||
<input name="name" :value="item" type="hidden">
|
||||
</td>
|
||||
<td v-text="item" style="background-color: rgb(235, 235, 228);"></td>
|
||||
<td v-text="">{{getFieldLabel(item)}}</td>
|
||||
<td v-show="false"><input v-model="item.label" style="width: 100px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- exports -->
|
||||
<div class="col-md-4" v-show="status==3">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
导出的属性配置
|
||||
</div>
|
||||
<div id="export" class="panel-body">
|
||||
<table class="table-bordered table-auto" style="width: 100%">
|
||||
<tr style="background-color: #f1f1f1">
|
||||
<th></th>
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<!--<th>展示名</th>-->
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in meta.exports">
|
||||
<td class="icon icon-move">
|
||||
<input name="name" :value="item" type="hidden">
|
||||
</td>
|
||||
<td v-text="item" style="background-color: rgb(235, 235, 228);"></td>
|
||||
<td v-text="">{{getFieldLabel(item)}}</td>
|
||||
<td v-show="false"><input v-model="item.label" style="width: 100px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- imports -->
|
||||
<div class="col-md-4" v-show="status==4">
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
导入的属性配置
|
||||
</div>
|
||||
<div id="import" class="panel-body">
|
||||
<table class="table-bordered table-auto" style="width: 100%">
|
||||
<tr style="background-color: #f1f1f1">
|
||||
<th></th>
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<!--<th>展示名</th>-->
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in meta.imports">
|
||||
<td class="icon icon-move">
|
||||
<input name="name" :value="item" type="hidden">
|
||||
</td>
|
||||
<td v-text="item" style="background-color: rgb(235, 235, 228);"></td>
|
||||
<td v-text="">{{getFieldLabel(item)}}</td>
|
||||
<td v-show="false"><input v-model="item.label" style="width: 100px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- findList -->
|
||||
<div class="col-md-6" v-show="status==6">
|
||||
<!--<div class="form-group">
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox"> fdsaf
|
||||
</label>
|
||||
|
||||
</div>-->
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
高级查询的属性配置
|
||||
</div>
|
||||
<div id="find" class="panel-body" style="overflow:auto;">
|
||||
<table class="table-bordered table-auto" style="width: 100%">
|
||||
<tr style="background-color: #f1f1f1">
|
||||
<th></th>
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<th>支持查询类型</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in meta.filters">
|
||||
<td class="icon icon-move">
|
||||
<input name="name" :value="item.name" type="hidden">
|
||||
</td>
|
||||
<td v-text="item.name" style="background-color: rgb(235, 235, 228);"></td>
|
||||
<td v-text="">{{getFieldLabel(item.name)}}</td>
|
||||
<td>
|
||||
<label class="checkbox-inline" v-for="item in filterCate">
|
||||
<input type="checkbox"> {{item}}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- jQuery (ZUI中的Javascript组件依赖于jQuery) -->
|
||||
<script src="../res/zui/lib/jquery/jquery.js"></script>
|
||||
<!-- ZUI Javascript组件 -->
|
||||
<script src="../res/zui/js/zui.js"></script>
|
||||
<script src="../res/zui/lib/sortable/zui.sortable.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
|
||||
<!--<script src="https://unpkg.com/axios/dist/axios.min.js"></script>-->
|
||||
<script>
|
||||
var vm = new Vue({
|
||||
el:".row",
|
||||
data: {
|
||||
inTypes: ["INPUT", "SELECT_EXT", "INPUT_DT"],
|
||||
dataTypes: ["bigint(20)","varchar(255)","varchar(64)","varchar(32)","varchar(16)","int(11)", "int(3)","int(2)","datetime"],
|
||||
filterCate:["EQUAL","NOTEQUAL","LIKE","IN","NOTEQUAL","LIKE","IN"],
|
||||
tables: [],//所有的业务类型,【测试用】
|
||||
meta: {
|
||||
items: [],
|
||||
shows: [],
|
||||
exports: [],
|
||||
imports: []
|
||||
},//完整的元数据数据,
|
||||
move: false,
|
||||
status:0, //页面默认状态
|
||||
table: "", //页面选择的业务类型
|
||||
itemSort:[], //待保存的业务属性
|
||||
|
||||
oldItems:[], //不被修改的字段属性
|
||||
itemEdit:{}, //待修改的字段属性
|
||||
|
||||
},
|
||||
watch: {
|
||||
status : function (v) {
|
||||
this.canMove(v)
|
||||
},
|
||||
table: function (table) {
|
||||
this.load(table);
|
||||
},
|
||||
"meta.items": {
|
||||
handler: function (nv, ov) {
|
||||
var itemNv = nv || [];
|
||||
var itemOv = vm.oldItems || [];
|
||||
if (itemOv.length == 0) return;
|
||||
|
||||
var itemEdit = [];
|
||||
a:for (var i = 0; i < itemOv.length; i++) {
|
||||
var attr = ["label", "name", "remark", "type", "inType"];
|
||||
for (var j = 0; j < attr.length; j++) {
|
||||
var k = attr[j];
|
||||
if (itemOv[i][k] != itemNv[i][k]) {
|
||||
itemEdit.push(itemNv[i]);
|
||||
continue a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.itemEdit = itemEdit;
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
"meta.shows": function (v) {
|
||||
console.log(v.length)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
load: function (cate) {
|
||||
this.status = 0;
|
||||
$.getJSON("/meta/info?key="+this.table,function (json) {
|
||||
vm.meta = json;
|
||||
|
||||
var oldItems = [];
|
||||
json.items.forEach(function (item) {
|
||||
var d = {};
|
||||
["label", "name", "remark", "type", "inType"].forEach(function (k) {
|
||||
d[k] = item[k];
|
||||
});
|
||||
oldItems.push(d);
|
||||
});
|
||||
vm.oldItems = oldItems;
|
||||
});
|
||||
|
||||
/*axios.get("/meta/info?key="+this.table).then(function (json) {
|
||||
console.log("axios", json)
|
||||
vm.meta = json.data;
|
||||
});*/
|
||||
},
|
||||
getAllTables: function() {
|
||||
$.getJSON("/meta/alltable",function (json) {
|
||||
vm.tables = json;
|
||||
if (!vm.table) {
|
||||
//vm.table = vm.tables[0].name;
|
||||
vm.table = "basic_platform";
|
||||
}
|
||||
});
|
||||
},
|
||||
canMove: function () {
|
||||
if (this.status == 1) {
|
||||
$('#sortableList,table>tbody').sortable({
|
||||
selector: '.list-group-item, tr',
|
||||
finish: function(e) {
|
||||
var rows = e.list;
|
||||
vm.itemSort = [];
|
||||
for (var i=0;i<rows.length;i++) {
|
||||
var 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) {
|
||||
var rows = e.list;
|
||||
var shows = [];
|
||||
for (var i=0;i<rows.length;i++) {
|
||||
var 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) {
|
||||
var rows = e.list;
|
||||
var shows = [];
|
||||
for (var i=0;i<rows.length;i++) {
|
||||
var 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) {
|
||||
var rows = e.list;
|
||||
var shows = [];
|
||||
for (var i=0;i<rows.length;i++) {
|
||||
var item = $(rows[i]).find("input[name='name']").val();
|
||||
shows.push(item);
|
||||
}
|
||||
vm.meta.exports = shows;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('table>tbody').sortable('destroy');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 保存元数据变更:
|
||||
* 1、基础数据排序
|
||||
* --> 传递元素的顺序,后台对元素顺序重排
|
||||
* 2、基础数据属性修改
|
||||
* --> 只提交被修改过的元素及属性数据,后端通过属性名称对应修改,
|
||||
* 3、导出
|
||||
* 导出排序
|
||||
* --> 传递元素的顺序,后台对元素的顺利重排,(同基础元素排序)
|
||||
* 导出元素加减
|
||||
* --> 将元素完整传递到后台,进行覆盖保存
|
||||
* 4、导入
|
||||
* 导入排序
|
||||
* 导入元素加减
|
||||
*
|
||||
*/
|
||||
metaSave: function () {
|
||||
if (vm.status == 1 && vm.itemSort.length > 0) {
|
||||
$.getJSON("/meta/itemsort", {serviceKey:vm.table, items:JSON.stringify(vm.itemSort)}, function (json) {
|
||||
console.log(json);
|
||||
new $.zui.Messager('操作成功', {
|
||||
type: 'info' // 定义颜色主题
|
||||
,placement: "bottom-right"
|
||||
}).show();
|
||||
//vm.status = 0;
|
||||
});
|
||||
}
|
||||
|
||||
else if (vm.status == 2 && vm.itemEdit.length > 0) {
|
||||
$.getJSON("/meta/itemupdate", {serviceKey:vm.table, items:JSON.stringify(vm.itemEdit)}, function (json) {
|
||||
console.log(json);
|
||||
//vm.status = 0;
|
||||
new $.zui.Messager('操作成功', {
|
||||
type: 'info' // 定义颜色主题
|
||||
,placement: "bottom-right"
|
||||
}).show();
|
||||
vm.itemEdit = [];
|
||||
});
|
||||
}
|
||||
else if (vm.status == 3 || vm.status == 4 || vm.status == 5) {
|
||||
var urls = {3: "/meta/exportsort", 4: "/meta/importsort", 5: "/meta/showsort"};
|
||||
var items = {3: vm.meta.exports, 4: vm.meta.imports, 5: vm.meta.shows};
|
||||
|
||||
|
||||
$.getJSON(urls[vm.status], {serviceKey:vm.table, items:JSON.stringify(items[vm.status])}, function (json) {
|
||||
console.log(json);
|
||||
//vm.status = 0;
|
||||
new $.zui.Messager('操作成功', {
|
||||
type: 'info' // 定义颜色主题
|
||||
,placement: "bottom-right"
|
||||
}).show();
|
||||
});
|
||||
}
|
||||
|
||||
else if (vm.status == 5) {
|
||||
$.getJSON("/meta/showsort", {serviceKey:vm.table, items:JSON.stringify(vm.meta.shows)}, function (json) {
|
||||
console.log(json);
|
||||
//vm.status = 0;
|
||||
new $.zui.Messager('操作成功', {
|
||||
type: 'info' // 定义颜色主题
|
||||
,placement: "bottom-right"
|
||||
}).show();
|
||||
});
|
||||
}
|
||||
|
||||
else {
|
||||
new $.zui.Messager('操作成功', {
|
||||
type: 'info' // 定义颜色主题
|
||||
,placement: "bottom-right"
|
||||
}).show();
|
||||
}
|
||||
},
|
||||
getFieldLabel: function (col) {
|
||||
for (var i = 0; i < vm.oldItems.length; i++) {
|
||||
if (vm.oldItems[i].name == col) {
|
||||
return vm.oldItems[i].label;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted: function (){
|
||||
this.getAllTables();
|
||||
//this.canMove();
|
||||
|
||||
/*for (var i = 0; i < 100; i++) {
|
||||
this.load('record_ip')
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
const plat = {
|
||||
|
||||
platList(params) { // 平台列表
|
||||
platList(params = {}) { // 平台列表
|
||||
params['platToken'] = 'xx'
|
||||
return red.getX('/plat/list', params)
|
||||
},
|
||||
platSave({plat}) {
|
||||
@@ -14,4 +15,8 @@ const plat = {
|
||||
dbSave({plat}) {
|
||||
return red.postX('/plat/db_save', {plat})
|
||||
},
|
||||
catalogList({dbAccount, dbPlatId}) { // database列表
|
||||
console.log(dbAccount)
|
||||
return red.postX('/_db/catalog_list', {dbAccount: JSON.stringify(dbAccount), dbPlatId})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
const qtask = {
|
||||
qtaskList() {
|
||||
return red.getX('_qtask/list',{})
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
//import red from '../res/js/red'
|
||||
|
||||
const login = ({username, pwd}, callback) => {
|
||||
$.post("/user/login", {username, pwd}, function (json) {
|
||||
callback(json);
|
||||
});
|
||||
const login = ({username, pwd}) => {
|
||||
return red.postX("/user/login", {username, pwd, platToken: 'xx'})
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
|
||||
@@ -91,7 +91,9 @@
|
||||
<script src="./res/js/red.js" defer></script>
|
||||
<script src="./api/meta.js" defer></script>
|
||||
<script src="./api/plat.js" defer></script>
|
||||
<script src="./api/qtask.js" defer></script>
|
||||
<script src="./res/zui/lib/sortable/zui.sortable.js" defer></script>
|
||||
<script src="./res/zui/lib/uploader/zui.uploader.min.js" defer></script>
|
||||
<!--<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
|
||||
<script type="module">
|
||||
import { logout } from './api/user.js'
|
||||
@@ -108,7 +110,8 @@
|
||||
{name: "MetaData", url: "/meta", nodes: [
|
||||
/*{url:"/metadata/metatable/list.html", name:"TableList"},*/
|
||||
{url:"/metadata/metatable/metaTable.html", name:"MetaTable", icon: "icon-table"},
|
||||
/*{url:"/metadata/metaLink.html", name:"MetaLink"},*/
|
||||
{url:"/metadata/metatable/import.html", name:"导入实体"},
|
||||
{url:"/metadata/metaLink.html", name:"MetaLink"},
|
||||
{url:"/metadata/metaService.html", name:"MetaService", icon:"icon-usecase"},
|
||||
{url:"/metadata/dataList.html", name:"数据查询", icon:"icon-bug"},
|
||||
]
|
||||
@@ -130,7 +133,11 @@
|
||||
{url:"/plat/db.html", name:"数据中心", icon: "icon-database"},
|
||||
]
|
||||
},
|
||||
{name: "关于", url: "/single/about.html"}
|
||||
{name: "关于", url: "/single", nodes: [
|
||||
{url:"/single/about.html", name:"关于", icon:"icon-server"},
|
||||
{url:"/single/metaFlow.html", name:"MetaKit使用", icon:"icon-server"},
|
||||
]
|
||||
},
|
||||
|
||||
],
|
||||
menus: {},
|
||||
@@ -156,7 +163,13 @@
|
||||
}
|
||||
page = page || this.page;
|
||||
this.page = page;
|
||||
$("#main").load(page.url);
|
||||
$("#main").load(page.url, () => this.showInfo());
|
||||
|
||||
},
|
||||
showInfo() {
|
||||
if (red.getData('userName') === 'root') {
|
||||
$('#main .info').show()
|
||||
}
|
||||
},
|
||||
loadMain(item) {
|
||||
this.menus = item.nodes || [item];
|
||||
@@ -179,14 +192,14 @@
|
||||
$this.closest('.nav-parent').addClass('active');
|
||||
});
|
||||
|
||||
$("#main").load(this.page.url);
|
||||
$("#main").load(this.page.url,() => this.showInfo());
|
||||
//this.loadPage(this.page);
|
||||
|
||||
//监听浏览器窗口大小变化
|
||||
function autoLeftHeight() {
|
||||
var h = document.documentElement.clientHeight || document.body.clientHeight;
|
||||
$("#left").attr("style", "height:" + (h - 50) + "px");
|
||||
$("#main").attr("style", "height:" + (h - 50) + "px; overflow: auto;");
|
||||
$("#main").attr("style", "height:" + (h - 90) + "px; overflow: auto;");
|
||||
|
||||
}
|
||||
autoLeftHeight();
|
||||
|
||||
@@ -6,6 +6,28 @@
|
||||
</style>
|
||||
|
||||
<row class="data-list">
|
||||
<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">功能概览</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center">
|
||||
<img src="../res/img/meta_flow.png">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h3>高级查询 - [测试用例]</h3>
|
||||
<div class="col-md-6">
|
||||
<select class="form-control" v-model="service" style="width: 300px;">
|
||||
@@ -274,6 +296,9 @@
|
||||
}
|
||||
return '';
|
||||
},
|
||||
showInfo() {
|
||||
$('#f-info').modal({moveable: true})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.serviceList();
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<row class="meta-link">
|
||||
|
||||
|
||||
</row>
|
||||
|
||||
<script>
|
||||
var vm = new Vue({
|
||||
el: ".meta-link",
|
||||
data: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
mounted: function () {
|
||||
var m = {"a.name": "lxyer", "a.`age`": 11}
|
||||
|
||||
console.log(m["a.name"])
|
||||
|
||||
console.log("---------")
|
||||
for (var k in m) {
|
||||
console.log(k)
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
52
root/metadata/metaLink.html
Normal file
52
root/metadata/metaLink.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<row class="meta-link">
|
||||
<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">功能概览</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center">
|
||||
<p> 数据结构:<br>
|
||||
系统中每个业务实体表都有唯一别名如:用户表-a,部门表-b,角色表-c,
|
||||
</p>
|
||||
<img src="../res/img/meta_link.png">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</row>
|
||||
|
||||
<script>
|
||||
var vm = new Vue({
|
||||
el: ".meta-link",
|
||||
data: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
showInfo() {
|
||||
$('#f-info').modal({moveable: true})
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
var m = {"a.field": "lxyer", "a.`age`": 11}
|
||||
|
||||
console.log(m["a.field"])
|
||||
|
||||
console.log("---------")
|
||||
for (var k in m) {
|
||||
console.log(k)
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -16,6 +16,48 @@
|
||||
</style>
|
||||
<row class="meta-service">
|
||||
<div class="col-md-12" style="padding-top: 10px;">
|
||||
<div class="info" style="padding-left: 10px">
|
||||
<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">功能概览</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: left">
|
||||
<div style="text-align: left">
|
||||
<p>
|
||||
<b>如何创建一个业务?</b><br><!-- <span style="color: #f1a325;font-size: 25px">so easy</span> -->
|
||||
1、选择业务主表、填写名称、标识码<br>
|
||||
2、保存<br>
|
||||
3、业务维护(常规业务维护:列表,查询配置,导出配置,修改基本信息, 以及未开发的:详情配置,表单配置)<br>
|
||||
</p>
|
||||
<p>
|
||||
<b>选择主表的意义,关联表信息业务中如何控制?</b><br>
|
||||
业务主表选择某个表,也即当前业务主要围绕这个实体表进行;<br>
|
||||
对于关联表,只需要在MetaLink中建立关联即可,此处选择了业务主表后会自动查询所有已经关联关联的业务表,<br>
|
||||
然后便可以轻松配置 列表要展示,导出哪些字段,查询过滤条件用哪些表的哪些字段,等等。。
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!--<p>数据存贮结构如下:</p>
|
||||
<img src="../res/img/meta_service.png">-->
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="input-group list-head">
|
||||
|
||||
<span class="input-group-btn">
|
||||
@@ -25,6 +67,9 @@
|
||||
<option v-for="item in services" :value="item.name"> {{item.name}} [{{item.comment}}]</option>
|
||||
</select>
|
||||
|
||||
<span class="input-group-btn pull-left" style="padding-left: 20px">
|
||||
<button @click="tipShow('开发中')" :class="['btn']" type="button"> 新建业务</button>
|
||||
</span>
|
||||
|
||||
|
||||
<span class="input-group-btn" style="padding-left: 20px">
|
||||
@@ -40,6 +85,9 @@
|
||||
<!--<span class="input-group-btn">
|
||||
<button @click="status=4" :class="['btn',{'btn-primary':status==4}]" type="button"> 导入配置</button>
|
||||
</span>-->
|
||||
<!--<span class="input-group-btn" style="padding-left: 20px">
|
||||
<button @click="tipShow()" :class="['btn',{'btn-primary':status==7}]" type="button"> 基本属性</button>
|
||||
</span>-->
|
||||
|
||||
<span class="input-group-btn" style="padding-left: 30px">
|
||||
<button @click="save()" :class="['btn',{'btn-primary':status!=0},{'disabled':status==0}]" type="button"> 保存</button>
|
||||
@@ -218,6 +266,7 @@
|
||||
//import { login } from '../api/user.js'
|
||||
//import { getServiceInfo, getServiceDetail, getServiceList } from '/api/meta.js'
|
||||
let { getServiceInfo, getServiceDetail, getServiceList } = meta;
|
||||
let { showOk } = red
|
||||
|
||||
var vm = new Vue({
|
||||
el: ".meta-service",
|
||||
@@ -453,14 +502,14 @@
|
||||
red.postX("/meta/itemsort", {
|
||||
serviceKey: vm.table,
|
||||
items: JSON.stringify(vm.itemSort)
|
||||
});
|
||||
}).then(() => showOk());
|
||||
}
|
||||
|
||||
else if (vm.status == 2 && vm.itemEdit.length > 0) {
|
||||
red.postX("/meta/itemupdate", {
|
||||
serviceKey: vm.table,
|
||||
items: JSON.stringify(vm.itemEdit)
|
||||
});
|
||||
}).then(() => showOk());
|
||||
}
|
||||
else if (vm.status == 3 || vm.status == 4 /*|| vm.status == 5*/) {
|
||||
var urls = {3: "/meta/exportsort", 4: "/meta/importsort", 5: "/meta/showsort"};
|
||||
@@ -471,7 +520,7 @@
|
||||
red.postX(urls[vm.status], {
|
||||
serviceKey: this.service,
|
||||
items: dataStr
|
||||
});
|
||||
}).then(() => showOk());
|
||||
}
|
||||
|
||||
else if (vm.status == 5) {
|
||||
@@ -480,7 +529,7 @@
|
||||
red.postX("/meta/showsort", {
|
||||
serviceKey: vm.service,
|
||||
items: dataStr
|
||||
});
|
||||
}).then(() => showOk());
|
||||
}
|
||||
|
||||
else if (vm.status == 6) {
|
||||
@@ -493,18 +542,24 @@
|
||||
red.postX("/meta/filter_update", {
|
||||
serviceKey: vm.service,
|
||||
filters: JSON.stringify(red.replace$(filterData))
|
||||
});
|
||||
}).then(() => showOk());
|
||||
|
||||
}
|
||||
|
||||
else if (vm.status == 7) {
|
||||
console.log(vm.row);
|
||||
red.postX("/meta/dbplatupdate", vm.row)
|
||||
red.postX("/meta/dbplatupdate", vm.row).then(() => showOk())
|
||||
}
|
||||
|
||||
else {
|
||||
red.showMsg();
|
||||
}
|
||||
},
|
||||
tipShow() {
|
||||
red.showMsg({msg: '开发中'})
|
||||
},
|
||||
showInfo() {
|
||||
$('#f-info').modal({moveable: true})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
336
root/metadata/metatable/import.html
Normal file
336
root/metadata/metatable/import.html
Normal file
@@ -0,0 +1,336 @@
|
||||
<style>
|
||||
.importDev {
|
||||
padding-top: 5px;
|
||||
}
|
||||
.checkbox-inline:first-child{
|
||||
left: 10px;
|
||||
margin-right: 10px!important;
|
||||
}
|
||||
.checkbox input[type=checkbox], .checkbox-inline input[type=checkbox], .radio input[type=radio], .radio-inline input[type=radio] {
|
||||
margin-top: 12px;
|
||||
}
|
||||
.hv {
|
||||
color: #ea644a!important;
|
||||
}
|
||||
.hv:focus,.hv:hover {
|
||||
color: #8b8a15!important;
|
||||
}
|
||||
.active>.hv{
|
||||
color: #8b8a15!important;
|
||||
}
|
||||
.tlist{
|
||||
height:100%; overflow: auto;
|
||||
}
|
||||
.tlist>li.active>a,
|
||||
.tlist>li.active>a:focus,
|
||||
.tlist>li.active>a:hover,
|
||||
.tlist>li>a:hover {
|
||||
background-color: #92b0cb;
|
||||
}
|
||||
</style>
|
||||
<!-- 对话框HTML -->
|
||||
<div class="importDev">
|
||||
<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">功能概览</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
本地导入、从数据源导入流程相似,都是: 介质中读取可用业务实体 => 选择要导入的实体 => 保存实体到元数据MetaTable
|
||||
</p>
|
||||
<img src="../res/img/table_import_flow.png">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="###" data-target="#tab2Content1" data-toggle="tab">从本地上传</a></li>
|
||||
<li><a href="###" data-target="#tab2Content2" data-toggle="tab">从数据源导入</a></li>
|
||||
<li><a href="###" data-target="#tab2Content3" data-toggle="tab">其他</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade active in" id="tab2Content1">
|
||||
<div id="tableUploader" class="uploader">
|
||||
<!--<div class="uploader-message text-center">
|
||||
<div class="content"></div>
|
||||
<button type="button" class="close">×</button>
|
||||
</div>-->
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="3">选择上传文件</th>
|
||||
<!--<th style="width: 100px">大小</th>
|
||||
<th style="width: 160px; text-align: center;">状态/操作</th>-->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="uploader-files">
|
||||
<tr class="file template">
|
||||
<td style="width: 38px; padding: 3px"><div class="file-icon"></div></td>
|
||||
<td style="padding: 0">
|
||||
<div style="position: relative; padding: 8px;">
|
||||
<strong class="file-field"></strong>
|
||||
<div class="file-progress-bar"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td><span class="file-size text-muted"></span></td>
|
||||
<!--<td class="actions text-right" style="padding: 0 4px;">
|
||||
<div class="file-status" data-toggle="tooltip" style="margin: 8px;"><i class="icon"></i> <span class="text"></span></div>
|
||||
<a data-toggle="tooltip" class="btn btn-link btn-download-file" target="_blank"><i class="icon icon-download-alt"></i></a>
|
||||
<button type="button" data-toggle="tooltip" class="btn btn-link btn-reset-file" title="Repeat"><i class="icon icon-repeat"></i></button>
|
||||
<button type="button" data-toggle="tooltip" class="btn btn-link btn-rename-file" title="Rename"><i class="icon icon-pencil"></i></button>
|
||||
<button type="button" data-toggle="tooltip" title="Remove" class="btn btn-link btn-delete-file"><i class="icon icon-trash text-danger"></i></button>
|
||||
</td>-->
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4" style="padding: 4px 0">
|
||||
<div style="position: relative;">
|
||||
<div class="pull-right text-muted" style="margin-top: 5px;margin-right: 5px">
|
||||
<p v-show="sheet">数据文件已上传,下面<code class="text-danger">红色</code> 部分已经导入过的数据表</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-link uploader-btn-browse"><i class="icon icon-plus"></i> 选择数据文件</button>
|
||||
<button type="button" class="btn btn-link uploader-btn-start"><i class="icon icon-cloud-upload"></i> 上传文件</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="row" v-show="sheet">
|
||||
<div class="col-xs-2 sheet-cell">
|
||||
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> Excel-Sheet</div>
|
||||
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
|
||||
<li class="checkbox-inline clearfix" v-for="item in sheetArr" >
|
||||
<input type="checkbox"
|
||||
v-model="ck"
|
||||
:value="sheetData[item]['field']"
|
||||
:disabled="item=='表说明' || item=='表名称' || sheetData[item]['hv']==1"
|
||||
>
|
||||
<a :class="[{hv: sheetData[item]['hv']==1 }]" href="javascript:;" @click="sheet=item" data-target="#tab3Content1" data-toggle="tab" v-text="item"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-show="ck && ck.length">已选择 <code v-text="ck.length||0"></code> 个实体待导入</p>
|
||||
</div>
|
||||
<div class="col-xs-8">
|
||||
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> Sheet-Detail</div>
|
||||
<div class="tab-content col-xs-9">
|
||||
<div class="tab-pane fade active in" id="">
|
||||
<table class="table-bordered" style="width: 100%">
|
||||
<caption class="" v-show="sheet && (sheet!='表说明' || sheet!='表名称')">
|
||||
表名称: <span v-text="metaTable.field"></span>,中文名:<span v-text="metaTable.comment"></span>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr style="background-color: #f1f1f1" v-show="sheet && sheet!='表说明' && sheet!='表名称'">
|
||||
<th>字段名</th>
|
||||
<th>中文名</th>
|
||||
<th>数据类型</th>
|
||||
<th>输入类型</th>
|
||||
<th>附加属性</th>
|
||||
<th>备注</th>
|
||||
</tr>
|
||||
<tr style="background-color: #f1f1f1" v-show="sheet && (sheet=='表说明' || sheet=='表名称')">
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
<th>D</th>
|
||||
<th>E</th>
|
||||
<th>F</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in metaTable.items">
|
||||
<td v-text="item.field"></td>
|
||||
<td v-text="item.label"></td>
|
||||
<td v-text="item.type"></td>
|
||||
<td v-text="item.inType"></td>
|
||||
<td v-text="item.inExt"></td>
|
||||
<td v-text="item.remark"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--<div class="col-xs-2">
|
||||
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> Checked-Sheet</div>
|
||||
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
|
||||
<li class="checkbox-inline clearfix" v-for="item in ck" >
|
||||
<a href="javascript:;" @click="sheet=getSheetName(item)" data-target="#tab3Content1" data-toggle="tab" v-text="getSheetName(item)"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-show="ck && ck.length">已选择 <code v-text="ck.length||0"></code> 个实体待导入</p>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="tab2Content2">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1">数据源</label>
|
||||
<div class="col-md-2 col-sm-10">
|
||||
<select class="form-control">
|
||||
<option v-for="item in dbPlats" :value="item" v-text="item.field"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<!--<p>1、选择数据源</p>
|
||||
<p>2、选择查询到的数据源实体</p>
|
||||
<p>3、导入选中的实体</p>-->
|
||||
</div>
|
||||
<div class="tab-pane fade" id="tab2Content3">
|
||||
<p>其他一些定制的特殊格式的 实体数据形式</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button @click="ck=[]" type="button" class="btn btn-default" data-dismiss="modal">取消选择</button>
|
||||
<button @click="back()" type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button @click="saveSheet()" type="button" class="btn btn-primary">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let {dbList} = plat
|
||||
|
||||
var vm = new Vue({
|
||||
el: ".importDev",
|
||||
data: {
|
||||
filePath: '',
|
||||
importStatus: false,
|
||||
sheetData: {}, // {name1: {}}
|
||||
sheetArr: [], // [name1,name2,]
|
||||
sheet: '',
|
||||
ck: [],
|
||||
metaTable: {items: []},
|
||||
|
||||
// 从数据源导入实体
|
||||
dbPlats: red.getData('dbPlats'),
|
||||
dbPlatId: '',
|
||||
|
||||
|
||||
cache: {
|
||||
local: {
|
||||
sheetData: {},
|
||||
sheetArr: [],
|
||||
sheet: '',
|
||||
ck: [],
|
||||
metaTable: {items: []},
|
||||
},
|
||||
dbPlat: {}
|
||||
},
|
||||
|
||||
},
|
||||
watch: {
|
||||
sheetData: function (v) {
|
||||
var arr = [];
|
||||
var ck = [];
|
||||
for (k in v) {
|
||||
let field = v[k]['field'];
|
||||
if (k!='表说明' && k!='表名称' && v[k]['hv'] != 1) {
|
||||
ck.push(field);
|
||||
}
|
||||
arr.push(k);
|
||||
}
|
||||
this.sheetArr = arr;
|
||||
this.ck = ck;
|
||||
if (arr.length > 0) {
|
||||
this.sheet = arr[0]
|
||||
} else {
|
||||
this.sheet = "";
|
||||
}
|
||||
},
|
||||
sheet: function (v) {
|
||||
this.metaTable = this.sheetData[v];
|
||||
console.log(this.metaTable)
|
||||
if (this.metaTable['load'] != 1) {
|
||||
this.loadSheetData();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadSheets: function(filePath) {
|
||||
if(!filePath) {
|
||||
return false;
|
||||
}
|
||||
red.post("/file/data",{filePath: filePath}, function (json) {
|
||||
console.log(json)
|
||||
vm.sheetData = json;
|
||||
})
|
||||
},
|
||||
loadSheetData: function() {
|
||||
let sheetName = this.sheet;
|
||||
red.post("/file/sheet_data",{filePath: this.filePath, sheetName: sheetName}, function (json) {
|
||||
json["hv"] = vm.sheetData[sheetName]["hv"];
|
||||
json["load"] = 1;
|
||||
vm.sheetData[sheetName] = json;
|
||||
if (vm.sheet == sheetName) {
|
||||
vm.metaTable = json;
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
saveSheet: function () {
|
||||
if (!this.ck || this.ck.length == 0) {
|
||||
red.showMsg({msg: "请选择导入数据", type:"danger", placement: "top"});
|
||||
return false;
|
||||
}
|
||||
red.post("/file/import_metatable", {sheetArr: JSON.stringify(this.ck), filePath: this.filePath});
|
||||
},
|
||||
getSheetName: function (tableName) {
|
||||
for(k in this.sheetData) {
|
||||
if (this.sheetData[k]['field'] == tableName) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
//return "";
|
||||
},
|
||||
back() {
|
||||
$("#main").load('/metadata/metatable/metaTable.html')
|
||||
},
|
||||
showInfo() {
|
||||
$('#f-info').modal({moveable: true})
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
// 初始化文件上传组件
|
||||
$('#tableUploader').uploader({
|
||||
url: '/upload/x',
|
||||
responseHandler: function (res, file) {
|
||||
var file = JSON.parse(res.response)["body"][0];
|
||||
vm.loadSheets(file["filePath"]);
|
||||
vm.importStatus = true;
|
||||
vm.filePath = file["filePath"];
|
||||
},
|
||||
filters: {
|
||||
mime_types: [
|
||||
{title: 'Excel文件', extensions: 'xls,xlsx'},
|
||||
],
|
||||
prevent_duplicates: true
|
||||
}
|
||||
});
|
||||
|
||||
dbList().then(res => this.dbPlats = res.rows)
|
||||
|
||||
|
||||
var h = document.documentElement.clientHeight || document.body.clientHeight;
|
||||
$(".sheet-cell").attr("style", "height:" + (h - 265) + "px;margin-bottom:20px;");
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -12,6 +12,10 @@
|
||||
<option v-for="item in tables" :value="item.name"> {{item.name}} [{{item.comment}}]</option>
|
||||
</select>
|
||||
|
||||
<span class="input-group-btn pull-left" style="padding-left: 20px">
|
||||
<button @click="loadImportPage()" :class="['btn']" type="button"> 导入实体</button>
|
||||
</span>
|
||||
|
||||
<span class="input-group-btn">
|
||||
<button @click="status=2" :class="['btn',{'btn-primary':status==2}]" type="button"> 字段编辑</button>
|
||||
</span>
|
||||
@@ -283,7 +287,8 @@
|
||||
</row>
|
||||
|
||||
<script>
|
||||
let { getTableList,getTableDetail } = meta;
|
||||
let {getTableList, getTableDetail} = meta;
|
||||
let {showOk} = red
|
||||
|
||||
var vm = new Vue({
|
||||
el: ".meta-list",
|
||||
@@ -493,30 +498,30 @@
|
||||
red.postX("/meta/itemsort", {
|
||||
serviceKey: vm.table,
|
||||
items: JSON.stringify(vm.itemSort)
|
||||
});
|
||||
}).then(() => showOk())
|
||||
}
|
||||
|
||||
else if (vm.status == 2 && vm.itemEdit.length > 0) {
|
||||
red.postX("/meta/itemupdate", {
|
||||
serviceKey: vm.table,
|
||||
items: JSON.stringify(vm.itemEdit)
|
||||
});
|
||||
}).then(() => showOk())
|
||||
}
|
||||
else if (vm.status == 3 || vm.status == 4 || vm.status == 5) {
|
||||
/*else if (vm.status == 3 || vm.status == 4 || vm.status == 5) {
|
||||
var urls = {3: "/meta/exportsort", 4: "/meta/importsort", 5: "/meta/showsort"};
|
||||
var items = {3: vm.meta.exports, 4: vm.meta.imports, 5: vm.meta.shows};
|
||||
|
||||
red.post(urls[vm.status], {
|
||||
serviceKey: vm.table,
|
||||
items: JSON.stringify(items[vm.status])
|
||||
});
|
||||
}
|
||||
})
|
||||
}*/
|
||||
|
||||
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) {
|
||||
@@ -524,13 +529,13 @@
|
||||
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)})
|
||||
red.postX("/meta/dbplatupdate", {metaTable: JSON.stringify(vm.row)}).then(() => showOk())
|
||||
}
|
||||
|
||||
else {
|
||||
@@ -546,6 +551,9 @@
|
||||
return vm.oldItems[i].label;
|
||||
}
|
||||
}
|
||||
},
|
||||
loadImportPage() {
|
||||
$("#main").load('/metadata/metatable/import.html')
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
<row class="plat">
|
||||
|
||||
<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">功能概览</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
数据平台:可以获取数据的平台(除java-method类型的qtask 实列都会对应绑定相应的数据平台)
|
||||
</p>
|
||||
<img src="../res/img/db_plat.png">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- head -->
|
||||
<div class="col-md-11">
|
||||
<h3 v-text="cfg.title"></h3>
|
||||
@@ -54,6 +79,17 @@
|
||||
<input v-model="row.name" class="form-control" id="queryId" placeholder="请输入 平台名称">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="queryId" class="col-sm-2">平台类型</label>
|
||||
<div class="col-md-2 col-sm-10">
|
||||
<select class="form-control" v-model="row.cate">
|
||||
<option value="mysql">MySql</option>
|
||||
<option value="es">ES</option>
|
||||
<option value="htttp">Htttp</option>
|
||||
<option value="method">Method</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="url" class="col-sm-2">连接URL</label>
|
||||
@@ -100,7 +136,8 @@
|
||||
</row>
|
||||
|
||||
<script>
|
||||
let {dbList, dbSave} = plat
|
||||
let {showOk} = red
|
||||
let {dbList, dbSave, catalogList} = plat
|
||||
|
||||
var vm = new Vue({
|
||||
el: ".plat",
|
||||
@@ -150,24 +187,11 @@
|
||||
|
||||
},
|
||||
methods: {
|
||||
findList: function () {
|
||||
dbList().then(res => {
|
||||
vm.list = res;
|
||||
})
|
||||
|
||||
/*var para = {
|
||||
doc:"db_plat",
|
||||
shows: JSON.stringify(["_id", "name", "url", "user", "pwd", "catalogs", "remark", "status"])
|
||||
};
|
||||
red.getJSON("/meta/find", para, function (json) {
|
||||
for (var i=0; i<json.rows.length; i++) {
|
||||
json.rows[i]["pulse"] = "";
|
||||
}
|
||||
vm.list = json;
|
||||
})*/
|
||||
findList() {
|
||||
dbList().then(res => vm.list = res)
|
||||
},
|
||||
update: function (kv, row) {
|
||||
red.post("/meta/save", {
|
||||
/*update: function (kv, row) {
|
||||
red.post('/meta/save', {
|
||||
_id: row._id,
|
||||
doc: JSON.stringify(kv)
|
||||
}, function (json) {
|
||||
@@ -175,38 +199,30 @@
|
||||
red.putAll(row, kv);
|
||||
vm.findList();
|
||||
});
|
||||
},
|
||||
},*/
|
||||
edit: function (row) {
|
||||
row["catalogs"] = row["catalogs"] || [];
|
||||
vm.row = row;
|
||||
this.loadCatalogs();
|
||||
$('#myModal').modal({moveable: true});
|
||||
this.row = row
|
||||
this.loadCatalogs()
|
||||
row['catalogs'] = row['catalogs'] || []
|
||||
$('#myModal').modal({moveable: true})
|
||||
},
|
||||
save: function (row) {
|
||||
dbSave({plat: row}).then(() => {
|
||||
red.showMsg({msg: "操作成功"})
|
||||
red.showOk()
|
||||
$('#myModal').modal('hide')
|
||||
vm.findList()
|
||||
this.findList()
|
||||
})
|
||||
|
||||
/* red.post("/meta/save", {
|
||||
_id: row._id || "db_plat",
|
||||
doc: JSON.stringify(row)
|
||||
}, function (json) {
|
||||
red.showMsg();
|
||||
$('#myModal').modal('hide');
|
||||
vm.findList();
|
||||
}); */
|
||||
},
|
||||
loadCatalogs: function () {
|
||||
vm.catalogs = [];
|
||||
red.post("/_db/catalogs", {
|
||||
url: this.row.url,
|
||||
user: this.row.user,
|
||||
pwd: this.row.pwd
|
||||
}, function (json) {
|
||||
vm.catalogs = json;
|
||||
});
|
||||
//let [cate, url, user, pwd] = this.row
|
||||
let dbAccount = {cate:'', url:'', user:'', pwd:''}
|
||||
for (let key in dbAccount) {
|
||||
dbAccount[key] = this.row[key]
|
||||
}
|
||||
catalogList({dbAccount}).then(res => {
|
||||
this.catalogs = res;
|
||||
})
|
||||
},
|
||||
dbPulse: function (row) {
|
||||
/*row["check"] = true;
|
||||
@@ -216,6 +232,9 @@
|
||||
row["pulse"] = json.body;
|
||||
row["check"] = false;
|
||||
});*/
|
||||
},
|
||||
showInfo() {
|
||||
$('#f-info').modal({moveable: true})
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
|
||||
@@ -139,6 +139,8 @@
|
||||
</row>
|
||||
<script src="http://www.1216.top/res/layui/layui.js"></script>
|
||||
<script>
|
||||
let {qtaskList} = qtask
|
||||
|
||||
var vm = new Vue({
|
||||
el: ".qtask-list",
|
||||
data: {
|
||||
@@ -163,7 +165,8 @@
|
||||
},
|
||||
methods: {
|
||||
loadList: function () {
|
||||
var para = {
|
||||
qtaskList().then(res => this.list = res)
|
||||
/*var para = {
|
||||
pn:1,
|
||||
ps:120,
|
||||
doc:"qtask",
|
||||
@@ -172,7 +175,8 @@
|
||||
};
|
||||
red.getJSON("/meta/find", para, function (json) {
|
||||
vm.list = json;
|
||||
});
|
||||
});*/
|
||||
|
||||
},
|
||||
openDia: function (row) {
|
||||
vm.row = row;
|
||||
|
||||
@@ -142,4 +142,16 @@ th{
|
||||
|
||||
.table td, .table th{
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/* 页面信息按钮样式 */
|
||||
#main .info {
|
||||
float: right;
|
||||
padding-top: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 设置对话框内容居中显示 */
|
||||
.modal-body {
|
||||
text-align: center;
|
||||
}
|
||||
BIN
root/res/img/db_plat.png
Normal file
BIN
root/res/img/db_plat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
root/res/img/meta_flow.png
Normal file
BIN
root/res/img/meta_flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
root/res/img/meta_link.png
Normal file
BIN
root/res/img/meta_link.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
BIN
root/res/img/meta_service.png
Normal file
BIN
root/res/img/meta_service.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
root/res/img/table_import_flow.png
Normal file
BIN
root/res/img/table_import_flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
root/res/img/user_link.png
Normal file
BIN
root/res/img/user_link.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -12,6 +12,9 @@ var red = {
|
||||
,placement: option.placement
|
||||
}).show();
|
||||
},
|
||||
showOk(msg = '操作成功') {
|
||||
red.showMsg({msg})
|
||||
},
|
||||
getData: function(key, defaultValue) {
|
||||
var v = localStorage.getItem(key) || defaultValue || "";
|
||||
if (typeof(v) == "string" && v.startsWith("{") && v.endsWith("}")) {
|
||||
@@ -42,7 +45,7 @@ var red = {
|
||||
}
|
||||
return plat["token"];
|
||||
},
|
||||
getJSON: function (url, params, callback) {
|
||||
getJSON: function (url, params = {}, callback) {
|
||||
params["platToken"] = red.getPlatToken()
|
||||
axios.get(url, {params}).then(res => {
|
||||
let data = res.data || {}
|
||||
@@ -57,8 +60,10 @@ var red = {
|
||||
callback(data)
|
||||
})
|
||||
},
|
||||
getX(url, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getX(url, params = {}) {
|
||||
if (!params['platToken'])
|
||||
params['platToken'] = red.getPlatToken()
|
||||
return new Promise(resolve => {
|
||||
axios.get(url, params).then(res => {
|
||||
let data = res.data || {}
|
||||
red.loginCheck(data)
|
||||
@@ -71,11 +76,15 @@ var red = {
|
||||
}
|
||||
|
||||
resolve(data)
|
||||
}).catch(res => {
|
||||
console.log(res)
|
||||
red.showMsg({type:"error", msg:'操作失败!'})
|
||||
})
|
||||
})
|
||||
},
|
||||
postX(url, params) {
|
||||
params["platToken"] = red.getPlatToken()
|
||||
postX(url, params = {}) {
|
||||
if (!params['platToken'])
|
||||
params['platToken'] = red.getPlatToken()
|
||||
return new Promise(resolve => {
|
||||
axios({
|
||||
url,
|
||||
@@ -91,13 +100,12 @@ var red = {
|
||||
else if (data.code == 0) {
|
||||
data = data.body
|
||||
}
|
||||
red.showMsg()
|
||||
resolve(data)
|
||||
});
|
||||
})
|
||||
},
|
||||
post: function(url, params, callback) {
|
||||
params["platToken"] = red.getPlatToken()
|
||||
post: function(url, params = {}, callback) {
|
||||
params['platToken'] = red.getPlatToken()
|
||||
axios.post(url, params).then(res => {
|
||||
let data = red.loginCheck(res.data)
|
||||
if (data && data.code == -1) {
|
||||
@@ -173,9 +181,9 @@ var red = {
|
||||
},
|
||||
loginCheck: function (json) {
|
||||
if (json && (json['code'] == -2 || json['referid'])) {
|
||||
red.showMsg({type:'error', placement: 'center', msg: '登陆过期,请前往登陆'});
|
||||
//red.showMsg({type:'error', placement: 'center', msg: '登陆过期,请前往登陆'});
|
||||
setTimeout(function () {
|
||||
location.href = "/user/login.html";
|
||||
//location.href = "/user/login.html";
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
|
||||
0
root/res/libs/axios.min.map
Normal file
0
root/res/libs/axios.min.map
Normal file
@@ -1,5 +1,5 @@
|
||||
<div id="about">
|
||||
{{about}}
|
||||
<h3>解放生产力,告别重复、累赘;流水线式的创造基础软件;集中火力构筑更扎实的城墙;</h3>
|
||||
</div>
|
||||
<script>
|
||||
var vm = new Vue({
|
||||
|
||||
12
root/single/metaFlow.html
Normal file
12
root/single/metaFlow.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<div id="meta-flow">
|
||||
<h3>MetaKit使用流程</h3>
|
||||
<img src="../res/img/meta_flow.png">
|
||||
</div>
|
||||
<script>
|
||||
var vm = new Vue({
|
||||
el: "#meta-flow",
|
||||
data: {
|
||||
about: "AbOUT",
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -120,8 +120,30 @@
|
||||
|
||||
},
|
||||
methods: {
|
||||
loginCheck: function ({username, pwd}) {
|
||||
login({username, pwd}, function (json) {
|
||||
login({username, pwd}) {
|
||||
login({username, pwd}).then(res => {
|
||||
console.log(res)
|
||||
platList().then(res => {
|
||||
let rows = res.rows
|
||||
console.log(rows)
|
||||
red.showMsg({msg:"请选择业务平台"})
|
||||
|
||||
this.sysPlats = rows;
|
||||
if (!this.sysPlat) {
|
||||
this.sysPlat = rows[0];
|
||||
}
|
||||
|
||||
red.setData("sysPlats", rows);
|
||||
red.setData('userName', username)
|
||||
setTimeout(function () {
|
||||
vm.choose = true;
|
||||
}, 500);
|
||||
})
|
||||
})
|
||||
},
|
||||
/*loginCheck: function ({username, pwd}) {
|
||||
|
||||
/!*login({username, pwd}, function (json) {
|
||||
if (json.code == 0) {
|
||||
platList().then(res => {
|
||||
let rows = res.rows
|
||||
@@ -139,12 +161,12 @@
|
||||
} else {
|
||||
red.showMsg({msg: json.message})
|
||||
}
|
||||
});
|
||||
},
|
||||
});*!/
|
||||
},*/
|
||||
/*loadPlats: function () {
|
||||
var para = {
|
||||
doc:"sys_plat",
|
||||
shows: JSON.stringify(["_id", "_key", "name", "token","remark", "status"])
|
||||
shows: JSON.stringify(["_id", "_key", "field", "token","remark", "status"])
|
||||
};
|
||||
red.getJSON("/meta/plat_list", {}, function (json) {
|
||||
vm.sysPlats = json;
|
||||
@@ -166,7 +188,7 @@
|
||||
$('body').bind('keyup', function(event) {
|
||||
if (event.keyCode == "13") {
|
||||
if (!vm.choose) {
|
||||
vm.loginCheck(vm.row);
|
||||
vm.login(vm.row);
|
||||
} else {
|
||||
vm.goIndex();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package net.tccn.meta;
|
||||
package net.tccn.base;
|
||||
|
||||
import net.tccn.base.Kv;
|
||||
import net.tccn.base.UtilityExt;
|
||||
import net.tccn.base.arango.Doc;
|
||||
import net.tccn.dbq.Field;
|
||||
import net.tccn.dbq.fbean.FilterType;
|
||||
import net.tccn.dbq.jdbc.api.DbAccount;
|
||||
import net.tccn.dbq.jdbc.api.DbKit;
|
||||
import net.tccn.meta.MetaLink;
|
||||
import net.tccn.meta.MetaService;
|
||||
import net.tccn.meta.MetaTable;
|
||||
import net.tccn.plat.DbPlat;
|
||||
import net.tccn.plat.SysPlat;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -23,6 +28,7 @@ public class MetaKit {
|
||||
private static List<MetaService> metaServices;
|
||||
|
||||
private static List<DbAccount> dbPlats;
|
||||
private static List<SysPlat> sysPlats;
|
||||
|
||||
static {
|
||||
metaTables = MetaTable.dao.find();
|
||||
@@ -30,6 +36,17 @@ public class MetaKit {
|
||||
metaServices = MetaService.dao.find();
|
||||
|
||||
dbPlats = DbAccount.dao.find();
|
||||
sysPlats = SysPlat.dao.find();
|
||||
}
|
||||
|
||||
public static <T extends Doc> void reload(Class<T> clazz) {
|
||||
|
||||
if (MetaTable.class == clazz) metaTables = MetaTable.dao.find();
|
||||
else if (MetaLink.class == clazz) metaLinks = MetaLink.dao.find();
|
||||
else if (MetaService.class == clazz) metaServices = MetaService.dao.find();
|
||||
else if (DbAccount.class == clazz) dbPlats = DbAccount.dao.find();
|
||||
else if (DbPlat.class == clazz) dbPlats = DbAccount.dao.find();
|
||||
else if (SysPlat.class == clazz) sysPlats = SysPlat.dao.find();
|
||||
}
|
||||
|
||||
//----- get/set ----
|
||||
@@ -61,6 +78,14 @@ public class MetaKit {
|
||||
MetaKit.dbPlats = dbPlats;
|
||||
}
|
||||
|
||||
public static List<SysPlat> getSysPlats() {
|
||||
return sysPlats;
|
||||
}
|
||||
|
||||
public static void setSysPlats(List<SysPlat> sysPlats) {
|
||||
MetaKit.sysPlats = sysPlats;
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
public static void setMetaServices(List<MetaService> metaServices) {
|
||||
MetaKit.metaServices = metaServices;
|
||||
@@ -433,6 +458,18 @@ public class MetaKit {
|
||||
return tables;
|
||||
}
|
||||
|
||||
public static DbKit getDbKit(String dbPlatId) {
|
||||
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getKey().equals(dbPlatId)).findAny();
|
||||
|
||||
return new DbKit(dbAccount.get());
|
||||
}
|
||||
|
||||
public static DbAccount getDbPlat(String dbPlatId) {
|
||||
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getKey().equals(dbPlatId)).findFirst();
|
||||
|
||||
return dbAccount.get();
|
||||
}
|
||||
|
||||
public String nextAlias(String x) {
|
||||
return next(x, "");
|
||||
}
|
||||
@@ -206,7 +206,7 @@ public class ArangoSource {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Map<String, Integer> order = t.getOrder();
|
||||
if (isEmpty.test(order)) {
|
||||
return buf;
|
||||
return buf.append(" sort d._key desc");
|
||||
}
|
||||
buf.append(" sort ");
|
||||
order.forEach((k, v) -> {
|
||||
|
||||
@@ -25,6 +25,7 @@ public abstract class Doc<T extends Doc> {
|
||||
|
||||
private Set<String> _shows;
|
||||
private Map _order;
|
||||
private List<Map> _filters;//[{col, value, expr}]
|
||||
|
||||
public String getId() {
|
||||
return _id;
|
||||
@@ -194,6 +195,9 @@ public abstract class Doc<T extends Doc> {
|
||||
if (flipper == null) {
|
||||
flipper = new Flipper();
|
||||
}
|
||||
if (t == null) {
|
||||
t = (T) this;
|
||||
}
|
||||
|
||||
List<T> list = find(t, flipper.getOffset(), flipper.getLimit());
|
||||
long count = count(t);
|
||||
@@ -251,7 +255,7 @@ public abstract class Doc<T extends Doc> {
|
||||
return (T) collection.getDocument(String.valueOf(key), this.getClass());
|
||||
}
|
||||
|
||||
//ok
|
||||
// ok todo: 将数据放入回收库
|
||||
public void delete() {
|
||||
collection.deleteDocument(getKey());
|
||||
}
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
package net.tccn.dbq;
|
||||
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.base.PageBean;
|
||||
import net.tccn.dbq.fbean.FBean;
|
||||
import net.tccn.dbq.jdbc.api.DbAccount;
|
||||
import net.tccn.dbq.jdbc.api.DbKit;
|
||||
import net.tccn.dbq.parser.ParseMysql;
|
||||
import net.tccn.dbq.parser.Parser;
|
||||
import net.tccn.meta.MetaKit;
|
||||
import net.tccn.meta.MetaService;
|
||||
import net.tccn.meta.MetaTable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class DbExecutors {
|
||||
private final static Parser PARSER = new ParseMysql();
|
||||
|
||||
public static PageBean findPage(FBean fBean) {
|
||||
|
||||
public static PageBean findPage(FBean fBean) throws ExecutionException, InterruptedException {
|
||||
//sql解析
|
||||
String[] sqls = PARSER.parse(fBean);
|
||||
|
||||
//当前的业务 => 获取主表 信息 => 数据源信息 => 数据源对象 => 创建数据工具对象 => 查询数据
|
||||
@@ -25,15 +26,13 @@ public class DbExecutors {
|
||||
|
||||
MetaTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTable());
|
||||
|
||||
DbAccount dbAccount = DbAccount.dao.findByKey(mainTable.getDbPlatId());
|
||||
|
||||
DbKit dbKit = new DbKit(dbAccount);
|
||||
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbPlatId());
|
||||
System.out.println("countSql: " + sqls[0]);
|
||||
System.out.println("findSql: " + sqls[1]);
|
||||
|
||||
Integer count = dbKit.queryColumn(sqls[0], int.class);
|
||||
List<Map> list = dbKit.findList(sqls[1], Map.class);
|
||||
CompletableFuture<Integer> countFuture = CompletableFuture.supplyAsync(() -> dbKit.queryColumn(sqls[0], int.class));
|
||||
CompletableFuture<List<Map>> listFuture = CompletableFuture.supplyAsync(() -> dbKit.findList(sqls[1], Map.class));
|
||||
|
||||
return PageBean.by(list, count);
|
||||
return PageBean.by(listFuture.get(), countFuture.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,14 @@ public class DbKit implements DbSource{
|
||||
public <T> T queryColumn(String sql, Class<T> type) {
|
||||
return dbSource.queryColumn(sql, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTable(String sql) {
|
||||
dbSource.createTable(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropTable(String tableName) {
|
||||
dbSource.dropTable(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,4 +32,7 @@ public interface DbSource {
|
||||
default Date queryDate(String sql) {
|
||||
return queryColumn(sql, Date.class);
|
||||
}
|
||||
|
||||
void createTable(String sql);
|
||||
void dropTable(String tableName);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
|
||||
/**
|
||||
* Created by liangxianyou at 2019/3/12 14:20.
|
||||
@@ -17,7 +17,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class DbSourceMysql implements DbSource {
|
||||
|
||||
private static ConcurrentHashMap<String, AtomicReferenceArray<Connection>> conns = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, LinkedBlockingQueue<Connection>> conns = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, AtomicInteger> counter = new ConcurrentHashMap<>();
|
||||
|
||||
private String accountKey;
|
||||
@@ -111,57 +111,66 @@ public class DbSourceMysql implements DbSource {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTable(String sql) {
|
||||
new RuntimeException("DbSourceMysql.createTable NOT SUPPORT right now" ); // todo:
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropTable(String tableName) {
|
||||
new RuntimeException("[DbSourceMysql.dropTable] NOT SUPPORT right now" ); // todo:
|
||||
}
|
||||
|
||||
private Connection connection() {
|
||||
return connection(0);
|
||||
}
|
||||
private Connection connection(int n) {
|
||||
AtomicReferenceArray<Connection> arr = conns.getOrDefault(accountKey, new AtomicReferenceArray<>(15));
|
||||
Connection connection = null;
|
||||
AtomicInteger num = counter.getOrDefault(accountKey, new AtomicInteger(0));
|
||||
for (int i = 0; num.get() > 0 && i < arr.length() && connection == null; i++) {
|
||||
try {
|
||||
connection = arr.getAndUpdate(i, null);
|
||||
} catch (Exception e) {
|
||||
System.out.println("getAndUpdate exception");
|
||||
}
|
||||
}
|
||||
if (connection == null) {
|
||||
try {
|
||||
if (num.get() < 15) {
|
||||
connection = DriverManager.getConnection(dbAccount.getUrl(), dbAccount.getUser(), dbAccount.getPwd());
|
||||
num.getAndIncrement();
|
||||
} else {
|
||||
//连接被全部使用中,等待1s后再次获取连接,直到得到连接 !!!
|
||||
Thread.sleep(1000);
|
||||
if (++n > 3)
|
||||
connection(n);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("获取数据库连接失败");
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
LinkedBlockingQueue<Connection> queue = conns.getOrDefault(accountKey, new LinkedBlockingQueue<>(15));
|
||||
|
||||
return connection;
|
||||
Connection conn = null;
|
||||
AtomicInteger num = counter.getOrDefault(accountKey, new AtomicInteger(0));
|
||||
try {
|
||||
if (queue.size() == 0 && num.get() < 15) {
|
||||
conn = DriverManager.getConnection(dbAccount.getUrl(), dbAccount.getUser(), dbAccount.getPwd());
|
||||
int x = num.incrementAndGet();
|
||||
counter.put(accountKey, num);
|
||||
System.out.println("创建新的连接:" + x);
|
||||
} else {
|
||||
conn = queue.take();
|
||||
if (conn != null) {
|
||||
System.out.println("获取已有连接" + conn);
|
||||
}
|
||||
}
|
||||
} catch (SQLException | InterruptedException e) {
|
||||
if (e instanceof InterruptedException) {
|
||||
try {
|
||||
conn = DriverManager.getConnection(dbAccount.getUrl(), dbAccount.getUser(), dbAccount.getPwd());
|
||||
num.getAndIncrement();
|
||||
if (conn != null) {
|
||||
System.out.println("获取连接异常,并重新创建成功");
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
new IllegalArgumentException("创建连接失败", e);
|
||||
}
|
||||
num.getAndIncrement();
|
||||
counter.put(accountKey, num);
|
||||
} else {
|
||||
new IllegalArgumentException("获取连接失败", e);
|
||||
}
|
||||
}
|
||||
conns.put(accountKey, queue);
|
||||
return conn;
|
||||
}
|
||||
private void release(Connection connection) {
|
||||
AtomicReferenceArray<Connection> arr = conns.getOrDefault(accountKey, new AtomicReferenceArray<>(15));
|
||||
|
||||
int i = 0;
|
||||
boolean bool = false;
|
||||
while (i < arr.length() && !bool){
|
||||
bool = arr.compareAndSet(i++, null, connection);
|
||||
}
|
||||
|
||||
//如果没成功释放,关系连接
|
||||
if (!bool && connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
LinkedBlockingQueue<Connection> queue = conns.getOrDefault(accountKey, new LinkedBlockingQueue<>(15));
|
||||
try {
|
||||
if (connection != null) {
|
||||
queue.put(connection);
|
||||
conns.put(accountKey, queue);
|
||||
System.out.println("还回连接:" + connection);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package net.tccn.dbq.parser;
|
||||
|
||||
import net.tccn.base.Kv;
|
||||
import net.tccn.dbq.fbean.*;
|
||||
import net.tccn.meta.MetaKit;
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.meta.MetaLink;
|
||||
import net.tccn.meta.MetaService;
|
||||
import net.tccn.meta.MetaTable;
|
||||
|
||||
@@ -5,7 +5,7 @@ package net.tccn.dbq.table;
|
||||
* @author: liangxianyou at 2018/10/8 10:59.
|
||||
*/
|
||||
public class Column {
|
||||
private String name; //列名称
|
||||
private String field; //列名称
|
||||
private String type; //列类型
|
||||
private boolean notNull; //不为null
|
||||
private String comment; //列说明
|
||||
@@ -14,18 +14,18 @@ public class Column {
|
||||
}
|
||||
|
||||
public Column(String name, String type, boolean notNull, String comment) {
|
||||
this.name = name;
|
||||
this.field = name;
|
||||
this.type = type;
|
||||
this.notNull = notNull;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public void setField(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
@@ -52,4 +52,9 @@ public class Column {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
//-----------------------
|
||||
public void setNull(String notNull) {
|
||||
this.notNull = "NO".equalsIgnoreCase(notNull) ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class Table {
|
||||
|
||||
buf.append("CREATE TABLE " + name + "(");
|
||||
columns.forEach(x -> {
|
||||
buf.append("\n " + x.getName() + " " + x.getType() + ",");
|
||||
buf.append("\n " + x.getField() + " " + x.getType() + ",");
|
||||
});
|
||||
|
||||
buf.deleteCharAt(buf.length() - 1);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.tccn.meta;
|
||||
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.qtask.Task;
|
||||
|
||||
/**
|
||||
* Created by liangxianyou at 2019/3/7 16:13.
|
||||
|
||||
@@ -20,6 +20,7 @@ public class MetaTable extends Doc<MetaTable> implements Serializable {
|
||||
private String alias; //表别名:全库唯一,程序自动生成
|
||||
private String comment;
|
||||
private List<Field> items;
|
||||
private String sysPlatId; //所属系统平台
|
||||
private String dbPlatId; //所属数据平台
|
||||
private String catalog; //所在database
|
||||
|
||||
@@ -57,6 +58,14 @@ public class MetaTable extends Doc<MetaTable> implements Serializable {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public String getSysPlatId() {
|
||||
return sysPlatId;
|
||||
}
|
||||
|
||||
public void setSysPlatId(String sysPlatId) {
|
||||
this.sysPlatId = sysPlatId;
|
||||
}
|
||||
|
||||
public String getDbPlatId() {
|
||||
return dbPlatId;
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package net.tccn.meta;
|
||||
|
||||
/**
|
||||
* Created by liangxianyou at 2019/3/7 16:24.
|
||||
*/
|
||||
public class Task {
|
||||
}
|
||||
91
src/main/java/net/tccn/meta/_DbService.java
Normal file
91
src/main/java/net/tccn/meta/_DbService.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package net.tccn.meta;
|
||||
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.dbq.jdbc.api.DbAccount;
|
||||
import net.tccn.dbq.jdbc.api.DbKit;
|
||||
import net.tccn.dbq.table.Column;
|
||||
import net.tccn.dbq.table.Table;
|
||||
import net.tccn.service.BaseService;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
import org.redkale.net.http.RestService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@RestService(automapping = true, comment = "数据库操作类")
|
||||
public class _DbService extends BaseService {
|
||||
|
||||
@RestMapping(name = "catalog_list", comment = "获取数据源的database")
|
||||
public JBean catalogList(DbAccount dbAccount, String dbPlatId) {
|
||||
JBean jBean = new JBean();
|
||||
DbKit dbKit = null;
|
||||
if (dbAccount != null) {
|
||||
dbKit = new DbKit(dbAccount);
|
||||
} else {
|
||||
dbKit = MetaKit.getDbKit(dbPlatId);
|
||||
}
|
||||
|
||||
List<Map> list = dbKit.findList("SHOW DATABASES;", Map.class);
|
||||
|
||||
Stream<String> database = list.stream().map(x -> String.valueOf(x.get("Database")));
|
||||
|
||||
return jBean.setBody(database.toArray());
|
||||
}
|
||||
|
||||
@RestMapping(name = "table_list", comment = "数据库表列表")
|
||||
public JBean tableList(DbAccount dbAccount, String dbPlatId, String[] catalogs) {
|
||||
JBean jBean = new JBean();
|
||||
DbKit dbKit = MetaKit.getDbKit(dbPlatId);
|
||||
|
||||
StringBuffer sqlBuf = new StringBuffer("SELECT TABLE_NAME 'name',TABLE_COMMENT 'comment',table_schema 'catalog' FROM INFORMATION_SCHEMA.TABLES");
|
||||
if (catalogs != null && catalogs.length > 0) {
|
||||
sqlBuf.append("WHERE TABLE_SCHEMA in (");
|
||||
for (String catalog : catalogs) {
|
||||
sqlBuf.append("'").append(catalog).append("',");
|
||||
}
|
||||
sqlBuf.deleteCharAt(sqlBuf.length() - 1);
|
||||
sqlBuf.append(")");
|
||||
}
|
||||
List<Table> list = dbKit.findList(sqlBuf.toString(), Table.class);
|
||||
|
||||
return jBean.setBody(list);
|
||||
}
|
||||
|
||||
@RestMapping(name = "table_info", comment = "数据库表详情")
|
||||
public JBean tableInfo(DbAccount dbAccount,
|
||||
String dbPlatId, String catalog, String tableName) {
|
||||
JBean jBean = new JBean();
|
||||
DbKit dbKit = MetaKit.getDbKit(dbPlatId);
|
||||
|
||||
String sql = String.format("SELECT TABLE_NAME 'name',TABLE_COMMENT 'comment',table_schema 'catalog' FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='%s'", tableName);
|
||||
String columnSql = String.format("SHOW FULL COLUMNS FROM '%s.%s'", catalog, tableName);
|
||||
|
||||
CompletableFuture<Table> tableFuture = CompletableFuture.supplyAsync(() -> dbKit.findfirst(sql, Table.class));
|
||||
CompletableFuture<List<Column>> columnFuture = CompletableFuture.supplyAsync(() -> dbKit.findList(columnSql, Column.class));
|
||||
|
||||
try {
|
||||
Table table = tableFuture.get();
|
||||
table.setColumns(columnFuture.get());
|
||||
jBean.setBody(table);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
jBean.set(-1, "查询表信息失败");
|
||||
new IllegalArgumentException("查询表信息失败", e);
|
||||
}
|
||||
|
||||
return jBean;
|
||||
}
|
||||
|
||||
@RestMapping(name = "table_create", comment = "新建表[mysql]")
|
||||
public JBean tableCreate(String dbPlatId, String catalog, String sql) {
|
||||
JBean jBean = new JBean();
|
||||
|
||||
DbKit dbKit = MetaKit.getDbKit(dbPlatId);
|
||||
dbKit.createTable(sql);
|
||||
|
||||
return jBean;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
package net.tccn.plat;
|
||||
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.base.PageBean;
|
||||
import net.tccn.dbq.jdbc.api.DbAccount;
|
||||
import net.tccn.service.BaseService;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
import org.redkale.net.http.RestService;
|
||||
import org.redkale.source.Flipper;
|
||||
import org.redkale.util.Comment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestService(name = "plat", automapping = true, comment = "业务/数据平台")
|
||||
public class PlatService extends BaseService {
|
||||
|
||||
@@ -15,7 +19,9 @@ public class PlatService extends BaseService {
|
||||
public JBean list(SysPlat plat, Flipper flipper) {
|
||||
JBean jBean = new JBean();
|
||||
|
||||
PageBean<SysPlat> page = SysPlat.dao.findPage(plat, flipper);
|
||||
//PageBean<SysPlat> page = SysPlat.dao.findPage(plat, flipper);
|
||||
List<SysPlat> list = MetaKit.getSysPlats();
|
||||
PageBean page = PageBean.by(list, list.size());
|
||||
|
||||
return jBean.setBody(page);
|
||||
}
|
||||
@@ -42,19 +48,24 @@ public class PlatService extends BaseService {
|
||||
public JBean dbList(DbPlat plat, Flipper flipper) {
|
||||
JBean jBean = new JBean();
|
||||
|
||||
PageBean<DbPlat> page = DbPlat.dao.findPage(plat, flipper);
|
||||
//PageBean<DbPlat> page = DbPlat.dao.findPage(plat, flipper);
|
||||
|
||||
List<DbAccount> list = MetaKit.getDbPlats();
|
||||
PageBean page = PageBean.by(list, list.size());
|
||||
|
||||
return jBean.setBody(page);
|
||||
}
|
||||
|
||||
@RestMapping(name = "db_save", comment = "数据源信息保存")
|
||||
public JBean dbSave(DbPlat plat) {
|
||||
//DbAccount dbPlat = MetaKit.getDbPlat(plat.getKey());
|
||||
|
||||
if (plat.getKey() == null) {
|
||||
plat.save();
|
||||
} else {
|
||||
plat.update();
|
||||
}
|
||||
MetaKit.reload(DbPlat.class);
|
||||
|
||||
return new JBean();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package net.tccn.qtask;
|
||||
|
||||
|
||||
import net.tccn.base.Kv;
|
||||
import net.tccn.base.arango.Doc;
|
||||
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* cate:mysql
|
||||
@@ -22,7 +25,9 @@ import net.tccn.base.Kv;
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Task {
|
||||
@Table(name = "qtask", catalog = "db_dev")
|
||||
public class Task extends Doc<Task> {
|
||||
public static Task dao = dao(Task.class);
|
||||
|
||||
public String cate;//MYSQL,ES,METHOD,HTTP
|
||||
public String queryId;
|
||||
|
||||
@@ -23,6 +23,9 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class BaseService implements Service {
|
||||
|
||||
@Resource(name = "SERVER_ROOT")
|
||||
protected File webroot;
|
||||
|
||||
public static Gson gson = new Gson();
|
||||
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import net.tccn.base.Kv;
|
||||
import net.tccn.dbq.Field;
|
||||
import net.tccn.dbq.jdbc.api.DbAccount;
|
||||
import net.tccn.plat.SysPlat;
|
||||
import net.tccn.meta.MetaKit;
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.meta.MetaService;
|
||||
import net.tccn.meta.MetaTable;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
|
||||
243
src/main/java/net/tccn/service/_FileService.java
Normal file
243
src/main/java/net/tccn/service/_FileService.java
Normal file
@@ -0,0 +1,243 @@
|
||||
package net.tccn.service;
|
||||
|
||||
import com.lxyer.excel.poi.ExcelKit;
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.base.Kv;
|
||||
import net.tccn.dbq.Field;
|
||||
import net.tccn.meta.MetaTable;
|
||||
import net.tccn.plat.SysPlat;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
import org.redkale.net.http.RestParam;
|
||||
import org.redkale.net.http.RestService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* @author: liangxianyou at 2018/10/24 10:57.
|
||||
*/
|
||||
@RestService(automapping = true, comment = "文件服务")
|
||||
public class _FileService extends BaseService {
|
||||
|
||||
private final static String[] FIELDS = {"field", "cate", "must", "remark1", "remark2", "tag", "selects", "column", "filter", "ck", "edit"};
|
||||
|
||||
@Resource
|
||||
private QtaskService qtaskService;
|
||||
|
||||
|
||||
@RestMapping(name = "sheets", comment = "得到所有的sheetName")
|
||||
public List<String> sheets(String filePath) {
|
||||
List<String> sheets = new ArrayList<>();
|
||||
try {
|
||||
|
||||
File file = new File(webroot, filePath);
|
||||
if (file.exists()) {
|
||||
sheets = ExcelKit.getSheetNames(file);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return sheets.stream().filter(x -> {
|
||||
return !x.contains("版本记录") && !x.contains("表说明") && !x.contains("表名称");
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@RestMapping(name = "data", comment = "得到文件数据")
|
||||
public JBean data(String filePath, @RestParam(name = "platToken") String token) {
|
||||
JBean jBean = new JBean();
|
||||
SysPlat sysPlat = qtaskService.getSysPlat(token);
|
||||
File file = new File(webroot, filePath);
|
||||
if (file.exists()) {
|
||||
try {
|
||||
Map<String, List<Map>> map = ExcelKit.readExcelAll(file, FIELDS);
|
||||
|
||||
Kv<String, MetaTable> data = Kv.of();
|
||||
map.forEach((k, v) -> {
|
||||
if (v.size() > 2) {
|
||||
data.put(k.replace(" ", ""), toCols(v));
|
||||
}
|
||||
});
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("for d in meta_cols\n" +
|
||||
" filter d.name in [");
|
||||
data.values().forEach(x -> {
|
||||
buf.append("'").append(x.getName()).append("',");
|
||||
});
|
||||
buf.deleteCharAt(buf.length() - 1);
|
||||
buf.append("] and d.sysPlatId=='" + sysPlat.getKey() + "'\n" +
|
||||
" return d.name");
|
||||
|
||||
List<String> hv = MetaTable.dao.find(buf.toString(), String.class);
|
||||
|
||||
Kv res = Kv.of();
|
||||
data.forEach((k, v) -> {
|
||||
Kv kv = Kv.of();
|
||||
res.put(k,
|
||||
kv.set("name", v.getName())
|
||||
.set("hv", hv.contains(v.getName()) ? 1 : 0)
|
||||
.set("comment", v.getComment())
|
||||
);
|
||||
});
|
||||
|
||||
jBean.setBody(res);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return jBean;
|
||||
}
|
||||
|
||||
@RestMapping(name = "sheet_data", comment = "得到sheet数据")
|
||||
public JBean sheetData(String filePath, String sheetName, @RestParam(name = "platToken") String token) {
|
||||
JBean jBean = new JBean();
|
||||
SysPlat sysPlat = qtaskService.getSysPlat(token);
|
||||
File file = new File(webroot, filePath);
|
||||
try {
|
||||
List<Map> list = ExcelKit.readExcel(file, FIELDS, sheetName);
|
||||
MetaTable metaTable = toCols(list);
|
||||
|
||||
jBean.setBody(metaTable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
jBean.set(-1, String.format("读取sheet[%s]失败", sheetName));
|
||||
}
|
||||
|
||||
return jBean;
|
||||
}
|
||||
|
||||
@RestMapping(name = "import_metatable", comment = "导入excel数据到metatable")
|
||||
public JBean importMetaTable(@RestParam(name = "sheetArr", comment = "sheet名") String[] sheetArr,
|
||||
@RestParam(name = "filePath", comment = "文件路径") String filePath,
|
||||
@RestParam(name = "platToken") String token) {
|
||||
JBean jBean = new JBean();
|
||||
SysPlat sysPlat = qtaskService.getSysPlat(token);
|
||||
|
||||
File file = new File(webroot, filePath);
|
||||
String[] fields = {"field", "cate", "must", "remark1", "remark2", "tag", "selects", "column", "filter", "ck", "edit"};
|
||||
try {
|
||||
Map<String, List<Map>> map = ExcelKit.readExcelAll(file, fields);
|
||||
map.forEach((k, v) -> {
|
||||
if (v.size() > 2) {
|
||||
MetaTable table = toCols(v);
|
||||
for (String sn : sheetArr) {
|
||||
if (table.getName().equals(sn)) { //在选中列表中
|
||||
MetaTable metaTable = new MetaTable();
|
||||
metaTable.setSysPlatId(sysPlat.getKey());
|
||||
metaTable.setName(table.getName());
|
||||
|
||||
MetaTable _metaTable = MetaTable.dao.findFirst(metaTable);
|
||||
if (_metaTable == null) {//库里没有数据保存
|
||||
table.setSysPlatId(sysPlat.getKey());
|
||||
table.save();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return jBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装元数据
|
||||
*/
|
||||
private MetaTable toCols(List<Map> list) {
|
||||
|
||||
//Kv col = Kv.of();
|
||||
MetaTable metaTable = new MetaTable();
|
||||
|
||||
list.remove(1);//list[0] head info
|
||||
Map rowHead = list.remove(0);
|
||||
|
||||
String comment = getComment(rowHead);//list[1] comment,
|
||||
String tableName = getTableName(rowHead);
|
||||
//col.set("name", tableName).set("comment", comment);
|
||||
metaTable.setName(tableName);
|
||||
metaTable.setComment(comment);
|
||||
|
||||
//所有字段
|
||||
List<Field> items = new ArrayList<>();
|
||||
|
||||
//展示的字段
|
||||
List<String> shows = new ArrayList<>();
|
||||
|
||||
//编辑的字段
|
||||
List<Map> edits = new ArrayList<>();
|
||||
|
||||
//查询过滤用字段
|
||||
List<Map> filters = new ArrayList<>();
|
||||
|
||||
|
||||
list.forEach(x -> {
|
||||
String colName = x.getOrDefault("field", "") + "";
|
||||
|
||||
Field item = new Field();
|
||||
item.setName(colName);
|
||||
item.setLabel(x.getOrDefault("remark1", "") + "");
|
||||
item.setType(x.getOrDefault("cate", "") + "");
|
||||
item.setInType(x.getOrDefault("tag", "") + "");
|
||||
item.setInExt(x.getOrDefault("selects", "") + "");
|
||||
|
||||
items.add(item);
|
||||
|
||||
if ("1".equals(x.getOrDefault("column", "") + "")) {
|
||||
shows.add(colName);
|
||||
}
|
||||
|
||||
if ("1".equals(x.getOrDefault("edit", "") + "")) {
|
||||
edits.add(Kv.of("col", colName));
|
||||
}
|
||||
|
||||
if (x.get("filter") != null && !"".equals(x.get("filter") + "")) {
|
||||
String filter = x.getOrDefault("filter", "") + "";
|
||||
filter = filter.replace("1", "EQUAL");
|
||||
filter = filter.replace("!1", "NOTEQUAL");
|
||||
filter = filter.replace("like", "LIKE");
|
||||
|
||||
filters.add(Kv.of("name", item).set("filterType", asList(filter.split(","))));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
metaTable.setItems(items);
|
||||
//metaTable.setShows(shows);
|
||||
//metaTable.setEdits(edits);
|
||||
//metaTable.setFilters(filters);
|
||||
return metaTable;
|
||||
}
|
||||
|
||||
private String getTableName(Map rowHead) {
|
||||
String field = rowHead.get("field") + "";
|
||||
|
||||
int s = field.indexOf("(");
|
||||
if (s > 0) {
|
||||
return field.substring(0, s);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
private String getComment(Map rowHead) {
|
||||
String field = rowHead.get("field") + "";
|
||||
|
||||
int s = field.indexOf("(");
|
||||
int e = field.indexOf(")");
|
||||
if (s > 0) {
|
||||
return field.substring(s + 1, e > 0 ? e : field.length());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
22
src/main/java/net/tccn/service/_QtaskService.java
Normal file
22
src/main/java/net/tccn/service/_QtaskService.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package net.tccn.service;
|
||||
|
||||
import net.tccn.base.JBean;
|
||||
import net.tccn.base.PageBean;
|
||||
import net.tccn.qtask.Task;
|
||||
import org.redkale.net.http.RestParam;
|
||||
import org.redkale.net.http.RestService;
|
||||
import org.redkale.source.Flipper;
|
||||
import org.redkale.util.Comment;
|
||||
|
||||
@RestService(automapping = true)
|
||||
public class _QtaskService extends BaseService{
|
||||
|
||||
@Comment("qtask列表")
|
||||
public JBean list(Task task, Flipper flipper, @RestParam(name = "platToken") String token) {
|
||||
PageBean<Task> page = Task.dao.findPage(task, flipper);
|
||||
|
||||
|
||||
return JBean.by(0, "", page);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import net.tccn.dbq.fbean.FBean;
|
||||
import net.tccn.dbq.parser.ParseMysql;
|
||||
import net.tccn.dbq.jdbc.api.DbAccount;
|
||||
import net.tccn.dbq.jdbc.api.DbKit;
|
||||
import net.tccn.meta.MetaKit;
|
||||
import net.tccn.base.MetaKit;
|
||||
import net.tccn.qtask.QRuner;
|
||||
import net.tccn.qtask.Task;
|
||||
import org.junit.Test;
|
||||
@@ -60,8 +60,11 @@ public class RunTest<T> {
|
||||
|
||||
DbKit dbKit = new DbKit(dbAccount);
|
||||
|
||||
//String sql = "select * from basic_concat limit 1";
|
||||
String sql = "show databases;";
|
||||
|
||||
// find list
|
||||
List<Map> list = dbKit.findList("select * from basic_concat limit 1", Map.class);
|
||||
List<Map> list = dbKit.findList(sql, Map.class);
|
||||
System.out.println(list.get(0));
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user