Compare commits

13 Commits
master ... dev

Author SHA1 Message Date
8bdedd7370 优化:1、增加左侧菜单收缩按钮
2、meta 预览默认选中历史查看
     3、数据查询tinyint转short
2024-04-05 20:13:40 +08:00
36a30ba2b3 新增:1、qtask-debug结果渲染为表格
2、mdict 存贮到MySQL, meta 业务预览支持字典渲染验证
     3、其他交互优化
2024-04-05 00:30:11 +08:00
3bbf78f51c 优化:1、meta 业务配置页面,其他界面改善
2、元数据记录到内存缺少id的处理
     3、设置platid为不可修改字段
2024-04-03 11:43:23 +08:00
c5ea3cb944 优化:1、mtable、mlink、mservice、qtask 展示的排序最新展示到前面
2、其他修改
2024-04-03 11:42:09 +08:00
28813e1231 . 2024-04-01 16:06:07 +08:00
9973ad18ca 修改:1、arangodb -> mysql,去除arangodb
2、部分字段逻辑重构
2024-04-01 15:53:48 +08:00
81e1a59e65 . 2024-04-01 01:08:26 +08:00
7bbbd29931 修改:1、qtask.call 服务
2、其他界面样式优化
2024-04-01 01:07:36 +08:00
4dcebf32de 升级:1、增加界面夜间模式
2、qtask 功能交互升级
     3、mysql连接管理增加心跳保活
     4、其他修改
2024-03-31 00:34:26 +08:00
8cc55c2c4b . 2024-03-21 18:39:49 +08:00
59585e6369 . 2024-03-21 18:28:51 +08:00
68e5dda2b8 . 2024-01-16 22:17:23 +08:00
2f9cde6ce4 修改:界面样式 2024-01-15 04:17:03 +08:00
81 changed files with 4652 additions and 1887 deletions

View File

@@ -17,7 +17,7 @@ redkale.server[0].protocol = HTTP
redkale.server[0].port = 80
redkale.server[0].host = 0.0.0.0
redkale.server[0].maxbody = 2m
redkale.server[0].root = root
# --- request ---
redkale.server[0].request.remoteaddr = request.headers.X-Real-IP
@@ -25,6 +25,8 @@ redkale.server[0].request.remoteaddr = request.headers.X-Real-IP
redkale.server[0].rest.autoload = true
redkale.server[0].rest.base = net.tccn.base.BaseServlet
# --- render ---
redkale.server[0].render.value = net.tccn.base.MetaRender
# --- response ---
redkale.server[0].response.addheader[0].name = X-Node
redkale.server[0].response.addheader[0].value = system.property.APP_NODE

View File

@@ -1,24 +1,16 @@
#FileHandler/ConsoleHandler
handlers = java.util.logging.ConsoleHandler
handlers=java.util.logging.ConsoleHandler
############################################################
.level = FINER
java.level = INFO
javax.level = INFO
com.sun.level = INFO
sun.level = INFO
jdk.level = INFO
java.util.logging.FileHandler.level = FINER
.level=FINEST
java.level=INFO
javax.level=INFO
com.sun.level=INFO
sun.level=INFO
jdk.level=INFO
java.util.logging.FileHandler.level=FINEST
#10M
java.util.logging.FileHandler.limit = 10485760
java.util.logging.FileHandler.count = 10000
java.util.logging.FileHandler.encoding = UTF-8
java.util.logging.FileHandler.pattern = ${APP_HOME}/logs-%m/log-%d.log
java.util.logging.FileHandler.unusual = ${APP_HOME}/logs-%m/log-warnerr-%u.log
java.util.logging.FileHandler.append = true
java.util.logging.ConsoleHandler.level = FINER
java.util.logging.FileHandler.limit=10485760
java.util.logging.FileHandler.count=10000
java.util.logging.FileHandler.encoding=UTF-8
java.util.logging.FileHandler.pattern=${APP_HOME}/logs-%m/log-%d.log
java.util.logging.FileHandler.append=true
java.util.logging.ConsoleHandler.level=FINEST

View File

@@ -1,98 +0,0 @@
四月 28, 2019 6:17:11 下午 [Transport-Thread-3] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:17:11 下午 [Transport-Thread-3] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
四月 28, 2019 6:18:34 下午 [Transport-Thread-6] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:18:34 下午 [Transport-Thread-6] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
四月 28, 2019 6:23:34 下午 [Transport-Thread-2] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:24:04 下午 [Transport-Thread-2] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
四月 28, 2019 6:24:44 下午 [Transport-Thread-4] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:24:44 下午 [Transport-Thread-4] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
四月 28, 2019 6:24:44 下午 [Transport-Thread-7] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:24:44 下午 [Transport-Thread-7] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
四月 28, 2019 6:24:47 下午 [Transport-Thread-3] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:24:47 下午 [Transport-Thread-3] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
四月 28, 2019 6:25:08 下午 [Transport-Thread-6] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error (retcode=1073741824, retinfo=Inner exception)
四月 28, 2019 6:25:08 下午 [Transport-Thread-6] org.redkale.net.sncp.SncpClient$1$1 completed
严重: public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String) sncp (params: ["3421432"]) deal error
java.lang.RuntimeException: remote service(public net.tccn.base.JBean net.tccn.service.MetadataService.serviceList(java.lang.String)) deal error (retcode=1073741824, retinfo=Inner exception)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:437)
at org.redkale.net.sncp.SncpClient$1$1.completed(SncpClient.java:396)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

17
pom.xml
View File

@@ -11,6 +11,9 @@
<!--<modules>
&lt;!&ndash;<module>qtask</module>&ndash;&gt;
</modules>-->
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
<repositories>
<repository>
@@ -38,11 +41,11 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>LATEST</version>
<version>8.0.33</version>
</dependency>
<!-- arangodb支持 -->
<dependency>
<!--<dependency>
<groupId>com.arangodb</groupId>
<artifactId>arangodb-java-driver-async</artifactId>
<version>6.0.0</version>
@@ -52,12 +55,12 @@
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependency>-->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>5.1.5</version>
<version>3.3</version>
</dependency>
<!-- poi支持 -->
@@ -80,6 +83,12 @@
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@@ -1,12 +1,12 @@
const db = {
catalogList({dbAccount, dbPlatId}) { // database列表
catalogList({dbAccount, dbid}) { // database列表
console.log(JSON.stringify(dbAccount))
return red.postX('/_db/catalog_list', {dbAccount: escape(JSON.stringify(dbAccount)), dbPlatId})
return red.postX('/_db/catalog_list', {dbAccount: escape(JSON.stringify(dbAccount)), dbid})
},
tableList({dbPlatId, catalog}) { // 数据库表列表
return red.postX('/_db/table_list', {dbPlatId, catalog})
tableList({dbid, catalog}) { // 数据库表列表
return red.postX('/_db/table_list', {dbid, catalog})
},
tableInfo({dbPlatId, catalog, tableName}) {
return red.postX('/_db/table_info', {dbPlatId, catalog, tableName})
tableInfo({dbid, catalog, tableName}) {
return red.postX('/_db/table_info', {dbid, catalog, tableName})
}
}

View File

@@ -19,9 +19,9 @@ const meta = {
getServiceInfo({name}, callback) {
red.getJSON("/meta/service_info",{name}, res => {
let {name, comment, table, edits, imports, shows, exports, filters, details, dels} = red.replacePoint(res)
let {name, comment, tablealias, edits, imports, shows, exports, filters, details, dels} = red.replacePoint(res)
callback({name, comment, table, edits, imports, shows, exports, filters, details, dels});
callback({name, comment, tablealias, edits, imports, shows, exports, filters, details, dels});
});
},
getServiceDetail({name}, callback) {
@@ -97,7 +97,7 @@ const meta = {
//client
exportData({fbean, cate}) {
if (cate == 'excel') {
location.href = "/data/export?fBean=" + JSON.stringify(fbean) + "&platToken=" + red.getPlatToken() + "&cate=csv";
location.href = "/data/export?fBean=" + JSON.stringify(fbean) + "&plattoken=" + red.getPlatToken() + "&cate=excel";
} else if (cate == 'cvs') {
} else if (cate == 'json') {

View File

@@ -2,7 +2,7 @@
const plat = {
platList(params = {}) { // 平台列表
params['platToken'] = 'xx'
params['plattoken'] = 'xx'
return red.getX('/plat/list', params)
},
platSave({plat}) {
@@ -14,8 +14,9 @@ const plat = {
},
dbSave({plat}) {
// todo解决重复点击保存出现的异常
plat["url"] = escape(plat["url"])
return red.postX('/plat/db_save', {plat: JSON.stringify(plat)})
let _plat = JSON.parse(JSON.stringify(plat));
_plat["url"] = encodeURIComponent(_plat["url"])
return red.postX('/plat/db_save', {plat: JSON.stringify(_plat)})
},
}

View File

@@ -1,9 +1,16 @@
const qtask = {
qtaskList() {
return red.postX('_qtask/list', {})
qtaskList({flipper={}}) {
return red.get2('_qtask/list', {flipper})
},
qtaskSave({task}) {
return red.postX('_qtask/save', {task: JSON.stringify(task)})
qtaskSave(task) {
if (task.qtaskid) {
return red.post2('_qtask/update', task)
} else {
return red.post2('_qtask/create', task)
}
},
qtaskDelete(qtaskid) {
return red.post2("_qtask/delete", {qtaskid})
},
qtaskDebug({task}) {
return red.postX('_qtask/debug', {task: JSON.stringify(task)})

View File

@@ -1,19 +1,19 @@
const table = {
_sheets({cate, filePath, dbAccount, dbPlatId, catalog}) {
return red.postX('/_table/sheets',{cate, filePath, dbAccount, dbPlatId, catalog})
_sheets({cate, filePath, dbAccount, dbid, catalog}) {
return red.postX('/_table/sheets',{cate, filePath, dbAccount, dbid, catalog})
},
sheetsExcel({filePath}) {
return table._sheets({cate: "excel", filePath})
},
sheetMySql({dbPlatId, catalog}) {
return table._sheets({cate: "mysql", dbPlatId, catalog})
sheetMySql({dbid, catalog}) {
return table._sheets({cate: "mysql", dbid, catalog})
},
sheetInfo({filePath, sheetName}) {
return red.postX('/_table/sheet_info', {cate: 'excel', filePath, sheetName})
},
saveTable({dbPlatId, catalog, tableArr}) { //
return red.postX('/_table/table_save', {cate: 'mysql', dbPlatId, catalog, tableArr: JSON.stringify(tableArr)})
saveTable({dbid, catalog, tableArr}) { //
return red.postX('/_table/table_save', {cate: 'mysql', dbid, catalog, tableArr: JSON.stringify(tableArr)})
},
saveSheet({filePath, sheetNames}) {
return red.postX('/_table/table_save', {cate: 'excel', filePath, sheetNames: JSON.stringify(sheetNames)})

View File

@@ -1,7 +1,7 @@
//import red from '../res/js/red'
const login = ({username, pwd}) => {
return red.postX("/user/login", {username, pwd, platToken: 'xx'})
return red.postX("/user/login", {username, pwd, plattoken: ''})
}
const logout = () => {

View File

@@ -4,7 +4,7 @@
</div>
<div class="col-md-12" style="padding-top: 10px;overflow:auto;">
<table class="table table-bordered table-hover" style="width: 100%">
<table class="table table-bordered table-hover">
<!--<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -89,7 +89,7 @@
<div class="form-group">
<label for="para" class="col-sm-2 required">数据平台</label>
<div class="col-md-6">
<select v-model="row.dbPlatId" class="form-control">
<select v-model="row.dbid" class="form-control">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
</select>

View File

@@ -22,7 +22,7 @@
</div>
</div>
<div class="col-md-12" style="padding-top: 10px;overflow:auto;">
<table class="table table-bordered table-hover" style="width: 100%">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -88,7 +88,7 @@
<div class="form-group">
<label for="para" class="col-sm-2 required">数据平台</label>
<div class="col-md-6">
<select v-model="row.dbPlatId" class="form-control">
<select v-model="row.dbid" class="form-control">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
</select>

View File

@@ -5,15 +5,18 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MetaKit</title>
<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/zui-theme.css">-->
<link rel="stylesheet" href="/res/css/zui-theme-x.css">
<link rel="stylesheet" href="/res/css/red-kit.css">
<link rel="stylesheet" href="/res/ztree/zTreeStyle.css">
</head>
<body id="home">
<div class="container-fluid">
<row>
<div class="col-md-12 col-xs-12" id="top">
<div class="logo">
<h1>Meta-Kit</h1>
<!--<h1>Meta-Kit</h1>-->
<h1>{{sysPlat.platname}}</h1>
</div>
<ul class="nav nav-tabs">
<!--item in pages-->
@@ -22,48 +25,71 @@
</li>
<li class="pull-right" title="刷新服务端缓存数据">
<a @click="refresh()" href="javascript:;" style="padding: 6px 15px;border: 0;background-color: #404a53;color: #fff;">
<a @click="refresh()" href="javascript:;" class="btn btn-default" style="padding: 6px 15px;border: 0;background-color: #404a53!important;color: #fff;">
<i class="icon icon-repeat"></i>
</a>
</li>
<li class="pull-right">
<a @click="logout()" href="javascript:;" style="padding: 6px 15px;border: 0;background-color: #404a53;color: #fff;">
<a @click="logout()" href="javascript:;" class="btn btn-default" style="padding: 6px 15px;border: 0;background-color: #404a53!important;color: #fff;">
<i class="icon icon-user"></i> 退出
</a>
</li>
<li class="pull-right">
<select v-model="sysPlat" class="form-control" style="border: 0;background-color: #404a53;color: #fff;">
<option v-for="item in sysPlats" :value="item" v-text="item.name"></option>
<select v-model="sysPlat" class="form-control plat-switch">
<option v-for="item in sysPlats" :value="item" v-text="item.platname"></option>
</select>
</li>
</ul>
</div>
<div id="mainDiv">
<div class="col-md-1 col-xs-1" id="left">
<div id="mainDiv" :class="{leftMini:leftMini}">
<div :class="['col-md-1 col-xs-1']" id="left">
<nav class="menu" data-ride="menu">
<ul class="nav nav-primary">
<li class="active show nav-parent" style="width: 100%;">
<!--<a href="javascript:;"><i class="icon icon-tasks"></i> <span v-text="pageId"></span></a>-->
<ul class="nav">
<ul class="nav" v-if="!leftMini">
<!-- item in menus -->
<li v-for="item in menus" @click="loadPage(item)" :class="{active:page.url==item.url}">
<a href="javascript:;"><i :class="['icon', item.icon ? item.icon : 'icon-circle-blank']"></i> <span v-text="item.name"></span></a>
</li>
</ul>
<ul class="nav" v-if="leftMini">
<!-- item in menus -->
<li v-for="item in menus" @click="loadPage(item)" :class="{active:page.url==item.url}"
data-toggle="tooltip"
:title="item.name">
<a href="javascript:;"><i
:class="['icon', item.icon ? item.icon : 'icon-circle-blank']"></i>
<!--<span v-text="item.name"></span>-->
</a>
</li>
</ul>
</li>
</ul>
<!--<div class="user">
<a style="cursor: pointer">绝尘</a>
</div>-->
<div class="footer" @click="leftMiniSwitch()">
<!--<i :class="['icon', leftMini? 'icon-caret-right':'icon-caret-left']"></i>-->
{{leftMini ? 'MK' : 'Meta-Kit'}}
</div>
</nav>
</div>
<div class="col-md-11 col-xs-11">
<!-- 固定漂浮在left 用来收缩打开left -->
<div id="leftMiniBtn" @click="leftMiniSwitch()" :title="leftMini? '展开左侧菜单': '收起左侧菜单'" data-toggle="tooltip">
<i :class="['icon', leftMini? 'icon-caret-right':'icon-caret-left']" style="top: 50%"> </i>
</div>
<!--<div style="height: 40px;background-color: #fff;"></div>-->
<!-- load main body to here -->
<div id="main"></div>
<div class="footer">
Meta-Kit Developer v0.2
<div class="main-footer">
Meta-Kit Dev-v0.2.1
</div>
</div>
</div>
@@ -85,6 +111,7 @@
<script src="/api/tmp.js"></script>
<script src="/res/zui/lib/sortable/zui.sortable.js"></script>
<script src="/res/zui/lib/uploader/zui.uploader.min.js"></script>
<script src="/res/ztree/jquery.ztree.all.min.js"></script>
<script type="module">
import { logout } from './api/user.js'
let { refresh } = meta
@@ -106,8 +133,8 @@
{url:"/metadata/metaLink.html", name:"实体关系", icon:"icon-branch"},
{url:"/metadata/metaService.html", name:"业务管理", icon: "icon-sliders"},
{url:"/metadata/dataList.html", name:"业务预览", icon:"icon-window-alt"},
/*{url: "/oth/ddlCompare.html", name: "DDL-Compare", icon: "icon-table"},*/
/*{url:"/metadata/dict.html", name:"字典管理", icon:"icon-usecase"},*/
{url:"/content/create.html", name:"内容管理", icon:"icon-edit-sign"},
/*{url:"/content/list.html", name:"游戏查询", icon:"icon-usecase"},
{url:"/content/funs.html", name:"平台功能", icon:"icon-usecase"},*/
]
@@ -115,24 +142,13 @@
{
name: "QTask", url: "/qtask", nodes: [
{url:"/qtask/list.html", name:"QTask", icon:"icon-cube-alt"},
{url:"/qtask/debug.html", name:"QTask-Debug", icon:"icon-bug"},
/*{url:"/qtask/debug.html", name:"QTask-Debug", icon:"icon-bug"},*/
]
},
{
name: "其他服务", url: "/plat/db.html", nodes: [
{url:"/oth/index.html", name:"业务平台管理", icon: "icon-database"},
{url:"/oth/file.html", name:"文件服务", icon: "icon-database"},
]
},
{
name: "业务平台", url: "/qtask", nodes: [
{url:"/plat/index.html", name:"业务平台", icon:"icon-server"},
{url:"/plat/dev.html", name:"dev", icon:"icon-beaker"},
]
},
{
name: "数据平台", url: "/plat/db.html", nodes: [
{url:"/plat/db.html", name:"数据中心", icon: "icon-database"},
name: "平台管理", url: "/plat/db.html", nodes: [
{url:"/plat/db.html", name:"数据源", icon: "icon-database"},
{url:"/plat/index.html", name:"应用平台", icon:"icon-server"},
]
},
{name: "关于", url: "/single", nodes: [
@@ -142,6 +158,14 @@
{url:"/single/metaFlow.html", name:"MetaKit使用", icon:"icon-server"},
]
},
/*{
name: "其他服务", url: "/plat/db.html", nodes: [
{url:"/oth/index.html", name:"业务平台管理", icon: "icon-database"},
{url:"/oth/file.html", name:"文件服务", icon: "icon-database"},
{url:"/content/create.html", name:"内容管理", icon:"icon-edit-sign"},
{url:"/plat/dev.html", name:"dev", icon:"icon-beaker"},
]
},*/
{name: "Zhub", url: "/zhub", nodes: [
{url:"/zhub/monitor.html", name:"Monitor", icon:"icon-server"},
{url:"/zhub/topic.html", name:"Topics", icon:"icon-server"},
@@ -149,18 +173,18 @@
{url:"/zhub/timer.html", name:"Timer", icon:"icon-server"},
]
},
{name: "微信公众号", url: "/weixin", nodes: [
/*{name: "微信公众号", url: "/weixin", nodes: [
{url:"/weixin/wxapp.html", name:"公众号管理", icon:"icon-server"},
{url:"/weixin/user.html", name:"用户管理", icon:"icon-server"},
{url:"/weixin/templateMessage.html", name:"模板消息", icon:"icon-server"},
{url:"/weixin/timer.html", name:"Timer", icon:"icon-server"},
]
},
}*/
],
menus: {},
page: {},
pageId: ''
pageId: '',
leftMini: red.getData('leftMini') === 'Min',
},
watch: {
page: function () {
@@ -172,6 +196,12 @@
sysPlat: function (v) {
red.setData("sysPlat", v);
this.loadPage();
},
leftMini: function () {
this.tooltipShow()
},
menus: function () {
this.tooltipShow()
}
},
methods: {
@@ -192,6 +222,9 @@
loadMain(item) {
this.menus = item.nodes || [item];
this.pageId = item.name;
// 加载新模块下的第一个
this.loadPage(this.menus[0]);
},
refresh() {
refresh().then(res => {
@@ -221,8 +254,23 @@
data[k] = vs
}
red.setData("dictKv", data)
red.getData()
})
},
leftMiniSwitch() {
this.leftMini = !this.leftMini;
red.setData("leftMini", this.leftMini ? 'Min' : 'Max');
},
tooltipShow() {
$('[data-toggle="tooltip"]').tooltip('destroy');
if (!this.leftMini) {
return
}
setTimeout(function () {
$('[data-toggle="tooltip"]').tooltip({placement: 'right'});
}, 5)
},
},
mounted: function () {
this.loadDictData()

View File

@@ -1,6 +1,39 @@
<row class="data-list">
<div class="col-md-12">
<h3 class="pull-left">业务预览</h3>
<div class="col-xs-4 pull-right">
<div class="input-group">
<!--<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 v-for="f in cfg.filters" :value="f.name" v-show="!f.checked">{{f.label}}</option>
</select>-->
<div></div>
<div class="dropdown dropdown-hover pull-right" style="padding-right: 20px;max-width: 160px;">
<button class="btn" type="button" data-toggle="dropdown">
<i class="icon icon-filter"></i> 过滤条件 <span class="caret"></span></button>
<div class="dropdown-menu dropdown-menu-table" style="padding: 0">
<div class="checkbox" v-for="f in cfg.filters">
<label>
<input type="checkbox" v-model="f.checked" :value="f.name"> {{f.label}}
</label>
</div>
</div>
</div>
<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>
<div class="clearfix"></div>
<div class="info">
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
</div>
@@ -24,51 +57,49 @@
<!-- 业务列表 -->
<div class="col-xs-2">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 业务列表(Meta-Service)</div>
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
<li :class="['clearfix',{'active':service==item.alias}]" v-for="item in services" >
<a @click="service=item.name" :title="`${item.name}`" v-text="`${item.comment}`" href="javascript:;"></a>
<div style="padding-left: 10px;/*background-color: #ccc;*/width: 100%"> 业务列表(Meta-Service)</div>
<ul class="nav nav-tabs nav-stacked dlist" style="height: 100%">
<li :class="[{'active':service==item.name}]" v-for="item in services" >
<a @click="service=item.name" :title="`${item.name}`" v-text="`${item.comment}`" href="javascript:;"></a>
</li>
</ul>
</div>
<!-- 预览功能 -->
<div class="col-xs-10">
<div class="col-xs-4 pull-right">
<div class="input-group">
<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 v-for="f in cfg.filters" :value="f.name" v-show="!f.checked">{{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="clearfix"></div>
<div class="col-xs-10" style="margin-top: 15px">
<!-- 过滤条件 -->
<div class="col-lg-4 col-xs-6" v-for="(filter,index) in cfg.filters" v-if="filter.checked">
<div class="input-group item" style="padding-top: 3px">
<span class="input-group-addon" style="max-width: 130px;">{{filter.label}}</span>
<select class="form-control" v-model="filter['type']" style="width: 95px;">
<!--<div class="input-group col-xs-4" v-for="(filter,index) in cfg.filters" v-if="filter.checked">
<span class="input-group-addon">{{filter.label}}</span>
<select class="form-control input-group-addon">
<option>xxx</option>
<option>yyy</option>
</select>
<span class="input-group-addon fix-border fix-padding"></span>
<input type="text" class="form-control" placeholder="输入电话号码">
<span class="input-group-addon fix-border fix-padding"></span>
<span class="input-group-addon"><i class="icon icon-trash"></i></span>
</div>-->
<div class="col-xs-4" v-for="(filter,index) in cfg.filters" v-if="filter.checked">
<div class="input-group " style="padding-top: 3px">
<span class="input-group-addon" style="max-width: 100px;" :title="filter.label" data-toggle="tooltip">{{filter.label}}</span>
<select class="form-control" v-model="filter['type']">
<option v-for="(t, i) in filter.filterType" :value="t.name" v-text="t.remark"></option>
</select>
<span class="input-group-addon fix-border fix-padding"></span>
<input v-if="!filter.inType || filter.inType == 'INPUT'" type="text" class="form-control" v-model="filter['value']">
<select v-if="filter.inType == 'DICT'" class="form-control" v-model="filter['value']" style="width: 100px">
<!-- option v-for="(t, index) in filter.filterType" :value="t.name" v-text="t.remark"></option -->
<option value=""> 字典值一</option>
<option value=""> 字典值二</option>
<select v-if="filter.inType == 'DICT'" class="form-control" v-model="filter['value']">
<option value=""></option>
<option v-for="(t, index) in getDict(filter.inExt)" :value="t.value" v-text="t.label"></option>
<!--<option value=""> 字典值一</option>
<option value=""> 字典值二</option>-->
</select>
<span class="input-group-addon fix-border fix-padding" style="padding: 5px" title="删除过滤条件">
<span class="input-group-addon" title="删除过滤条件">
<a href="javascript:;" @click="filter.checked = false;"><i class="icon icon-trash"></i></a>
</span>
</div>
@@ -76,11 +107,11 @@
<!-- 数据表格 -->
<div class="col-xs-12" style="padding-top: 10px;overflow:auto;">
<table class="table table-bordered table-hover" style="width: 100%">
<table class="table table-bordered table-hover">
<thead>
<tr>
<!-- 'sort':field.order>0 -->
<!--<th>操作</th>-->
<th>操作</th>
<th v-for="field in cfg.shows"
v-if="field.inType != 'HIDDEN'"
v-text="field.label || getFieldLabel(field.col)"
@@ -93,11 +124,11 @@
<!--
<td v-for="field in cfg.shows" v-title="dealFieldFmt(row, field.col)" v-text="dealFieldFmt(row, field.col)"></td>
-->
<!--<td>
<td v-if="cfg.details.length">
<a href="javascript:;" @click="detailData=row; detail()">详情</a>
<a href="javascript:;" @click="detailData=row; edit()">编辑</a>
<a href="javascript:;" @click="detailData=row; del()">删除</a>
</td>-->
<a href="javascript:;" disabled @click="detailData=row; edit()">编辑</a>
<a href="javascript:;" disabled @click="detailData=row; del()">删除</a>
</td>
<td v-for="field in cfg.shows"
v-if="field.inType != 'HIDDEN'"
v-title="dealFieldFmt(row, field)"
@@ -110,8 +141,9 @@
<img src="../res/img/none.png">
<p>暂无数据</p>
</div>
<!-- 分页 -->
<div>
<ul class="pager pull-right" style="margin: 5px 10px">
<ul class="pager pull-right">
<li class="previous">
<a style="border: 0;">共{{list.total}}条数据</a>
@@ -124,7 +156,7 @@
</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>
<a style="border-bottom: 0;border-right: 0;border-top: 0;">到第<input v-model="limit.pn" style="width: 40px;height: 21px;">/ {{limit.total}}页</a>
</li>
<li class="previous">
<a @click="findList(limit.pn)" href="javascript:;">确定</a>
@@ -141,7 +173,7 @@
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>
<h4 class="modal-title" v-text="cfg.title + ' - [详情]'"> </h4>
</div>
<div class="modal-body">
<div class="modal-body" style="width: auto">
<table class="table table-bordered table-hover">
<tr v-for="i in parseInt(cfg.details.length/2)">
@@ -234,7 +266,7 @@
return {1:"男",2:"女"}[v] || "未知性别"
}
let {getServiceList, getCfg, getDataList, exportData, dataDel, dataSave} = meta
let {getServiceList, getDataList, exportData, dataDel, dataSave} = meta
let {showOk} = red
let vm = new Vue({
el:".data-list",
@@ -253,24 +285,26 @@
para: {},
list: {rows: [], total: 0},
limit: {pn: 1, ps: 20, total: 0},
order: {col: "id", desc: 1},
order: {col: "", desc: 1},
pk: "",
detailData: {}
detailData: {},
dictData: {}, // 存放字典数据
},
watch: {
addFilter(v) {
this.cfg.filters.forEach(function (f) {
if (f.name == v) {
if (f.name === v) {
f["checked"] = true;
vm.addFilter = "";
}
})
},
service() {
this.loadCfg();
this.limit = {pn: 1, ps: 20, total: 0};
this.order = {col:"", desc:1};
this.findList();
service(v) {
red.setData("meta:service", v)
this.loadCfg(function () {
vm.limit = {pn: 1, ps: 20, total: 0};
vm.findList();
});
},
list () {
let limit = this.limit;
@@ -294,41 +328,91 @@
return;
},
serviceList() {
getServiceList(json => {
vm.services = json;
vm.service = json[0].name;
getServiceList(res => {
vm.services = res;
// 如果有缓存数据,优先取上一次访问页面
if (red.getData("meta:service")) {
for (let i in res) {
if (res[i].name === red.getData("meta:service")) {
vm.service = res[i].name;
break
}
}
} else {
vm.service = res[0].name;
}
});
},
loadCfg() {
getCfg({name: this.service}).then(res => {
loadCfg(back) {
meta.getCfg({name: this.service}).then(res => {
// res['type'] = res.filters[0]['name']
for (i in res["filters"]) {
res["filters"][i]['type'] = res["filters"][i]['filterType'][0]['name']
}
if (!res.details || res.details.length === 0) {
res.details = res.shows
}
this.cfg = res
// 设置默认查询值
let fbean = red.getData(`FBean-${this.service}`,{});
if (fbean['filters']) {
for (let i in fbean['filters']) {
this.cfg.filters.forEach(function (f) {
if (f.name === fbean['filters'][i]['col']) {
f.value = fbean['filters'][i]['value']
f.type = fbean['filters'][i]['type'];
f.checked = f.checked || fbean['filters'][i]['checked']
}
})
}
}
if (fbean['orders'] && fbean['orders'].length > 0) {
this.order = fbean['orders'][0]
} else {
this.order = {col: "", desc: 0};
}
if (back) {
back();
}
});
},
dealFieldFmt(bean, colFmt) { //处理字典数据 及 自定义函数处理数据
let v = bean[colFmt["col"]]
if (colFmt.inType == "DICT") {
if (colFmt.inType === "DICT") {
// 取字典值返回
let dicttype = colFmt['inExt']
let dictArr = this.dictData[dicttype]
if (!dictArr) {
/*dict.list({type: dicttype}).then(res => {
dictArr = res
this.dictData[dicttype] = res
console.log(res)
})*/
return v
}
else if (colFmt.inType == "INPUT_DAY") {
for (let i in dictArr) {
if (dictArr[i].value + "" === v + "") {
return dictArr[i].label
}
else if (colFmt.inType == "INPUT_TIME") {
}
return v
} else if (colFmt.inType == "INPUT_DAY") {
return red.timeFmt(new Date(v), 'yyyy-MM-dd')
} else if (colFmt.inType == "INPUT_TIME") {
// 时间戳格式化
return red.timeFmt(new Date(v))
}
else if (colFmt.inType == "INPUT_FUNC") {
}
else if (colFmt.inType == "FILE" && v) {
} else if (colFmt.inType == "INPUT_FUNC") {
return eval(colFmt.inExt)
} else if (colFmt.inType == "FUNC") {
return funDept(bean, v)
} else if (colFmt.inType == "FILE" && v) {
return '<a href="{0}" target="_blank">查看</a>'.format(v)
}
else {
} else {
}
@@ -373,8 +457,12 @@
return str;
},
sortEvent(col) {
if (vm.order.col == col) {
if (vm.order.col === col) {
vm.order.desc = -vm.order.desc
// 第一次 1、第二次 -1、第三次点击的时候回到1这个时候取消排序
if (vm.order.desc === 1) {
vm.order.col = ''
}
} else {
vm.order.col = col;
vm.order.desc = 1;
@@ -428,6 +516,7 @@
limit: this.limit,
};
red.setData(`FBean-${this.service}`, fbean)
return fbean
},
detail() {
@@ -460,10 +549,17 @@
},
showInfo() {
$('#f-info').modal({moveable: true})
}
},
getDict(code) {
console.log(this.dictData[code])
return this.dictData[code] || []
},
},
mounted() {
this.serviceList();
dict.list({}).then(res => {
this.dictData = res
})
}
});
</script>

View File

@@ -1,4 +1,8 @@
<row class="meta-link">
<div class="col-md-12">
<h3 v-text="cfg.title"></h3>
</div>
<div class="info">
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
</div>
@@ -23,17 +27,19 @@
</div>
</div>
<div class="col-md-3 col-xs-4 sheet-cell">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 实体表(Meta-Table)</div>
<div class="col-xs-4 sheet-cell">
<div class="base-info">
实体表(Meta-Table) <input v-model="filter" placeholder="关键字筛选表" class="base-input">
</div>
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
<li :class="[{'active': aliasA == item.alias}]" v-for="item in tables" >
<li :class="[{'active': aliasA == item.alias}]" v-for="item in tables" v-if="dealFilter(item)">
<a href="javascript:;" @click="aliasA=item.alias" data-target="#tab3Content1" data-toggle="tab" v-text="dealTableLabel(item)"></a>
</li>
</ul>
<!--<p v-show="ckTable && ckTable.length">已选择 <code v-text="ckTable.length||0"></code> 个实体待导入</p>-->
</div>
<div class="col-md-9 col-xs-8">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 已关联的表 </div>
<div class="col-xs-8">
<div class="base-info"> 已关联的表 </div>
<!-- 关联表列表 -->
<button v-for="link in linkInfos" @click="aliasB=link.alias" :class="['btn', {'btn-primary' :aliasB==link.alias}]" style="margin: 5px">
<i class="icon icon-table"></i>
@@ -41,9 +47,9 @@
</button>
<div class="pull-right" style="margin: 5px;">
<button @click="status=1" v-show="status==0 && aliasB" class="btn">修改关联关系</button>
<button @click="status=0" v-show="status==1" class="btn">取消修改</button>
<button @click="addLinkDia()" class="btn">+ 添加关联表</button>
<button @click="status=1" v-show="status==0 && aliasB" class="btn btn-default">修改关联关系</button>
<button @click="status=0" v-show="status==1" class="btn btn-default">取消修改</button>
<button @click="addLinkDia()" class="btn btn-default">+ 添加关联表</button>
<button @click="saveLink()" v-show="status==1" class="btn btn-primary" style="margin-left: 15px">保存</button>
</div>
<!--<div class="clearfix"></div>-->
@@ -54,24 +60,24 @@
<th v-show="status==1">操作</th>
</tr>
<tr v-show="status==0" v-for="(k, v) in linkInfo.link">
<tr v-show="status==0" v-for="(k, v) in linkInfo.links">
<td v-text="k.startsWith(aliasA + '.') ? k : v"></td>
<td v-text="v.startsWith(aliasB + '.') ? v : k"></td>
</tr>
<tr v-show="status==1" v-for="(linkItem, index) in link2">
<tr v-show="status==1" v-for="(linkItem, index) in links2">
<td>
<select class="form-control" v-model="linkItem.f1">
<option></option>
<option v-for="item in tableInfoA.items"
:value="aliasA + '.' +item.name" v-text="aliasA + '.' +item.name + ' --- '+ item.label"></option>
:value="aliasA + '.' +item.name" v-text="strJoin(aliasA + '.' +item.name,item.label, '---')"></option>
</select>
</td>
<td>
<select class="form-control" v-model="linkItem.f2">
<option></option>
<option v-for="item in tableInfoB.items"
:value="aliasB + '.' +item.name" v-text="aliasB + '.' +item.name + ' --- '+ item.label">
:value="aliasB + '.' +item.name" v-text="strJoin(aliasB + '.' +item.name, item.label, '---')">
</option>
</select>
</td>
@@ -101,7 +107,7 @@
</div>
<div class="modal-body" style="text-align: center">
<select class="form-control" v-model="newLinkTable">
<option v-for="x in tables" :value="x" v-text="x.name + ' --- ' + x.comment" v-show="!isDisable(x)"></option>
<option v-for="x in tables" :value="x" v-text="strJoin(x.tablename, x.comment, '---')" v-show="!isDisable(x)"></option>
</select>
</div>
<div class="modal-footer">
@@ -126,6 +132,7 @@
let vm = new Vue({
el: ".meta-link",
data: {
cfg:{title:"实体关系"},
status: 0,
tables: [], //所有的表数据{name,comment, alias, linkCount}
aliasA: '', //选中的主体表别名
@@ -134,13 +141,15 @@
links: [], //
linkInfos: [],
linkInfo: {},
link2: [],
links2: [],
newLinkTable: {},
aliasB: '',
tableInfoA: {items:[]},
tableInfoB: {items:[]},
filter: '',
},
watch: {
aliasA(v) {
@@ -175,20 +184,20 @@
for (let i in this.links) { // 数据转换
if (this.links[i]['tables'][0] == v || this.links[i]['tables'][1] == v) {
linkInfo = this.links[i]
let link = {}
let link2 = [] // [{f1:"", f2:""}]
for(k in linkInfo["link"]) {
let [_k, _v] = [k, linkInfo["link"][k]]
let links = {}
let links2 = [] // [{f1:"", f2:""}]
for(k in linkInfo["links"]) {
let [_k, _v] = [k, linkInfo["links"][k]]
if (k.startsWith(this.aliasA + '.')) {
link[_k] = _v
link2.push({f1: _k, f2: _v})
links[_k] = _v
links2.push({f1: _k, f2: _v})
} else {
link[_v] = _k
link2.push({f1: _v, f2: _k})
links[_v] = _k
links2.push({f1: _v, f2: _k})
}
}
linkInfo['link'] = link
this.link2 = link2
linkInfo['links'] = links
this.link2 = links2
}
}
this.linkInfo = linkInfo
@@ -213,7 +222,15 @@
})
},
dealTableLabel(table) {
return `${table.name} [${table.comment}] (${table.linkCount})`
return `${table.tablename} (${table.comment||'-'}) [${table.linkCount}]`
},
dealFilter(table) {
// table.name 中是否包含 thiss.filter 的值
if (table.tablename.indexOf(this.filter) > -1 || table.comment.indexOf(this.filter) > -1) {
return true
} else {
return false
}
},
addLinkDia() {
this.newLinkTable = ""
@@ -240,28 +257,28 @@
// 保存(同修改)
},
addLinkField() {
let link2 = this.link2
link2.push({f1: "", f2: ""})
this.link2 = link2
let links2 = this.links2
links2.push({f1: "", f2: ""})
this.links2 = links2
},
delLinkField(index) {
let link2 = []
let links2 = []
for (let i in this.link2) {
if (i != index) {
link2.push(this.link2[i])
links2.push(this.link2[i])
}
}
this.link2 = link2
this.links2 = links2
},
saveLink() {
let link = {}
for(let i in this.link2) {
let item = this.link2[i]
let links = {}
for(let i in this.links2) {
let item = this.links2[i]
if (item['f1'] && item['f2']) {
link[item['f1']] = item['f2']
links[item['f1']] = item['f2']
}
}
if (link.size == 0) {
if (links.size === 0) {
red.showError("请填写完整的关联字段信息")
return false
}
@@ -271,7 +288,7 @@
if (!linkInfo['tables']) {
linkInfo['tables'] = [this.aliasA, this.aliasB]
}
linkInfo["link"] = link
linkInfo["links"] = links
linkSave({link: linkInfo}).then(res => {
red.showOk()
})
@@ -287,6 +304,12 @@
},
showInfo() {
$('#f-info').modal({moveable: true})
},
strJoin(a,b,c) {
if (a && b) {
return a + ' ' + c + ' ' + b
}
return a + b
}
},
mounted: function () {

View File

@@ -10,10 +10,10 @@
.dropdown-menu-table .table td {
padding: 0;
}
.dropdown-menu-table .table a {
/*.dropdown-menu-table .table a {
padding: 8px;
display: block;
}
}*/
/*.dropdown-menu-table .table a:hover,
.dropdown-menu-table .table a:active,
.dropdown-menu-table .table a:focus {
@@ -22,7 +22,99 @@
}*/
</style>
<row class="meta-service">
<div class="col-xs-12">
<div class="col-md-12 pull-left" style="margin-bottom: 5px">
<h3>业务管理</h3>
<div class="input-group pull-right">
<div class="pull-left">
<button @click="createService({})" class="btn btn-primary" type="button"> 新建业务</button>
</div>
<!--<span class="input-group-btn">
<button class="btn btn-default" type="button">选择业务类型</button>
</span>
<div class="input-group-btn dropdown dropdown-hover">
<button class="btn" type="button" data-toggle="dropdown"><span v-text="serviceLabel"></span> <span class="caret"></span></button>
<ul class="dropdown-menu">
<li v-for="item in services" @click="service=item.name;serviceLabel=item.comment;"><a href="javascript:;" v-text="`${item.comment}`"></a></li>
</ul>
</div>-->
<!--
<option v-for="item in services" :value="item.name"> {{item.name}}&nbsp;&nbsp;&nbsp;[{{item.comment}}]</option>
<select class="form-control dropdown-hover" v-model="service" style="width: 180px;">
<option v-for="item in services" :value="item.name"> {{item.name}}&nbsp;&nbsp;&nbsp;[{{item.comment}}]</option>
</select>
-->
<!--<span class="input-group-btn pull-left" style="padding-left: 5px">
<button @click="createService()" class="btn btn-primary" 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">
<button @click="status='detail'" :class="['btn',{'btn-primary':status=='detail'}]" type="button"> 详情配置</button>
</span>
<span class="input-group-btn">
<button @click="status='edit'" :class="['btn',{'btn-primary':status=='edit'}]" type="button"> 表单配置</button>
</span>
<span class="input-group-btn">
<button @click="status='del'" :class="['btn',{'btn-primary':status=='del'}]" type="button"> 删除配置</button>
</span>
<span class="input-group-btn" style="padding-left: 10px">
<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: 20px">
<button @click="tipShow()" :class="['btn',{'btn-primary':status==7}]" type="button"> 基本属性</button>
</span>-->
<span class="input-group-btn" style="padding-left: 20px">
<button @click="save()" :class="['btn',{'btn-primary':status!=0},{'disabled':status==0}]" type="button"> 保存</button>
</span>
</div>
<!--<div class="pull-leftx">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="icon icon-filter"></i> 过滤 <span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-table">
<table class="table">
<tr>
<td>
<a href="javascript:;">
<input type="checkbox" checked>
<label>业务名称</label>
</a>
</td>
<td>
<a href="javascript:;">
<input type="checkbox" checked>
<label>标识码</label>
</a>
</td>
<td>
<a href="javascript:;">
<input type="checkbox" checked>
<label>状态</label>
</a>
</td>
</tr>
</table>
</ul>
</div>
</div>-->
</div>
<div class="info" style="padding-left: 10px">
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
</div>
@@ -66,81 +158,61 @@
</div>
<div class="input-group list-head">
<div class="col-xs-3">
<div class="base-info"> 业务列表</div>
<table class="table table-bordered tlist">
<tr>
<th>业务KEY</th>
<th>业务名称</th>
<th>操作</th>
</tr>
<tr v-for="item in services" @click="service=item.name;serviceLabel=item.comment;" :class="[{'active': item.name==service}]">
<td>
{{item.name}}
</td>
<td>{{item.comment}}</td>
<td>
<a @click="createService(item)" href="javascript:">编辑</a>
<!--<a href="javascript:">删除</a>-->
</td>
</tr>
<span class="input-group-btn">
<button class="btn btn-default" type="button">选择业务类型</button>
</span>
<div class="input-group-btn dropdown dropdown-hover">
<button class="btn" type="button" data-toggle="dropdown"><span v-text="serviceLabel"></span> <span class="caret"></span></button>
<ul class="dropdown-menu">
<li v-for="item in services" @click="service=item.name;serviceLabel=item.comment;"><a href="javascript:;" v-text="`${item.comment}`"></a></li>
</ul>
</table>
</div>
<!--
<option v-for="item in services" :value="item.name"> {{item.name}}&nbsp;&nbsp;&nbsp;[{{item.comment}}]</option>
<select class="form-control dropdown-hover" v-model="service" style="width: 180px;">
<option v-for="item in services" :value="item.name"> {{item.name}}&nbsp;&nbsp;&nbsp;[{{item.comment}}]</option>
</select>
-->
<span class="input-group-btn pull-left" style="padding-left: 5px">
<button @click="createService()" :class="['btn']" 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">
<button @click="status='detail'" :class="['btn',{'btn-primary':status=='detail'}]" type="button"> 详情配置</button>
</span>
<span class="input-group-btn">
<button @click="status='edit'" :class="['btn',{'btn-primary':status=='edit'}]" type="button"> 表单配置</button>
</span>
<span class="input-group-btn">
<button @click="status='del'" :class="['btn',{'btn-primary':status=='del'}]" type="button"> 删除配置</button>
</span>
<!-- 实体字段信息 -->
<!--<div class="col-xs-4" style="padding-left: 0px;">
<span class="input-group-btn" style="padding-left: 10px">
<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: 20px">
<button @click="tipShow()" :class="['btn',{'btn-primary':status==7}]" type="button"> 基本属性</button>
</span>-->
</div>-->
<span class="input-group-btn" style="padding-left: 20px">
<button @click="save()" :class="['btn',{'btn-primary':status!=0},{'disabled':status==0}]" type="button"> 保存</button>
</span>
</div>
</div>
<div class="col-xs-2">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 业务相关表</div>
<ul class="nav nav-tabs nav-stacked tlist">
<div class="col-xs-9" style="padding-left: 0px;padding-right: 0px;">
<div class="col-xs-4">
<div class="base-info"> 业务相关表</div>
<!--<ul class="nav nav-tabs nav-stacked tlist">
<li @click="sheet=item" :class="[{active: sheet==item }]" v-for="item in sheetArr">
<a href="javascript:;" data-target="#tab3Content1" data-toggle="tab" v-text="serviceDetail['tables'][item]['name']"></a>
</li>
</ul>
</ul>-->
<!--<div class="btn-group" style="margin: 5px 0">
<a class="btn btn-default" @click="sheet=item" v-for="item in sheetArr" v-text="dealTableName(item)"> </a>
</div>-->
<!-- 业务相关表使用 radios 做选择 -->
<div v-for="item in sheetArr" @click="sheet=item" style="cursor:pointer; padding: 0 3px">
<input type="radio" :name="item" :value="item" v-model="sheet">
<a v-text="dealTableName(item)" style="text-decoration: none"></a>
</div>
<!-- 实体字段信息 -->
<div class="col-xs-4" style="padding-left: 0px;">
<div style="padding-left: 10px;background-color: #ccc;"> 字段信息</div>
<div class="base-info">字段信息</div>
<table class="table table-bordered">
<tr>
<td v-show="status==3 || status==4 || status==5 || status==6"><input type="checkbox"></td>
<td v-show="status==3 || status==4 || status==5 || status==6 || status=='detail' || status=='edit'"><input type="checkbox"></td>
<th v-show="status==1"></th>
<th>字段</th>
<th>中文名</th>
<th>数据字段</th>
<th>注释</th>
<!--<th>数据类型</th>
<th>输入类型</th>
<th>附加属性</th>
@@ -154,7 +226,7 @@
<td v-show="status=='detail'"><input type="checkbox" v-model="detailArr" :value="sheet + '$' + item.name"></td>
<td v-show="status=='edit'"><input type="checkbox" v-model="editArr" :value="sheet + '$' + item.name"></td>
<td v-text="item.name" style="background-color: rgb(235, 235, 228);"></td>
<td v-text="item.name"></td>
<td v-text="item.label"></td>
<!--<td v-text="item.type"></td>
<td v-text="item.inType"></td>
@@ -164,10 +236,10 @@
</table>
</div>
<div class="col-xs-6" style="padding-left: 0px;padding-right: 0px;">
<div class="col-xs-8">
<!-- shows -->
<div id="show" v-show="status==5">
<div style="padding-left: 10px;background-color: #ccc;"> 列表配置</div>
<div class="base-info"> 列表配置</div>
<table class="table table-bordered table-auto">
<thead>
<tr>
@@ -179,26 +251,25 @@
</tr>
</thead>
<tr v-for="(item, index) in serviceInfo.shows">
<td class="icon icon-move">
<td :class="['icon','icon-move',{'color-x': colorX(item)}]">
<input type="hidden" name="item" :value="JSON.stringify(item)">
</td>
<td v-text="item.col" style="background-color: rgb(235, 235, 228);"></td>
<td style="padding: 1px;"><input v-model="item.label" class="form-control" style="width: 130px;padding: 0px"></td>
<td style="padding: 1px;">
<select v-model="item.inType" class="form-control" style="width: 130px">
<td v-text="dealCol(item.col)"></td>
<td><input v-model="item.label" class="form-control" ></td>
<td>
<select v-model="item.inType" class="form-control" >
<option v-for="x in inTypes" :value="x">{{x}}</option>
</select>
</td>
<td style="padding: 1px;" title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<select v-show="item.inType == 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px">
<option></option>
<td title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK' || item.inType == 'INPUT_FUNC'" v-model="item.inExt" class="form-control">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'INPUT_FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control">
<select v-show="item.inType == 'DICT'" v-model="item.inExt" class="form-control">
<option v-for="x in dictType" :value="x.value">{{x.label}}</option>
</select>
</td>
<!--
<td style="padding: 1px;"><input v-model="item.fmt" class="form-control" style="width: 130px;padding: 0px"></td>
<td><input v-model="item.fmt" class="form-control" style="width: 130px;padding: 0px"></td>
-->
</tr>
</table>
@@ -206,29 +277,29 @@
<!-- exports -->
<div id="export" v-show="status==3">
<div style="padding-left: 10px;background-color: #ccc;"> 导出配置</div>
<table class="table table-bordered table-auto" style="width: 100%">
<div class="base-info"> 导出配置</div>
<table class="table table-bordered table-auto">
<thead>
<tr>
<th></th>
<th>字段</th>
<th>中文名</th>
<th>数据字段</th>
<th>展示名称</th>
<th>格式化类型</th>
<th>附加参数</th>
</tr>
</thead>
<tr v-for="item in serviceInfo.exports">
<td class="icon icon-move">
<td :class="['icon','icon-move',{'color-x': colorX(item)}]">
<input type="hidden" name="item" :value="JSON.stringify(item)">
</td>
<td v-text="item.col" style="background-color: rgb(235, 235, 228);"></td>
<td style="padding: 1px;"><input v-model="item.label" class="form-control" style="padding: 0px"></td>
<td style="padding: 1px;">
<td v-text="dealCol(item.col)" style="background-color: rgb(235, 235, 228);"></td>
<td><input v-model="item.label" class="form-control" style="padding: 0px"></td>
<td>
<select v-model="item.inType" class="form-control" style="width: 130px">
<option v-for="x in exportFmtTypes" :value="x">{{x}}</option>
</select>
</td>
<td style="padding: 1px;" title="格式化类型为funs或qtask的时候需要填写附加参数">
<td title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK' || item.inType == 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
</td>
@@ -246,8 +317,8 @@
<thead>
<tr style="background-color: #f1f1f1">
<th></th>
<th>字段</th>
<th>中文名</th>
<th>数据字段</th>
<th>展示名称</th>
<!--<th>展示名</th>-->
</tr>
</thead>
@@ -267,37 +338,38 @@
<!-- filters -->
<div id="filter" v-show="status==6">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 查询配置</div>
<table class="table table-bordered table-auto" style="width: 100%">
<div class="base-info"> 查询配置</div>
<table class="table table-bordered table-auto">
<thead>
<tr>
<th></th>
<th style="width: 30px">字段</th>
<th style="width: 30px">中文名</th>
<th style="width: 30px">数据字段</th>
<th>展示名称</th>
<th style="width: 30px">默认</th>
<th>组件配置</th>
<th>附加参数</th>
</tr>
</thead>
<tr v-for="item in serviceInfo.filters">
<td class="icon icon-move">
<td :class="['icon','icon-move',{'color-x': colorX(item)}]">
<input type="hidden" name="item" :value="JSON.stringify(item)">
</td>
<td v-text="item.name" style="background-color: rgb(235, 235, 228);"></td>
<td style="padding: 1px;"><input v-model="item.label" class="form-control" style="width: 130px;padding: 0px"></td>
<td style="padding: 1px;text-align: center;">
<label>
<td v-text="dealCol(item.name)"></td>
<td><input v-model="item.label" class="form-control"></td>
<td style="text-align: center">
<input type="checkbox" v-model="item.checked" value="1">
</label>
</td>
<td style="padding: 1px;overflow: inherit;">
<td style="overflow: inherit;">
<select v-model="item.inType" class="form-control">
<option v-for="x in findTypes" :value="x">{{x}}</option>
</select>
</td>
<td style="padding: 1px;">
<input v-show="item.inType == 'DICT' || item.inType == 'CHECKBOX' || item.inType == 'REDIO'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<input disabled v-show="!(item.inType == 'DICT' || item.inType == 'CHECKBOX' || item.inType == 'REDIO')" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<td>
<input v-show="item.inType == 'CHECKBOX' || item.inType == 'REDIO'" v-model="item.inExt" class="form-control">
<input disabled v-show="!(item.inType == 'DICT' || item.inType == 'CHECKBOX' || item.inType == 'REDIO')" v-model="item.inExt" class="form-control">
<select v-show="item.inType == 'DICT'" v-model="item.inExt" class="form-control">
<option v-for="x in dictType" :value="x.value">{{x.label}}</option>
</select>
</td>
<!--
<td style="padding: 1px;overflow: inherit;">
@@ -331,7 +403,7 @@
<!-- details -->
<div id="detail" v-show="status=='detail'">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 详情配置</div>
<div class="base-info"> 详情配置</div>
<table class="table table-bordered table-auto">
<thead>
<tr>
@@ -344,19 +416,19 @@
</thead>
<tbody>
<tr v-for="(item, index) in serviceInfo.details">
<td class="icon icon-move">
<td :class="['icon','icon-move',{'color-x': colorX(item)}]">
<input type="hidden" name="item" :value="JSON.stringify(item)">
</td>
<td v-text="item.col" style="background-color: rgb(235, 235, 228);"></td>
<td style="padding: 1px;"><input v-model="item.label" class="form-control" style="width: 130px;padding: 0px"></td>
<td style="padding: 1px;">
<select v-model="item.inType" class="form-control" style="width: 130px">
<td v-text="dealCol(item.col)"></td>
<td><input v-model="item.label" class="form-control"></td>
<td>
<select v-model="item.inType" class="form-control">
<option v-for="x in inTypes" :value="x">{{x}}</option>
</select>
</td>
<td style="padding: 1px;" title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK' || item.inType == 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<td title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK' || item.inType == 'DICT'" v-model="item.inExt" class="form-control">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control">
</td>
</tr>
</tbody>
@@ -365,7 +437,7 @@
<!-- edits -->
<div id="edit" v-show="status=='edit'">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 表单配置</div>
<div class="base-info"> 表单配置</div>
<table class="table table-bordered table-auto">
<thead>
<tr>
@@ -379,19 +451,19 @@
</thead>
<tbody>
<tr v-for="(item, index) in serviceInfo.edits">
<td class="icon icon-move">
<td :class="['icon','icon-move',{'color-x': colorX(item)}]">
<input type="hidden" name="item" :value="JSON.stringify(item)">
</td>
<td v-text="item.col" style="background-color: rgb(235, 235, 228);"></td>
<td style="padding: 1px;"><input v-model="item.label" class="form-control" style="width: 100px;padding: 0px"></td>
<td style="padding: 1px;">
<select v-model="item.inType" class="form-control" style="width: 130px">
<td v-text="dealCol(item.col)"></td>
<td><input v-model="item.label" class="form-control"></td>
<td>
<select v-model="item.inType" class="form-control">
<option v-for="x in inTypes" :value="x">{{x}}</option>
</select>
</td>
<td style="padding: 1px;" title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK' || item.inType == 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control" style="width: 130px;padding: 0px">
<td title="格式化类型为funs或qtask的时候需要填写附加参数">
<input v-show="item.inType == 'FUNC' || item.inType == 'QTASK' || item.inType == 'DICT'" v-model="item.inExt" class="form-control">
<input disabled v-show="item.inType != 'FUNC' && item.inType != 'QTASK' && item.inType != 'DICT'" v-model="item.inExt" class="form-control">
</td>
<td style="padding: 1px;overflow: inherit;">
<div class="dropdown dropdown-hover">
@@ -421,7 +493,7 @@
<!-- del -->
<div id="del" v-show="status=='del'">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 删除策略</div>
<div class="base-info"> 删除策略</div>
<div class="panel-body" style="overflow:auto;">
<form class="form-horizontal">
<!--
@@ -439,8 +511,8 @@
<br>
<div v-show="serviceInfo.dels.cate == 'UP_FIELD'" class="form-group">
<label class="col-md-2">SQL</label>
<div class="col-md-8">
<label class="col-xs-2">SQL</label>
<div class="col-xs-8">
<textarea v-model="serviceInfo.dels.sql1" disabled style="width: 100%;" rows="5"></textarea>
<!--
<input v-model="serviceInfo.dels.name" class="form-control" id="name" placeholder="请输入Table名称">
@@ -449,8 +521,8 @@
</div>
<div v-show="serviceInfo.dels.cate == 'SQL'" class="form-group">
<label class="col-md-2">SQL</label>
<div class="col-md-8">
<label class="col-xs-2">SQL</label>
<div class="col-xs-8">
<textarea v-model="serviceInfo.dels.sql" style="width: 100%;" rows="5"></textarea>
<!--
<input v-model="serviceInfo.dels.name" class="form-control" id="name" placeholder="请输入Table名称">
@@ -462,6 +534,7 @@
</div>
</div>
</div>
</div>
<!-- 新建业务 -->
@@ -477,8 +550,8 @@
<div class="form-group">
<label class="col-sm-3 required">选择业务主表</label>
<div class="col-sm-6">
<select class="form-control" v-model="createRow.table">
<option v-for="x in tables" :value="x.alias" v-text="x.name + ' --- ' + x.comment"></option>
<select class="form-control" v-model="createRow.tablealias">
<option v-for="x in tables" :value="x.alias" v-text="x.tablename + ' --- ' + x.comment"></option>
</select>
</div>
</div>
@@ -527,13 +600,13 @@
EQUAL:"等于", NOTEQUAL:"不等于", IN: "包含", NOTIN:"不包含", LIKE: "模糊查询", RANGE: "范围"
},
findTypes: ["INPUT", "DICT", "CHECKBOX", "RADIO", "DAY", "TIME"],
inTypes: ["INPUT", "DICT", "INPUT_DAY", "INPUT_TIME", "FUNC", "QTASK", "HIDDEN", "FILE"],
inTypes: ["INPUT", "DICT", "INPUT_DAY", "INPUT_TIME", /*"INPUT_FUNC", "FUNC", "QTASK",*/ "HIDDEN", "FILE"],
ckTypes: [{label:"必填", name: "NOTNULL"},{label:"IP", name: "IP"},{label:"IPv4", name: "IPv4"},{label:"电话号码", name: "phone"}],
dataTypes: ["bigint(20)", "varchar(255)", "varchar(64)", "varchar(32)", "varchar(16)", "int(11)", "int(3)", "int(2)", "datetime"],
filterCate: ["EQUAL", "NOTEQUAL", "LIKE", "IN"],
serviceInfo: {
name: "",
table: "",
tablealias: "",
items: [],
shows: [],
exports: [],
@@ -559,11 +632,11 @@
filters: [],//查询配置
status: 0, //页面默认状态 0:默认 3:导出 4:导入 5:列表配置 6:查询配置 detail:详情配置 edit:表单配置 del:删除策略配置
status: 5, //页面默认状态 0:默认 3:导出 4:导入 5:列表配置 6:查询配置 detail:详情配置 edit:表单配置 del:删除策略配置
services: [],//业务列表
service: "", //页面选择的业务类型
serviceLabel: "",
table: "",//表别名
tablealias: "",//表别名
//filter
filterArr: [],
@@ -649,7 +722,7 @@
//console.log("dels", dels)
let cate = dels["cate"] || "UP_FIELD"
let sql1 = dels["sql1"] || "update #(table) set status=9 where id=#(id);"
let sql = dels["sql"] || `update ${v['tables'][this.serviceInfo.table]['name']} set status=9 where id=#(id);`
let sql = dels["sql"] || `update ${v['tables'][this.serviceInfo.tablealias]['tablename']} set status=9 where id=#(id);`
let qtask = dels["qtask"] || ""
let serviceInfo = this.serviceInfo
@@ -657,7 +730,7 @@
this.serviceInfo = serviceInfo
},
sheet: function (v) {
this.table = v;
this.tablealias = v;
},
filterArr: function (v) { // 添加或删除选项触发
let filters = this.serviceInfo.filters
@@ -709,7 +782,7 @@
b:for (let j in shows) {
if (v[i] == shows[j]['col']) {
if (!shows[j]['label']) {
shows[j]['label'] = this.getFieldLabel(v[i])
shows[j]['label'] = this.getFieldLabel(v[i]) || (shows[j]['col']).replace(/\$/g, ".")
}
if (!shows[j]['inType']) {
shows[j]['inType'] = "INPUT"
@@ -862,7 +935,7 @@
}
}
this.serviceInfo = json;
vm.serviceInfo = json;
})
},
loadDetail(name) {
@@ -921,7 +994,7 @@
});
if (this.status == 1) {
if (this.status === 1) {
$('#sortableList,table>tbody').sortable({
selector: '.list-group-item, tr',
finish: function (e) {
@@ -1067,8 +1140,8 @@
red.showMsg();
}
},
createService() {
this.createRow = {}
createService(row) {
this.createRow = row
if (this.tables.length == 0) {
tableLinkList().then(res => {
this.tables = res
@@ -1078,7 +1151,7 @@
},
saveService() {
serviceSave({service: this.createRow}).then(res => {
red.showOk("创建成功, 请对业务进行配置")
red.showOk(this.createRow['servid'] ? "操作成功" : "创建成功, 请对业务进行配置")
$('#createServiceDia').modal('hide')
this.service = this.createRow.name
@@ -1089,15 +1162,37 @@
},
showInfo() {
$('#f-info').modal({moveable: true})
},
dealCol(col) {
return col.replace(/\$/g, ".")
},
dealTableName(item) {
let table = this.serviceDetail['tables'][item]
return `[${table.alias}] ${table.tablename} (${table.comment})`
},
colorX(item) {
// {col :"rl$transaction_price"} 截取出 rl
if (item.col) {
let col = item.col.split("$")[0]
return col === this.sheet
}
if (item.name) {
let col = item.name.split("$")[0]
return col === this.sheet
}
return false
}
},
mounted: function () {
this.serviceList()
this.setMove(this.status)
dictList({type:"dict"}).then(res => {
this.dictType = res
console.log(res)
//console.log(res)
})
}
});

View File

@@ -30,6 +30,10 @@
</style>
<!-- 对话框HTML -->
<div class="importDev">
<div class="col-md-12">
<h3>实体导入</h3>
</div>
<div class="info">
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
</div>
@@ -108,7 +112,7 @@
<!-- excel sheets -->
<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>
<div class="base-info"> Excel-Sheet</div>
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
<li class="checkbox-inline clearfix" v-for="item in sheetArr" >
<!-- || sheetData[item]['hv']==1 -->
@@ -123,17 +127,17 @@
<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="base-info"> 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%">
<table class="table-bordered">
<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>
<tr v-show="sheet && sheet!='表说明' && sheet!='表名称'">
<th></th>
<th>注释</th>
<th>数据类型</th>
<th>输入类型</th>
<th>附加属性</th>
@@ -181,7 +185,7 @@
<label class="col-md-1 col-sm-1" style="padding-bottom: 10px;padding-top: 5px;">数据源选择</label>
<div class="col-md-2 col-sm-10" style="padding-bottom: 10px">
<select class="form-control" v-model="dbPlat">
<option v-for="item in dbPlats" :value="item" v-text="item.name"></option>
<option v-for="item in dbPlats" :value="item" v-text="item.dbname"></option>
</select>
</div>
<div class="col-md-2 col-sm-10" style="padding-bottom: 10px">
@@ -193,34 +197,41 @@
<div class="clearfix"></div>
<div class="row" v-show="tableName">
<div class="col-xs-2 sheet-cell">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> DB-Table</div>
<div class="col-xs-4 sheet-cell">
<div class="base-info"> DB-Table</div>
<ul class="nav nav-tabs nav-stacked tlist" style="height: 90%">
<li class="checkbox-inline clearfix" v-for="item in tableArr" >
<li class="checkbox-inline" v-for="item in tableArr" >
<!-- || tableData[item]['hv']==1 -->
<input type="checkbox"
v-model="ckTable"
:value="tableData[item]['name']"
:value="tableData[item]['tablename']"
:disabled="item=='表说明' || item=='表名称'"
>
<a :class="[{hv: tableData[item]['hv']==1 }]" href="javascript:;" @click="tableName=item" data-target="#tab3Content1" data-toggle="tab" v-text="item"></a>
</li>
</ul>
<!-- v-show="ckTable && ckTable.length" -->
<p >已选择 <code v-text="ckTable.length||0"></code> 个实体待导入,上面<code class="text-danger">红色</code> 部分已经导入过的数据表</p>
<div class="modal-footer" v-show="cate=='mysql'">
<button @click="back()" type="button" class="btn btn-default" data-dismiss="modal">返回</button>
<button @click="ckTable=[]" type="button" class="btn btn-default" data-dismiss="modal">取消选择</button>
<button @click="saveTable()" type="button" class="btn btn-primary">导入</button>
</div>
</div>
<div class="col-xs-8">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> Table-Detail</div>
<div class="base-info"> Table-Detail</div>
<div class="tab-content col-xs-9">
<div class="tab-pane fade active in">
<table class="table-bordered" style="width: 100%">
<table class="table-bordered">
<caption class="" v-show="tableName && (sheet!='表说明' || sheet!='表名称')">
表名称: <span v-text="tableInfo.name"></span>,中文名:<span v-text="tableInfo.comment"></span>
</caption>
<thead>
<tr style="background-color: #f1f1f1">
<th>字段</th>
<th>中文名</th>
<th></th>
<th>注释</th>
<th>数据类型</th>
<!--<th>输入类型</th>
<th>附加属性</th>
@@ -255,11 +266,6 @@
<button @click="ck=[]" type="button" class="btn btn-default" data-dismiss="modal">取消选择</button>
<button @click="saveTable()" type="button" class="btn btn-primary">确定</button>
</div>
<div class="modal-footer" v-show="cate=='mysql'">
<button @click="ckTable=[]" 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="saveTable()" type="button" class="btn btn-primary">确定</button>
</div>
</div>
<script>
@@ -286,7 +292,7 @@
tableData: {},
tableArr: [],
dbPlat: red.getData("dbPlat",{}),
dbPlatId: red.getData("dbPlatId",''),
dbid: red.getData("dbid",''),
catalog: '',
tableName: '',
ckTable: [],
@@ -318,7 +324,7 @@
}
},
dbPlat(v) {
this.dbPlatId = v['key']
this.dbid = v['dbid']
this.catalogs = v['catalogs']
},
catalog() {
@@ -326,7 +332,7 @@
//cache
red.setData("dbPlat", this.dbPlat)
red.setData("dbPlatId", this.dbPlatId)
red.setData("dbid", this.dbid)
red.setData("catalog", this.catalog)
},
tableName() {
@@ -385,8 +391,8 @@
},
//------从mysql导入使用的相关方法-------
loadTables() { // 查询table列表
let [dbPlatId, catalog] = [this.dbPlatId, this.catalog]
sheetMySql({dbPlatId, catalog}).then(res => { // 数据转换
let [dbid, catalog] = [this.dbid, this.catalog]
sheetMySql({dbid, catalog}).then(res => { // 数据转换
this.tableData = res
let tableArr = []
let ckTable = []
@@ -407,7 +413,7 @@
this.tableInfo = this.tableData[this.tableName]
if (!this.tableInfo['load']) {
tableInfo({dbPlatId: this.dbPlatId, catalog: this.catalog, tableName: this.tableName}).then(res => {
tableInfo({dbid: this.dbid, catalog: this.catalog, tableName: this.tableName}).then(res => {
res['hv'] = this.tableData[this.tableName]['hv']
res['load'] = 1
@@ -418,8 +424,8 @@
},
saveTable() { // 保存数据
if (this.cate == 'mysql') {
let [dbPlatId, catalog, tableArr] = [this.dbPlatId, this.catalog, this.ckTable]
saveTable({dbPlatId, catalog, tableArr}).then(res => {
let [dbid, catalog, tableArr] = [this.dbid, this.catalog, this.ckTable]
saveTable({dbid, catalog, tableArr}).then(res => {
red.showOk()
this.loadTables()
})

View File

@@ -3,11 +3,11 @@
<h3 v-text="cfg.title"></h3>
</div>
<div class="col-md-12">
<div class="input-group list-head pull-left">
<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="filter.dbPlatId" style="width: 150px;">
<select class="form-control" v-model="filter.dbid" style="width: 150px;">
<option></option>
<option v-for="item in dbPlats" :value="item.key">{{item.name}}</option>
</select>
@@ -28,7 +28,7 @@
</div>
</div>
<div class="col-md-12" style="padding-top: 10px;overflow:auto;">
<table class="table table-bordered table-hover" style="width: 100%">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -65,7 +65,7 @@
},
dbPlats:[],
list:{rows:[{name:"user", comment:"[用户表]", dataCount: 23}]},
filter: {dbPlatId: "", catalog: "", name: ""},
filter: {dbid: "", catalog: "", name: ""},
},
watch: {
filter: {
@@ -81,7 +81,7 @@
catalogs: function () {
var dbPlats = this.dbPlats;
for (i in dbPlats) {
if (dbPlats[i].key == this.filter.dbPlatId) {
if (dbPlats[i].key == this.filter.dbid) {
return dbPlats[i]["catalogs"]
}
}

View File

@@ -1,4 +1,8 @@
<row class="meta-list">
<div class="col-md-12">
<h3 v-text="cfg.title" class="pull-left"></h3>
</div>
<div class="info">
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
</div>
@@ -21,22 +25,40 @@
</div>
<div class="col-md-12 col-xs-12">
<div class="input-group list-head">
<hr style="margin: 0px 5px 5px">
</div>
<!-- 实体列表 -->
<div class="col-md-4 col-xs-4">
<div>
实体表(Meta-Table) <input v-model="filter" placeholder="筛选实体" class="base-input">
<button @click="loadImportPage()" class="btn btn-primary pull-right" type="button"> <i class="icon icon-signin"></i>导入实体</button>
</div>
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
<li :class="[{'active':alias==item.alias}]" v-for="item in tables" v-if="dealFilter(item)">
<a @click="alias=item.alias" :title="dealTableLabel(item)" data-toggle="tooltip" v-text="dealTableLabel(item)" href="javascript:;"></a>
</li>
</ul>
</div>
<div class="col-md-8 col-xs-8">
<div class="input-group" style="padding-bottom: 10px">
<div class="pull-left">
<span class="input-group-btn">
<button @click="loadImportPage()" :class="['btn','btn-primary']" type="button"> <i class="icon icon-signin"></i>导入实体</button>
</span>
</div>
<span class="input-group-btn" style="padding-left: 5px">
<button @click="status=8" :class="['btn',{'btn-primary':status==8}]" type="button"> 实体关系MetaLink</button>
<button @click="status=8" :class="['btn',{'btn-primary':status==8}]" type="button"> 实体关系</button>
</span>
<span class="input-group-btn" style="padding-left: 10px">
<button @click="status=2" :class="['btn',{'btn-primary':status==2}]" type="button"> 字段编辑</button>
</span>
<span class="input-group-btn">
<button @click="status=1" :class="['btn',{'btn-primary':status==1}]" type="button"> 排序</button>
<button @click="status=1" :class="['btn',{'btn-primary':status==1}]" type="button"> 字段排序</button>
</span>
<span class="input-group-btn" style="padding-left: 10px">
@@ -47,29 +69,36 @@
<button @click="save()" :class="['btn',{'btn-primary':status!=0},{'disabled':status==0}]" type="button"> 保存</button>
</span>
</div>
<hr style="margin: 0px 5px 5px">
</div>
<!-- 实体列表 -->
<div class="col-md-3 col-xs-4">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 实体表(Meta-Table)</div>
<ul class="nav nav-tabs nav-stacked tlist" style="height: 100%">
<li :class="['clearfix',{'active':alias==item.alias}]" v-for="item in tables" >
<a @click="alias=item.alias" :title="dealTableLabel(item)" v-text="dealTableLabel(item)" href="javascript:;"></a>
</li>
</ul>
</div>
<div class="col-md-9 col-xs-8">
<!-- 实体属性列表 -->
<div class="panel" v-show="status!=7 && status!=8">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 实体字段信息</div>
<table :class="[{'table':status!=2},'table-bordered']" style="width: 100%">
<tr style="background-color: #f1f1f1">
<!-- baseInfo -->
<div class="base-info">基本属性</div>
<!--<div class="panel-heading">基本属性配置</div>-->
<table :class="['table','table-bordered']">
<tr>
<th style="width: 100px">表名</th>
<td><span class="label label-outline" title="表别名alias">{{row.alias}}</span> {{row.tablename}}</td>
<th>数据平台</th>
<td>{{dealDbPlatName(row)}}</td>
</tr>
<tr>
<th>描述</th>
<td>{{row.comment}}</td>
<td></td>
<td></td>
</tr>
</table>
<div class="base-info"> 字段信息</div>
<table :class="[{'table':status!=2},'table-bordered']">
<tr>
<td v-show="status==3 || status==4 || status==5 || status==6"><input type="checkbox"></td>
<th v-show="status==1"></th>
<th>字段</th>
<th>中文名</th>
<th></th>
<th>注释</th>
<th>数据类型</th>
<!--
<th>输入类型</th>
@@ -80,7 +109,7 @@
</tr>
<tr v-for="(item, index) in meta.items" class="item">
<td v-show="status==1" class="icon icon-move"></td>
<td v-show="status!=2" v-text="item.name" style="background-color: rgb(235, 235, 228);"></td>
<td v-show="status!=2" v-text="item.name"></td>
<td v-show="status!=2" v-text="item.label"></td>
<td v-show="status!=2" v-text="item.type"></td>
<!--
@@ -128,23 +157,25 @@
<!-- baseInfo -->
<div class="panel" v-show="status==7 ">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 基本属性配置</div>
<div class="base-info"> 基本属性配置</div>
<!--<div class="panel-heading">基本属性配置</div>-->
<div class="panel-body" style="overflow:auto;">
<form class="form-horizontal">
<input type="hidden" v-model="row.key">
<div class="form-group">
<label for="name" class="col-md-2">Table名称</label>
<div class="col-md-4 col-sm-8">
<input v-model="row.name" class="form-control" id="name" placeholder="请输入Table名称">
</div>
<label for="name" class="col-md-2">表别名</label>
<div class="col-md-3 col-sm-2">
<div class="col-sm-4">
<input v-model="row.alias" class="form-control" readonly>
</div>
</div>
<div class="form-group">
<label for="comment" class="col-md-2">Table标题</label>
<label for="name" class="col-md-2">表名</label>
<div class="col-md-4 col-sm-8">
<input v-model="row.tablename" class="form-control" id="name" placeholder="请输入Table名称">
</div>
</div>
<div class="form-group">
<label for="comment" class="col-md-2">描述</label>
<div class="col-md-4 col-sm-8">
<input v-model="row.comment" class="form-control" id="comment" placeholder="请输入 Table标题">
</div>
@@ -152,13 +183,13 @@
<div class="form-group">
<label class="col-md-2">数据平台</label>
<div class="col-md-4 col-sm-8">
<select v-model="row.dbPlatId" class="form-control">
<div class="col-sm-2">
<select v-model="row.dbid" class="form-control">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
<option v-for="item in dbPlats" :value="item.dbid" v-text="item.dbname"></option>
</select>
</div>
<div class="col-md-4">
<div class="col-sm-2">
<select v-model="row.catalog" class="form-control">
<option></option>
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
@@ -170,12 +201,12 @@
</div>
<div class="panel" v-show="status==8">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 实体关系</div>
<div class="base-info"> 实体关系</div>
<p style="padding: 5px">整理中,【实体关系】放到此处维护</p>
</div>
<textarea class="form-control layui-code" v-model="upsql" rows="10" id="content" placeholder="/* 没有提交要执行的查询 */" />
<textarea class="form-control layui-code" v-if="upsql" v-model="upsql" rows="10" id="content" placeholder="/* 没有提交要执行的查询 */" />
</div>
<div class="col-md-10">
@@ -192,6 +223,7 @@
let vm = new Vue({
el: ".meta-list",
data: {
cfg: {"title": "实体管理"},
inTypes: ["INPUT", "SELECT_EXT", "INPUT_DT", "FMT_FUN", "FILE"],
dataTypes: ["bigint(20)", "varchar(255)", "varchar(64)", "varchar(32)", "varchar(16)", "int(11)", "int(3)", "int(2)", "datetime"],
filterCate: ["EQUAL", "NOTEQUAL", "LIKE", "IN"],
@@ -211,14 +243,16 @@
itemEdit: {}, //待修改的字段属性
dbPlats:[],
row: {key: "", platId: "", dbPlatId:"", catalog: "", name:"", comment:"", alias: ""},
row: {tableid: "", platid: "", dbid:"", catalog: "", tablename:"", comment:"", alias: ""},
filter: {db: "", catalog: "", name: ""},//tableList 过滤条件
upsql: "", // 需要执行的 sql语句
filter: "",
},
watch: {
metaTable(v) {
this.name = v.name
this.tablename = v.tablename
this.alias = v.alias
},
status: function (v) {
@@ -266,11 +300,11 @@
handler: function (row) {
//console.log(vm.metaTable.name, " -> ",v.name)
vm.upsql = ''
if (vm.metaTable.name != row.name) {
vm.upsql += 'RENAME TABLE `{0}`.`{1}` TO `{2}`.`{3}`;\n'.format(vm.metaTable.catalog, vm.metaTable.name, vm.metaTable.catalog, row.name)
if (vm.metaTable.tablename !== row.tablename) {
vm.upsql += 'RENAME TABLE `{0}`.`{1}` TO `{2}`.`{3}`;\n'.format(vm.metaTable.catalog, vm.metaTable.tablename, vm.metaTable.catalog, row.tablename)
}
if (vm.metaTable.comment != row.comment) {
vm.upsql += 'ALTER TABLE `{0}`.`{1}` COMMENT=\'{2}\';\n'.format(vm.metaTable.catalog, vm.metaTable.name, row.comment)
if (vm.metaTable.comment !== row.comment) {
vm.upsql += 'ALTER TABLE `{0}`.`{1}` COMMENT=\'{2}\';\n'.format(vm.metaTable.catalog, vm.metaTable.tablename, row.comment)
}
},
deep: true
@@ -288,7 +322,7 @@
deep: true
},
meta: function (v) {
this.row = {key:v.key, dbPlatId: v.dbPlatId, catalog: v.catalog, name:v.name, comment:v.comment, alias: v.alias};
this.row = {tableid:v.tableid, dbid: v.dbid, catalog: v.catalog, tablename:v.tablename, comment:v.comment, alias: v.alias};
let oldItems = v['items'] || []
this.oldItems = JSON.parse(JSON.stringify(oldItems))
},
@@ -315,7 +349,7 @@
catalogs: function() {
let dbPlats = this.dbPlats;
for (i in dbPlats) {
if (dbPlats[i].key == this.row.dbPlatId) {
if (dbPlats[i].dbid === this.row.dbid) {
return dbPlats[i]["catalogs"]
}
}
@@ -450,7 +484,15 @@
},
dealTableLabel(table) {
// (${table.linkCount})
return `${table.name} [${table.comment}]`
return `${table.tablename} [${table.comment}]`
},
dealFilter(table) {
// table.name 中是否包含 thiss.filter 的值
if (table.tablename.indexOf(this.filter) > -1 || table.comment.indexOf(this.filter) > -1) {
return true
} else {
return false
}
},
getFieldLabel (col) {
if (!col) {
@@ -470,6 +512,16 @@
},
buildSql() {
},
dealDbPlatName(row) {
let name = ""
this.dbPlats.forEach(function (item) {
if (item.dbid === row.dbid) {
name = item.dbname
}
})
name += "." + row.catalog
return name
}
},
mounted: function (){
@@ -478,11 +530,13 @@
})
this.tableList();
/*setTimeout(function () {
layui.use('code', function(){ //加载code模块
setTimeout(function () {
/*layui.use('code', function(){ //加载code模块
layui.code({title:"",about: false, height: "500"}); //引用code方法
});
}, 300)*/
});*/
// 手动初始化工具提示
$('[data-toggle="tooltip"]').tooltip();
}, 300)
}
});
</script>

View File

@@ -108,7 +108,7 @@
<h4 class="modal-title">功能概览</h4>
</div>
<div class="modal-body" style="text-align: center">
<table class="table-bordered" style="width: 100%">
<table class="table-bordered">
<tr>
<th v-text="tableA.comment"></th>
<th v-text="tableB.comment"></th>

198
root/oth/ddlCompare.html Normal file
View File

@@ -0,0 +1,198 @@
<row class="oth">
<!-- head -->
<!--<div class="col-md-2">
&lt;!&ndash;<h3 v-text="cfg.title"></h3>&ndash;&gt;
</div>-->
<div class="col-xs-2 sheet-cell">
数据源A
<select></select>
<select></select>
<br>
数据源B
<select></select>
<select></select>
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 实体表(Meta-Table)</div>
<!-- 创建一个空的树,需要包含 .tree CLASS -->
<ul class="tree tree-lines tree-angles" id="myTree" data-ride="tree"></ul>
</div>
<div class="col-md-10">
<div class="input-group pull-right" style="padding-top: 10px">
<a>HAO</a>
</div>
</div>
<div class="col-md-5">
<table class="table table-auto">
<tr>
<th>字段</th>
<th>备注</th>
<th>数据类型</th>
<th>默认值</th>
<th>可空</th>
</tr>
<tr>
<td>file_download_num</td>
<td>下载次数</td>
<td>int(11)</td>
<td>0</td>
<td>YES</td>
</tr>
<tr>
<td>xx</td>
<td>xx</td>
<td>xx</td>
<td>xx</td>
<td>xx</td>
</tr>
</table>
</div>
<div class="col-md-5">
<table class="table table-auto">
<tr>
<th>字段</th>
<th>备注</th>
<th>数据类型</th>
<th>默认值</th>
<th>可空</th>
</tr>
<tr>
<td>file_download_num</td>
<td>下载次数</td>
<td>int(11)</td>
<td>0</td>
<td>YES</td>
</tr>
<tr>
<td>xx</td>
<td>xx</td>
<td>xx</td>
<td>xx</td>
<td>xx</td>
</tr>
</table>
</div>
<!-- edit.modal -->
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<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">
<form class="form-horizontal">
<div class="form-group">
<label for="queryId" class="col-md-2 required">选择用户</label>
<div class="col-md-8">
<input v-model="row.name" class="form-control" id="queryId" placeholder="请输入 平台名称">
</div>
</div>
<div class="form-group">
<label for="token" class="col-md-2 required">平台 Token</label>
<div class="col-md-8 col-sm-10">
<input v-model="row.token" class="form-control" id="token" placeholder="请输入 Token">
</div>
</div>
<div class="form-group">
<label for="remark" class="col-md-2">备注</label>
<div class="col-md-8 col-sm-10">
<input v-model="row.remark" class="form-control" id="remark" placeholder="请输入 备注">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button @click="save(row)" type="button" class="btn btn-primary">确定</button>
</div>
</div>
</div>
</div>
</row>
<script>
var myTreeData = [{"title":"ck","path":"","children":[{"title":"ck.go","path":"D:/wk/_own/go-demo/_hello/ck","children":null},{"title":"ck_test.go","path":"D:/wk/_own/go-demo/_hello/ck","children":null}]},{"title":"cmd","path":"","children":[{"title":"cmd_demo.go","path":"D:/wk/_own/go-demo/_hello/cmd","children":null},{"title":"pack.bat","path":"D:/wk/_own/go-demo/_hello/cmd","children":null},{"title":"pack_linux.bat","path":"D:/wk/_own/go-demo/_hello/cmd","children":null},{"title":"upx.exe","path":"D:/wk/_own/go-demo/_hello/cmd","children":null}]},{"title":"dev-kit","path":"","children":[{"title":"dev_kit.go","path":"D:/wk/_own/go-demo/_hello/dev-kit","children":null}]},{"title":"file-io","path":"","children":[{"title":"file_kit.go","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"file_kit_test.go","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"file_read_test.go","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"file_write_test.go","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"pub.txt","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"test.txt","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"test1.txt","path":"D:/wk/_own/go-demo/_hello/file-io","children":null},{"title":"test2.txt","path":"D:/wk/_own/go-demo/_hello/file-io","children":null}]},{"title":"goroutine","path":"","children":[{"title":"gotoutine_test.go","path":"D:/wk/_own/go-demo/_hello/goroutine","children":null},{"title":"pool_test.go","path":"D:/wk/_own/go-demo/_hello/goroutine","children":null}]},{"title":"interface","path":"","children":[{"title":"interface_test.go","path":"D:/wk/_own/go-demo/_hello/interface","children":null}]},{"title":"net","path":"","children":[{"title":"net-x","path":"","children":[{"title":"UserController.go","path":"D:/wk/_own/go-demo/_hello/net/net-x","children":null},{"title":"a.go","path":"D:/wk/_own/go-demo/_hello/net/net-x","children":null}]},{"title":"net-demo.go","path":"D:/wk/_own/go-demo/_hello/net","children":null},{"title":"net_x.go","path":"D:/wk/_own/go-demo/_hello/net","children":null}]},{"title":"pulsar","path":"","children":[{"title":"pulsar_test.go","path":"D:/wk/_own/go-demo/_hello/pulsar","children":null}]},{"title":"struct","path":"","children":[{"title":"struct-demo.go","path":"D:/wk/_own/go-demo/_hello/struct","children":null}]},{"title":"timer","path":"","children":[{"title":"timer_test.go","path":"D:/wk/_own/go-demo/_hello/timer","children":null}]},{"title":"hello_test.go","path":"D:/wk/_own/go-demo/_hello","children":null}]
let { platList, platSave } = plat
let { filetoken } = tmp
var vm = new Vue({
el: ".oth",
data: {
cfg: {
title: "业务平台 管理",
cols: [
{col: "name", label: "业务名称"},
{col: "token", label: "Token"},
{col: "remark", label: "说明"},
{col: "status", label: "状态", fmt: function (v) {
return {"0":"未启用", "1":"启用", "-1":"删除"}[v] || "";
}},
],
filters: []
},
list: {rows:[], total: 0},
row: {},
content:"",
token: "x"
},
watch: {
},
methods: {
findList () {
platList().then(res => {
vm.list = res
})
},
update: function (kv, row) {
red.post("/meta/save", {
_id: row._id,
doc: JSON.stringify(kv)
}, function (json) {
red.showMsg();
red.putAll(row, kv);
vm.findList();
});
},
edit: function (row) {
vm.row = row;
console.log(this.row);
$('#myModal').modal({moveable: true});
},
save: function (row) {
platSave({plat: row}).then(() => {
red.showMsg({msg: "操作成功"})
$('#myModal').modal('hide')
})
}
},
mounted: function () {
this.findList();
$('#myTree').tree({
data: myTreeData
,itemCreator: function($li, item) {
$li.append($('<a/>', {href: item.url, click: ()=>{
console.log(item.title)
vm.content = item.title
}}).text(item.title));
// return false; // 如果要忽略当前节点,可以通过返回 false 来实现
}
});
filetoken().then(res => {
this.token = res[0]
console.log(this.token)
})
}
});
</script>

View File

@@ -16,7 +16,7 @@
<div class="col-md-12">
<button @click="edit({})" class="btn btn-primary" type="button"> 用户金币发放 </button>
<!--<table class="table table-bordered table-hover" style="width: 100%">
<!--<table class="table table-bordered table-hover">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>

View File

@@ -1,4 +1,9 @@
<row class="plat">
<!-- head -->
<div class="col-md-12" style="margin-bottom: 5px">
<h3 v-text="cfg.title" class="pull-left"></h3>
<button @click="edit({})" class="btn btn-primary pull-right" type="button"> 新增数据平台 </button>
</div>
<div class="info">
<a @click="showInfo()" href="javascript:;"><i class="icon icon-info"></i></a>
@@ -30,20 +35,8 @@
</div>
</div>
<!-- head -->
<div class="col-md-11">
<h3 v-text="cfg.title"></h3>
</div>
<div class="col-md-1">
<div class="input-group pull-right" style="padding-top: 10px">
<span class="input-group-btn">
<button @click="edit({})" class="btn btn-primary" type="button"> 新增数据平台 </button>
</span>
</div>
</div>
<div class="col-md-12">
<table class="table table-bordered table-hover" style="width: 100%">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -81,7 +74,7 @@
<div class="form-group">
<label for="queryId" class="col-sm-2 required">平台名称</label>
<div class="col-md-6 col-sm-10">
<input v-model="row.name" class="form-control" id="queryId" placeholder="请输入 平台名称">
<input v-model="row.dbname" class="form-control" id="queryId" placeholder="请输入 平台名称">
</div>
</div>
<div class="form-group">
@@ -111,7 +104,7 @@
<input v-model="row.pwd" class="form-control" id="pwd" placeholder="连接密码">
</div>
<div class="col-md-2">
<a @click="loadCatalogs" class="btn" href="javascript:;">获取catalogs</a>
<a @click="loadCatalogs" class="btn btn-default" href="javascript:;">获取catalogs</a>
</div>
</div>
<div class="form-group">
@@ -149,9 +142,9 @@
el: ".plat",
data: {
cfg: {
title: "数据中心 管理",
title: "数据 管理",
cols: [
{col: "name", label: "数据平台名称"},
{col: "dbname", label: "数据平台名称"},
{col: "url", label: "数据平台连接地址"},
{col: "user", label: "用户"},
{col: "remark", label: "备注"},
@@ -222,7 +215,7 @@
loadCatalogs: function () {
vm.catalogs = [];
//let [cate, url, user, pwd] = this.row
let dbAccount = {key: '',cate:'', url:'', user:'', pwd:''}
let dbAccount = {dbid: '',cate:'', url:'', user:'', pwd:''}
for (let key in dbAccount) {
dbAccount[key] = this.row[key]
}
@@ -233,7 +226,7 @@
dbPulse: function (row) {
/*row["check"] = true;
$.getJSON("/_db/pulse", {
dbPlatId: row._id
dbid: row._id
}, function (json) {
row["pulse"] = json.body;
row["check"] = false;

View File

@@ -1,19 +1,12 @@
<row class="plat">
<!-- head -->
<div class="col-md-11">
<h3 v-text="cfg.title"></h3>
</div>
<div class="col-md-1">
<div class="input-group pull-right" style="padding-top: 10px">
<span class="input-group-btn">
<button @click="edit({})" class="btn btn-primary" type="button"> 新增业务平台 </button>
</span>
</div>
<div class="col-md-12" style="margin-bottom: 5px">
<h3 v-text="cfg.title" class="pull-left"></h3>
<button @click="edit({})" class="btn btn-primary pull-right" type="button"> 新增业务平台 </button>
</div>
<div class="col-md-12">
<table class="table table-bordered table-hover" style="width: 100%">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -48,13 +41,13 @@
<div class="form-group">
<label for="queryId" class="col-md-2 required">平台名称</label>
<div class="col-md-8">
<input v-model="row.name" class="form-control" id="queryId" placeholder="请输入 平台名称">
<input v-model="row.platname" class="form-control" id="queryId" placeholder="请输入 平台名称">
</div>
</div>
<div class="form-group">
<label for="token" class="col-md-2 required">平台 Token</label>
<div class="col-md-8 col-sm-10">
<input v-model="row.token" class="form-control" id="token" placeholder="请输入 Token">
<input v-model="row.plattoken" class="form-control" id="token" placeholder="请输入 Token">
</div>
</div>
@@ -82,10 +75,10 @@
el: ".plat",
data: {
cfg: {
title: "业务平台 管理",
title: "应用平台 管理",
cols: [
{col: "name", label: "业务名称"},
{col: "token", label: "Token"},
{col: "platname", label: "业务名称"},
{col: "plattoken", label: "Token"},
{col: "remark", label: "说明"},
{col: "status", label: "状态", fmt: function (v) {
return {"0":"未启用", "1":"启用", "-1":"删除"}[v] || "";

View File

@@ -50,7 +50,7 @@
<div class="col-md-6" v-show="logs.total">
<h3>最近使用记录 <small>共 {{logs.total}} 条记录</small></h3>
<table class="table-bordered" style="width: 100%">
<table class="table-bordered">
<thead>
<tr>
<th>IP</th>

View File

@@ -5,7 +5,7 @@
<div class="col-xs-6">
<div class="input-group">
<span class="input-group-btn">
<a href="javascript:;" class="btn" type="button"> 选择QTask任务</a>
<a class="btn btn-default" type="button"> 选择QTask任务</a>
</span>
<select class="form-control" v-model="row">
<option v-for="item in list.rows" :value="item" v-text="`${item.name}--${item.title}`"></option>
@@ -26,7 +26,7 @@
<div class="form-group">
<label for="para" class="col-sm-2 required">数据平台</label>
<div class="col-md-6">
<select v-model="row.dbPlatId" class="form-control">
<select v-model="row.dbid" class="form-control">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
</select>
@@ -87,7 +87,7 @@
catalogs: function () {
let dbPlats = this.dbPlats;
for (i in dbPlats) {
if (dbPlats[i].key == this.row.dbPlatId) {
if (dbPlats[i].key == this.row.dbid) {
return dbPlats[i]["catalogs"]
}
}
@@ -104,7 +104,7 @@
dbList().then(res => {
this.dbPlats = res.rows;
})
qtaskList().then(res => {
qtaskList({}).then(res => {
let list = res
if(list && list.rows.length > 0) {

View File

@@ -1,28 +1,45 @@
<style>
.edit {
table {
border-collapse: collapse;
thead {
text-align: center;
/*th {
background-color: #c3deff;
}*/
}
th {
vertical-align: middle;
}
}
/*input,textarea,select {
border-top: 0;
border-right: 0;
!*border-left: 2px!important;*!
border-bottom: 0;
!*background-color: #DDF3F5;*!
}*/
textarea {
width: 100%;
}
.tpl-debug>pre{
background-color: #F1F1F1;
border-top: 0;
border-right: 0;
border-bottom: 0;
}
}
</style>
<row class="qtask-list">
<div class="col-md-12">
<div class="col-md-12" style="margin-bottom: 10px">
<h3 v-text="cfg.title"></h3>
<button @click="openDia({'x':1})" class="btn btn-primary" type="button"> 添加QTask</button>
</div>
<div class="col-md-12 ">
<!--<div class="col-md-2" style="padding-left: 0">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button">选择业务平台</button>
</span>
<select class="form-control">
<option>sdfa</option>
<option>sadf</option>
</select>
</div>
</div>-->
<div class="input-group pull-right">
<button @click="openDia({})" class="btn btn-primary" type="button"> 添加QTask</button>
<!--<button @click="openDia({})" class="btn btn-primary" type="button" style="margin-left: 5px"> 添加QTask</button>-->
</div>
</div>
<div class="col-md-12" style="padding-top: 10px;overflow:auto;">
<table class="table table-bordered table-hover" style="width: 100%">
<div class="col-md-5" style="">
<ul id="treeDemo" class="ztree" style="display: none"></ul>
<table class="table table-bordered tlist" style="width: 100%; ">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -30,12 +47,14 @@
</tr>
</thead>
<tbody>
<tr v-for="row in list.rows">
<tr v-for="row in list.rows" @click="openDia(row)" :class="{'active': row.name == _row.name}">
<td v-for="field in cfg.cols" v-title="row[field.col]" v-text="row[field.col]"></td>
<td>
<a @click="openDia(row)" href="javascript:;">编辑</a>|
<a @click="openDia(row)" href="javascript:;">编辑</a> |
<!--
<a @click="row['status']=1;qsave(row);" v-show="row.status != 1" href="javascript:;">启用</a>
<a @click="row['status']=0;qsave(row);" v-show="row.status == 1" href="javascript:;">不启用</a> |
-->
<a @click="row['status']=-1;comfirmDel(row);" href="javascript:;">删除</a>
</td>
</tr>
@@ -46,14 +65,164 @@
<img src="../res/img/none.png">
<p>暂无数据</p>
</div>
<!-- 分页 -->
<div>
<ul class="pager pull-right">
<li class="previous">
<a >共{{list.total}}条数据</a>
</li>
<li :class="['previous', {'disabled':limit.pn==1}]">
<a @click="loadList(-- limit.pn)" href="javascript:"><i class="icon icon-angle-left"></i>上一页</a>
</li>
<li :class="['next', {'disabled':limit.pn >= limit.total}]">
<a @click="loadList(limit.pn = ++limit.pn )" href="javascript:">下一页<i class="icon icon-angle-right"></i></a>
</li>
<li class="previous">
<a>到第<input v-model="limit.pn" style="width: 30px;height: 20px;margin: 0">/ {{limit.total}}页</a>
</li>
<li class="previous">
<a @click="loadList(limit.pn)" href="javascript:;">确定</a>
</li>
</ul>
</div>
</div>
<div class="col-md-7 edit" style="padding-top: 0px;">
<table v-show="editStatus==1" class="table table-bordered">
<thead>
<tr>
<th colspan="4">
<h5 class="pull-left">【任务编辑】</h5>
<!--全屏打开按钮-->
<!--<a @click="fullScreen()" href="javascript:" class="pull-right" style="margin: 5px; font-size: 18px">
<i class="icon icon-fullscreen"></i>
</a>-->
</th>
</tr>
</thead>
<tr>
<th style="width: 120px">任务名称</th>
<td>
<input v-model="row.title" class="form-control">
</td>
<th>数据平台</th>
<td>
<select v-model="row.dbid" class="form-control">
<option v-for="item in dbPlats" :value="item.dbid" v-text="item.dbname"></option>
</select>
</td>
</tr>
<tr>
<th>任务KEY</th>
<td>
<input v-model="row.name" class="form-control">
</td>
<th style="width: 120px">CataLog</th>
<td>
<select v-model="row.catalog" class="form-control">
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
</select>
</td>
<!--<td colspan="3">
<div class="col-xs-6" style="padding: 0;">
<select v-model="row.dbplatid" class="form-control" style="background-color: #f2f4f9">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
</select>
</div>
<div class="col-xs-4">
<select v-model="row.catalog" class="form-control" style="background-color: #f2f4f9">
<option></option>
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
</select>
</div>
</td>-->
</tr>
<tr>
<th>执行模板</th>
<td colspan="3" class="tpl-content">
<textarea v-model="row.content" @change="parsePara(row)" rows="6" class="pre-scrollable form-control"></textarea>
</td>
</tr>
<tr>
<th>默认参数</th>
<td colspan="3" class="tpl-para">
<textarea rows="1" v-model="row.para" class="form-control"></textarea>
</td>
</tr>
<tr>
<th>备注</th>
<td colspan="3" class="tpl-remark">
<textarea rows="1" v-model="row.remark" class="form-control"></textarea>
</td>
</tr>
<tr>
<th>操作</th>
<td colspan="3">
<div class="pull-right">
<button @click="debug()" type="button" class="btn btn-primary" style="margin-right: 20px">
<i class="icon icon-bug"> 调试</i></button>
<button @click="openDia({})" type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button @click="reset(row.name)" type="button" class="btn btn-default" data-dismiss="modal">重置</button>
<button @click="save()" type="button" class="btn btn-primary">
<i class="icon icon-save"> 保存</i></button>
</div>
</td>
</tr>
<tr>
<td colspan="4"></td>
</tr>
<tr>
<th colspan="4" style="text-align: center">
调试结果
<div class="pull-right">
<button @click="copyToClipboard(debugRet)" class="btn btn-default btn-mini"
title="拷贝调试结果"><i
class="icon icon-copy"></i></button>
<button @click="debugView ='JSON'" class="btn btn-default btn-mini" title="展示JSON"><i
class="icon icon-code"></i></button>
<button @click="debugView ='TABLE'" class="btn btn-default btn-mini" title="展示表格"><i
class="icon icon-table"></i></button>
</div>
</th>
</tr>
<tr>
<td colspan="4" class="tpl-debug" style="padding: 0">
<pre class="pre-scrollable"
v-if="debugView === 'JSON' || !(debugData.header && debugData.header.length)">{{debugRet}}<p
v-if="!debugRet" class="text-muted">暂无调试信息</p></pre>
<table v-if="debugView === 'TABLE' && (debugData.header && debugData.header.length)"
style="width: 100%;overflow: auto;">
<tr>
<th v-for="item in debugData.header">{{item}}</th>
</tr>
<tr v-for="item in debugData.list">
<td v-for="i in debugData.header">{{item[i]}}</td>
</tr>
<!--<tr>
<td colspan="{{debugData.header.length}}" class="pull-right">
{{debugData.total}}
</td>
</tr>-->
</table>
</td>
</tr>
</table>
<div v-show="editStatus!=1" style="text-align: center">
<img src="../res/img/none.png">
<p>暂无数据</p>
</div>
</div>
<!-- modal-tpl -->
<div class="col-md-12">
<!-- 对话框触发按钮 -->
<!-- 对话框HTML -->
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<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>
@@ -70,7 +239,7 @@
<div class="form-group">
<label class="col-sm-2 required">任务标识码</label>
<div class="col-md-6 col-sm-10">
<input v-model="row.name" :readonly="row.key" class="form-control" placeholder="请输入 任务标识码">
<input v-model="row.name" :disabled="row.qtaskid" :readonly="row.key" class="form-control" placeholder="请输入 任务标识码">
</div>
</div>
<div class="form-group" style="margin-bottom: 0">
@@ -87,13 +256,13 @@
</div>
<div class="form-group">
<label for="para" class="col-sm-2 required">数据平台</label>
<div class="col-md-6">
<select v-model="row.dbPlatId" class="form-control">
<div class="col-xs-6">
<select v-model="row.dbid" class="form-control">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
<option v-for="item in dbPlats" :value="item.dbid" v-text="item.dbname"></option>
</select>
</div>
<div class="col-md-4">
<div class="col-xs-4">
<select v-model="row.catalog" class="form-control">
<option></option>
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
@@ -126,7 +295,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button @click="save()" type="button" class="btn btn-primary">确定</button>
<button @click="del()" type="button" class="btn btn-primary">确定</button>
</div>
</div>
</div>
@@ -134,9 +303,21 @@
</row>
<script src="http://www.1216.top/res/layui/layui.js"></script>
<script>
let {qtaskList,qtaskSave} = qtask
//let {qtaskList, qtaskSave, qtaskDelete} = qtask
let {dbList} = plat
function beforeDrag(treeId, treeNodes) {
for (let i=0,l=treeNodes.length; i<l; i++) {
if (treeNodes[i].drag === false) {
return false;
}
}
return true;
}
function beforeDrop(treeId, treeNodes, targetNode, moveType) {
return targetNode ? targetNode.drop !== false : true;
}
var vm = new Vue({
el: ".qtask-list",
data: {
@@ -144,6 +325,7 @@
cfg: {
title: "QTask 管理",
cols: [
{col: "qtaskid", label: "#",},
{col: "name", label: "任务标识码",},
{col: "title", label: "任务名称",},
{col: "remark", label: "备注",},
@@ -152,60 +334,211 @@
cates: ["find","update"]
},
list: {rows:[], total: 0},
row: {},
limit: {pn: 1, ps: 20, total: 0},
row: {name:"",content:"", remark:"", para:"", x:""},
_row: {name:"",content:"", remark:""},
dbPlats: [],
sysPlats: [{name: "工控系统"}]
sysPlats: [{name: "工控系统"}],
editStatus: 0,
debugRet: "",
debugData: "",
debugView: "TABLE", // 0:TABLE, 1:SQL, 3:JSON
// ZTree
setting : {
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false
},
data: {
simpleData: {
enable: true
}
},
callback: {
beforeDrag: beforeDrag,
beforeDrop: beforeDrop
}
}
},
watch: {
},
methods: {
loadList: function () {
qtaskList().then(res => {
let list = res
this.list = list
})
},
openDia: function (row) {
vm.row = row;
$('#myModal').modal({moveable: true});
if (this.dbPlats.length == 0) {
row: function (row) {
if (row.name || row.x) {
vm.editStatus = 1
} else {
vm.editStatus = 0
}
if (this.dbPlats.length === 0) {
dbList().then(res => {
this.dbPlats = res.rows;
})
}
this.debugRet = ""
this.debugData = ""
$(".tpl-content>textarea").attr("rows", this.countLines(row.content))
$(".tpl-remark>textarea").attr("rows", this.countLines(row.remark, 2, 5))
}
},
methods: {
loadList: function (pn = 1, x = '') {
let limit = this.limit.ps
let offset = (pn - 1) * limit
qtask.qtaskList({flipper: {offset, limit}}).then(res => {
this.list = res
// 如果页面初次打开,则默认打开第一条记录
if (x === 'OPEN' && res.rows.length > 0) {
vm.openDia(res.rows[0])
}
let zNodes = [
{id: 1, pId: 0, name: "qtask 任务", open: true},
/*{id: 11, pId: 1, name: "随意拖拽 1-1"},
{id: 12, pId: 1, name: "随意拖拽 1-2", open: true},*/
];
for (let i in res.rows) {
let row = res.rows[i]
zNodes.push({id: row.qtaskid, pId: "1", name: row.title + '-(' + row.name+')'})
}
$.fn.zTree.init($("#treeDemo"), this.setting, zNodes);
this.limit.total = Math.ceil(this.list.total / limit)
})
},
openDia(row) {
vm.row = red.deepClone(row);
vm._row = red.deepClone(row);
vm.editStatus = 1
/*$('#myModal').modal({moveable: true});
if (this.dbPlats.length === 0) {
dbList().then(res => {
this.dbPlats = res.rows;
})
}*/
this.parsePara(row)
},
fullScreen(row) {
$('#myModal').modal({moveable: true})
},
save() {
qtaskSave({task:this.row}).then(res => {
qtask.qtaskSave(this.row).then(res => {
red.showOk()
red.wait(1000).then(() => {
this.loadList()
$('#myModal').modal('hide')
this.row = {}
// this.row = {}
// $('#myModal').modal('hide')
})
})
},
dealStatus: function (n) {
var arr = {"0":"未启用", "1":"启用", "-1":"删除",}
return arr[n+""] || "";
},
comfirmDel: function (row) {
vm.row = row;
$('#mySmModal').modal({});
},
del: function () {
qtask.qtaskDelete(this.row.qtaskid).then(res => {
$('#mySmModal').modal('hide')
this.loadList()
})
},
abc: function () {
$(".container-fixed").load("abc.html");
},
catalogs: function () {
let dbPlats = this.dbPlats;
for (i in dbPlats) {
if (dbPlats[i].key == this.row.dbPlatId) {
if (dbPlats[i].dbid === this.row.dbid) {
return dbPlats[i]["catalogs"]
}
}
},
debug: function () {
qtask.qtaskDebug({task: this.row}).then(res => {
this.debugRet = res;
red.showOk("查询成功")
this.parseDebugRet(res)
})
},
countLines: function (text='', min=3, max=15) {
// 计算"\n"和"\r\n"两种换行符的数量
let line = (text.match(/\n/g) || []).length + (text.match(/\r\n/g) || []).length + 1
if (line < 3) {
line = min;
}
if (line > 15) {
line = max;
}
return line; // 最后+1是因为可能末尾没有换行符但仍然算一行
},
reset: function () {
this.row = red.deepClone(vm._row)
},
parsePara(row) {
let sql = row.content || ''
let pattern = /#\((.*?)\)/g; // 创建一个正则表达式来查找 "#()" 内的任何内容
let match;
let para = JSON.parse(row.para)
let _para = {}
while ((match = pattern.exec(sql)) !== null) {
// console.log("提取的变量:", match[1]); // match[1] 存储的是第一个括号内捕获的内容
_para[match[1]] = para[match[1]] || ''
}
this.row.para = JSON.stringify(_para)
},
parseDebugRet(_res) {
let res = red.deepClone(_res)
if (res.list && res.list.length > 0) {
let header = []
for (let key in res.list[0]) {
header.push(key)
}
res['header'] = header
this.debugData = res
return
}
if (!res.total && res instanceof Object) {
let header = []
let _res = {}
for (let key in res) {
header.push(key)
}
// _res = {header: header, total: 1, list: [res]}
res['header'] = header
res['list'] = [res]
this.debugData = res
return
}
this.debugData = res
},
copyToClipboard(text) {
if (!navigator.clipboard) {
console.error("Clipboard API not supported.");
return;
}
let _text = text
if (typeof text !== 'string') {
_text = JSON.stringify(text)
}
navigator.clipboard.writeText(_text)
.then(() => {
red.showOk("调试结果已拷贝到剪贴板")
})
.catch(error => {
console.error("Failed to copy text:", error);
});
}
},
mounted: function () {
this.loadList();
this.loadList(1, 'OPEN');
setTimeout(function () {
layui.use('code', function(){ //加载code模块

View File

@@ -10,7 +10,7 @@ body {
}
#top {
background-color: #404a53;
background-color: #2B323BFF;
padding: 5px 10px;
margin: 0px;
height: 50px;
@@ -31,13 +31,13 @@ body {
#top>.nav-tabs>li.active>a:hover,
#top>.nav-tabs>li>a:hover {
background-color: #404a53;
color: #fff;
/*color: #fff;*/
border: 0;
border-bottom: 3px solid #607d8b;
}
#left {
background-color: #404a53; /*padding-bottom: 0px; margin-bottom: 0px;*/
background-color: #2B323BFF;
}
#main {
margin-top: 15px;
@@ -51,7 +51,7 @@ body {
/*background-color: #fff;*/
}
#left .nav {
background-color: #404a53;
background-color: #2B323BFF;
}
#left .menu > .nav > li > .nav > li > a {
@@ -83,20 +83,23 @@ body {
width: 150px;
font-size: 22px;
}
.footer{
.footer,.main-footer {
position: fixed;
bottom: 0;
margin-left: -10px;
width: 100%;
height: 35px;
background-color: #eee;
padding: 8px;
width: 100%;
color: #808080;
padding: 8px;
}
.main-footer {
/*background-color: #eee;*/
/*left: 50px;*/
margin-left: -10px;
}
.list-head {
/*.list-head {
padding-bottom: 10px;
}
}*/
table td,th{
white-space:nowrap;
@@ -104,9 +107,9 @@ table td,th{
text-overflow: ellipsis;
max-width: 173px;
}
th{
/*th{
background-color: #f1f1f1;
}
}*/
/*ddl-page*/
.ddl .input-group {
@@ -145,7 +148,7 @@ th{
.table td, .table th{
padding: 5px;
}
.table td {background-color: #fff;}
/*.table td {background-color: #fff;}*/
/* 页面信息按钮样式 */
#main .info {
@@ -167,13 +170,19 @@ th{
}
.tlist>li{
margin-top: 0;
/*设置不换行*/
white-space: nowrap;
/*设置高度*/
/*height: 30px;
padding: 0;*/
}
.tlist>li.active>a,
.tlist>li.active>a:focus,
.tlist>li.active>a:hover,
.tlist>li>a:hover {
background-color: #e2effc;
background-color: #404348;
border-radius: 2px 0 0 2px;
border-left: 5px solid #a5cff8;
}
/* 为可拖动的条目应用可移动光标类型 */
@@ -184,3 +193,228 @@ tr.dragging {
visibility: visible;
opacity: .3;
}
#left {
.footer {
background-color: #1b1e2461!important;
cursor: pointer;
color: #ccc;
margin: auto;
left: -1px;
z-index: 999;
}
.user {
position: fixed;
bottom: 35px;
height: 35px;
margin: auto;
background-color: #404a53;
color: #808080;
}
}
.leftMini {
#left {
width: 50px;
.icon {
font-size: 16px;
}
.footer {
margin: auto;
width: 50px;
}
}
.col-md-11 {
width: 96%!important;
}
.main-footer {
width: 100%;
}
}
.col-md-12>h3{
margin-top: 0px;
}
.base-info {
padding-left: 10px;
background-color: #ccc;
width: 100%;
}
.base-input {
margin-top: 5px;margin-bottom: 5px;height: 30px; border: 1px solid black;
}
.plat-switch {
border: 0;
background-color: #404a53!important;
color: #fff;
margin-left: -5px;
height: 35px;
}
ul.pager {
margin: -15px 0 11px 10px;
}
.meta-service {
#show,#edit,#filter,#export,#detail {
td {
input,select {
margin: -4px;
/*width: auto;*/
}
input[type="checkbox"] {
margin: 5px;
}
}
}
.icon-move {
text-align: center;
width: 35px;
}
.color-x {
color: #7771b9!important;
}
}
body,table,tr,/*th,td,*/.table-bordered,textarea,.form-control,button,pre,hr,.panel,input,checkbox,
.btn-default,.input-group-btn,.input-group,
/*.nav-tabs>li.active>a,.nav-tabs>li:focus,*/
.previous>a,.next>a,
.dlist>li>a,
.input-group-addon,
.modal-content,.modal-header,.modal-body,.modal-footer,
.base-info,.plat-switch,
/*.tlist>li.active>a,*/
.tlist>li>a,
.alert-info{
background-color: #22272e !important;
color: #c3c5c7 !important;
border-color: #9e9e9e50!important;
th {
background-color: #3b4652 !important;
color: #85878AFF!important;
}
a {
color: #7f74c4;
}
.btn-primary {
background-color: #8276c9!important;
color: #3e3a57!important;
}
.btn-primary:focus, .btn-primary:hover {
background-color: #998fd9 !important;
}
.btn {
text-shadow: none;
}
.btn-default:focus,.btn-default:hover {
border-color: #7f74c4!important;
color: #7f74c4!important;
}
.main-footer {
background-color: #404a53 !important;
}
a:focus,a:hover {
color: #fff!important;
}
.nav-tabs.nav-stacked {
border-right: 0;
ul {
li>a {
padding: 7px 15px;
border-radius: 0 25px 25px 0;
}
}
}
.base-info,H3 {
color: #85878AFF!important;
}
.nav-tabs.nav-stacked>li {
margin-right: 5px;
}
.alert-info {
background-color: #607d8b!important;
}
table {
width: 100%;
}
td,th {
border-color: #9e9e9e50!important;
}
tr.active {
background-color: #4c5960 !important;
}
.dropdown-menu {
background-color: #404a53;
}
.table tr > td.active,
.table tr > th.active,
.table tr.active > td,
.table tr.active > th {
background-color: var(--override-bg-color);
}
.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th {
background-color: var(--override-bg-color);
}
.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th {
background-color: var(--override-bg-color);
}
.nav-tabs>li>a:hover,
.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover {
color: grey;
cursor: default;
background-color: var(--override-bg-color);
border: 1px solid #4c5960;
border-bottom-color: transparent
}
.nav-tabs {
border-bottom: 1px solid #4c5960;
}
/*tr:hover {
background-color: #4c5960 !important;
}*/
.dlist li.active a, .tlist li.active a, .tlist tr.active
/*,.dlist li a:hover, .tlist li a:hover, .tlist tr:hover*/{
border-left: 5px solid #607d8b!important;
background-color: #4c5960;
}
}
.plat-switch {
border: 0;
background-color: #404a53 !important;
color: #fff;
}
#leftMiniBtn {
position: fixed;
left: 10.63%;
top: 40%;
/* 居中到容器中间*/
display: flex;
align-items: center;
justify-content: center;
width: 10px;
height: 100px;
border-radius: 0 15px 15px 0;
background-color: #404a53;
/*z-index: 9999;*/
cursor: pointer;
}
.leftMini {
#leftMiniBtn {
position: fixed;
left: 50px;
}
}

1379
root/res/css/zui-theme-x.css Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
var red = {
showMsg: function(option) {
var defOption = {msg: "操作成功", type:"info", placement: "top"};
var defOption = {msg: "操作成功", /*type:"success",*/ placement: "top"};
option = option || defOption;
for (var k in defOption) {
@@ -46,10 +46,10 @@ var red = {
location.href = "/user/login.html";
}, 2000);
}*/
return plat["token"];
return plat["plattoken"];
},
getJSON: function (url, params = {}, callback) {
params["platToken"] = red.getPlatToken()
params["plattoken"] = red.getPlatToken()
axios.get(url, {params}).then(res => {
let data = res.data || {}
red.loginCheck(data)
@@ -63,9 +63,69 @@ var red = {
callback(data)
})
},
get2(url, params = {}) {
return new Promise(resolve => {
// 创建一个包含自定义 headers 的配置对象
const config = {
method: 'get', // 指定请求方法为 GET
url: url, // 指定请求的 URL
headers: { // 设置 Header 参数
//'Authorization': 'Bearer your-token', // 假设添加一个 Bearer 认证 token
//'Content-Type': 'application/json', // 或者指定 Content-Type 等其他 Header
//'Custom-Header': 'Some value' // 自定义 Header 参数
'token': red.getData("token"),
'plattoken': red.getPlatToken(),
},
params: params,
};
axios.request(config).then(res => {
// 未登录,前往登录
if (res.data.retcode === -2) {
location.href = "/user/login.html"
}
resolve(res.data.result)
}).catch(error => {
console.error(error); // 处理错误
});
})
},
post2(url, params = {}) {
return new Promise(resolve => {
// 创建一个包含自定义 headers 的配置对象
const config = {
method: 'post', // 指定请求方法为 GET
url: url, // 指定请求的 URL
data: params,
headers: { // 设置 Header 参数
//'Authorization': 'Bearer your-token', // 假设添加一个 Bearer 认证 token
//'Content-Type': 'application/json', // 或者指定 Content-Type 等其他 Header
//'Custom-Header': 'Some value' // 自定义 Header 参数
'token': red.getData("token"),
'plattoken': red.getPlatToken(),
}
};
axios.request(config).then(res => {
// 未登录,前往登录
if (res.data.retcode === -2) {
location.href = "/user/login.html"
}
if (res.data.retcode !== 0) {
//console.log(res)
red.showError(res.data.retinfo)
return
}
resolve(res.data.result)
}).catch(error => {
console.error(error); // 处理错误
});
})
},
getX(url, params = {}) {
if (!params['platToken'])
params['platToken'] = red.getPlatToken()
if (!params['plattoken'])
params['plattoken'] = red.getPlatToken()
return new Promise(resolve => {
axios.get(url, params).then(res => {
let data = res.data || {}
@@ -80,14 +140,14 @@ var red = {
resolve(data)
}).catch(res => {
console.log(res)
//console.log(res)
red.showMsg({type:"error", msg:'操作失败!'})
})
})
},
postX(url, params = {}) {
if (!params['platToken'])
params['platToken'] = red.getPlatToken()
if (!params['plattoken'])
params['plattoken'] = red.getPlatToken()
return new Promise(resolve => {
axios({
url,
@@ -118,19 +178,21 @@ var red = {
})
},
post: function(url, params = {}, callback) {
params['platToken'] = red.getPlatToken()
//params['plattoken'] = red.getPlatToken()
axios.post(url, params).then(res => {
let data = red.loginCheck(res.data)
/*let data = red.loginCheck(res.data)
if (data && data.code == -1) {
red.showMsg({msg: data.message, type: "error"})
return;
}
}*/
if (callback) {
callback(data.code == 0 ? data.body : data)
console.log("xx", res.data.body)
callback(res.data.code === 0 ? res.data.body : data)
} else {
red.showMsg()
}
return res
})
},
@@ -169,6 +231,9 @@ var red = {
},
timeFmt: function (date,fmt){
if (!this.isValidDate(date)) {
return "";
}
fmt = fmt || "yyyy-MM-dd HH:mm:ss";
var o = {
"M+" : date.getMonth()+1, //月份
@@ -194,6 +259,7 @@ var red = {
location.href = "/user/login.html";
}, 2000);
}
return json.data
},
replaceAll: function (d, s, t) {
let reg=new RegExp(s,"g"); //创建正则RegExp对象
@@ -206,6 +272,26 @@ var red = {
},
replace$: function (d) {
return red.replaceAll(d, "[$]", ".");
},
wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
deepClone: function (obj) {
if (obj === null) return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (typeof obj !== 'object') return obj;
let cloneObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = this.deepClone(obj[key]);
}
}
return cloneObj;
},
isValidDate: function (date) {
return date instanceof Date && !isNaN(date.getTime());
}
}

View File

@@ -80,7 +80,7 @@
<label for="username" class="col-md-3">业务平台</label>
<div class="col-md-8">
<select v-model="sysPlat" class="form-control">
<option v-for="item in sysPlats" :value="item" v-text="item.name"></option>
<option v-for="item in sysPlats" :value="item" v-text="item.platname"></option>
</select>
</div>
</div>
@@ -88,7 +88,7 @@
</div>
<div class="modal-footer">
<!--<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>-->
<button @click="goIndex()" type="button" class="btn btn-primary btn-block">确定选择 <span v-text="[sysPlat.name]"></span></button>
<button @click="goIndex()" type="button" class="btn btn-primary btn-block">确定选择 <span v-text="[sysPlat.platname]"></span></button>
</div>
</div>
</div>
@@ -123,7 +123,7 @@
methods: {
login({username, pwd}) {
login({username, pwd}).then(res => {
console.log(res)
red.setData("token", res.sessionid);
platList().then(res => {
let rows = res.rows
console.log(rows)
@@ -133,7 +133,6 @@
if (!this.sysPlat) {
this.sysPlat = rows[0];
}
red.setData("sysPlats", rows);
red.setData('userName', username)
setTimeout(function () {

View File

@@ -0,0 +1,77 @@
package dev.zhub.mk.qtask;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.BaseEntity;
import net.tccn.base.Kv;
import net.tccn.base.Utils;
import net.tccn.qtask.Task;
import org.redkale.annotation.Comment;
import org.redkale.convert.json.JsonConvert;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
import java.util.Map;
@Getter
@Setter
@Entity
public class QTask extends BaseEntity {
@Id
@Comment("[记录ID]")
private Integer qtaskid;
@Comment("[查询默认参数]")
private String para = "{}";
@Comment("[CATALOG]")
private String catalog = "";
@Comment("[数据平台ID]")
private int dbid;
@Comment("[标识名称KEY]")
// @Column(updatable = false)
private String name = "";
@Comment("[所属平台ID]")
@Column(updatable = false, comment = "")
private Integer platid;
@Comment("[业务名称]")
private String title = "";
@Comment("[SQL模板]")
private String content;
@Comment("[备注]")
private String remark = "";
@Comment("[状态]10正常80删除")
private int status = 10;
public Task createTask(Kv<String, String> para) {
// TODO : QTask 作为 Task 的引用值,省去创建重复 Task 属性
Task task = new Task();
task.setName(name);
task.setTitle(title);
task.setContent(content);
task.setDbid(dbid);
task.setCatalog(catalog);
Kv _para = Kv.of();
if (!Utils.isEmpty(this.para)) {
try {
Map<String, String> map = JsonConvert.root().convertFrom(JsonConvert.TYPE_MAP_STRING_STRING, this.para);
_para.putAll(map);
} catch (Exception e) {
new IllegalArgumentException(String.format("fromJson error:[%s]", this.para), e);
}
}
_para.putAll(para); // 填充传入的参数,优先级最高
task.setPara(_para);
return task;
}
}

View File

@@ -0,0 +1,59 @@
package dev.zhub.mk.qtask;
import net.tccn.base.BaseService;
import net.tccn.base.Utils;
import org.redkale.net.http.RestHeader;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.service.RetResult;
import org.redkale.source.FilterNode;
import org.redkale.source.Flipper;
import org.redkale.util.AnyValue;
import org.redkale.util.Sheet;
import java.util.Map;
@RestService(name = "qtask", comment = "qtask服务")
public class QTaskService extends BaseService {
@Override
public void init(AnyValue config) {
super.init(config);
/*List<QTask> qTasks = metaSource.queryList(QTask.class);
for (QTask xTask : qTasks) {
System.out.println(JsonConvert.root().convertTo(xTask));
}*/
}
@RestMapping(name = "list", comment = "qtask列表")
public RetResult<Sheet<QTask>> list(@RestHeader(name = "platid") String platid,
Flipper flipper, Map<String, String> params) {
FilterNode node = FilterNode.create("platid", platid);
Sheet<QTask> sheet = metaSource.querySheet(QTask.class, flipper, node);
return RetResult.success(sheet);
}
@RestMapping(name = "create", comment = "qtask创建")
public RetResult create(@RestHeader(name = "platid") String platid,
QTask bean) {
// -- 数据检查 --
// 1. name 不可为空、 content 不可以为空
if (Utils.isEmpty(bean.getName())) {
return retError("名称不能为空");
}
if (Utils.isEmpty(bean.getContent())) {
return retError("内容不能为空");
}
// 2. bean.name 标识名称KEY唯一性检查
FilterNode node = FilterNode.create("name", bean.getName())
.and("platid", platid);
if (metaSource.exists(QTask.class, node)) {
return retError("名称重复");
}
// -- 数据保存 --
metaSource.insert(bean);
return render();
}
}

View File

@@ -0,0 +1,5 @@
package net.tccn.base;
public class BaseEntity {
}

View File

@@ -1,12 +1,15 @@
package net.tccn.base;
import org.redkale.annotation.Resource;
import org.redkale.convert.json.JsonConvert;
import org.redkale.net.http.RestMapping;
import org.redkale.service.RetResult;
import org.redkale.service.Service;
import org.redkale.source.CacheMemorySource;
import org.redkale.source.DataSource;
import org.redkale.util.Sheet;
import javax.annotation.Resource;
import java.io.File;
import java.util.List;
import java.util.Properties;
import java.util.function.Supplier;
import java.util.logging.Logger;
@@ -21,23 +24,47 @@ public class BaseService implements Service {
@Resource(name = "SERVER_ROOT")
protected File webroot;
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
protected Logger logger = Logger.getLogger(this.getClass().getSimpleName());
public static boolean isWinos = System.getProperty("os.name").contains("Window");
protected static boolean isWinos = System.getProperty("os.name").contains("Window");
@Resource(name = "cache")
protected static CacheMemorySource cacheSource = new CacheMemorySource("cache");
@Resource(name = "APP_HOME")
protected File APP_HOME;
@Resource(name = "meta")
protected DataSource metaSource;
@Resource
protected MetaKit metaKit;
public static Properties prop = new Properties();
protected static Properties prop = new Properties();
protected static TplKit tplKit = TplKit.use(true);
private static boolean tplInit = false;
@RestMapping(ignore = true)
public <T> T getT(String key, Class<T> clazz, Supplier<T> supplier) {
protected final static RetResult RET_SUCCESS = RetResult.success();
protected final static RetResult RET_EMPTY_SHEET = RetResult.success(new Sheet<>(0, List.of()));
protected final static RetResult RET_EMPTY_LIST = RetResult.success(List.of());
protected RetResult retError(String info) {
return new RetResult<>(100, info);
}
protected RetResult retError(int code, String info) {
return new RetResult<>(code, info);
}
protected <T> RetResult<T> render(T obj) {
return new RetResult<>(obj);
}
protected RetResult render() {
return RET_SUCCESS;
}
protected <T> T getT(String key, Class<T> clazz, Supplier<T> supplier) {
Object obj = cacheSource.getAndRefresh(key, 1000 * 60 * 3, clazz);
if (obj != null) {
return (T) obj;
@@ -50,12 +77,11 @@ public class BaseService implements Service {
return t;
}
@RestMapping(ignore = true)
public String platId(String token) {
protected Integer platId(String token) {
return MetaKit.getPlatId(token);
}
public boolean isEmpty(Object obj) {
protected boolean isEmpty(Object obj) {
return Utils.isEmpty(obj);
}
}

View File

@@ -1,6 +1,6 @@
package net.tccn.base;
import net.tccn.user.MetaUser;
import net.tccn.user.MUser;
import net.tccn.user.UserService;
import org.redkale.net.http.HttpRequest;
import org.redkale.net.http.HttpResponse;
@@ -9,6 +9,7 @@ import org.redkale.net.http.HttpServlet;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;
/**
@@ -33,14 +34,23 @@ public class BaseServlet extends HttpServlet {
if (sessionid == null) {
sessionid = request.getSessionid(true);
}
if (sessionid == null) {
Map<String, String> headers = request.getHeaders();
for (String key : headers.keySet()) {
if ("token".equalsIgnoreCase(key)) {
sessionid = headers.get(key);
break;
}
}
}
if (sessionid != null) {
MetaUser user = userService.current(sessionid);
MUser user = userService.current(sessionid);
/*request.setCurrentUserSupplier(() -> {
return user;
});*/
if (user != null) {
request.setCurrentUserid(user.getId());
request.setCurrentUserid(user.getUserid());
}
}
String uri = request.getRequestURI();

View File

@@ -25,7 +25,7 @@ public class Kv<K, V> extends LinkedHashMap<K, V> {
return new Kv();
}
public static Kv of(Object k, Object v) {
public static Kv<String, Object> of(Object k, Object v) {
return new Kv().set(k, v);
}
@@ -68,7 +68,7 @@ public class Kv<K, V> extends LinkedHashMap<K, V> {
}
// 将obj 属性映射到Kv 中
public static Kv toKv(Object m, String... fields) {
public static Kv<String, Object> toKv(Object m, String... fields) {
Kv kv = Kv.of();
if (m == null) {
return kv;

View File

@@ -1,25 +1,27 @@
package net.tccn.base;
import dev.zhub.mk.qtask.QTask;
import lombok.Getter;
import net.tccn.base.arango.Doc;
import net.tccn.base.dbq.jdbc.api.DbAccount;
import net.tccn.base.dbq.jdbc.api.DbKit;
import net.tccn.base.dbq.table.Field;
import net.tccn.dict.Dict;
import net.tccn.dict.DictKit;
import net.tccn.dict.MDict;
import net.tccn.meta.*;
import net.tccn.plat.MetaDb;
import net.tccn.plat.MetaPlat;
import net.tccn.qtask.DbTask;
import net.tccn.plat.MPlat;
import net.tccn.qtask.TaskKit;
import net.tccn.user.MetaUser;
import org.redkale.convert.json.JsonConvert;
import net.tccn.user.MUser;
import org.redkale.annotation.Resource;
import org.redkale.service.AbstractService;
import org.redkale.source.DataJdbcSource;
import org.redkale.source.DataSource;
import org.redkale.source.FilterNode;
import org.redkale.source.Flipper;
import org.redkale.util.AnyValue;
import org.redkale.util.Comment;
import org.redkale.util.TypeToken;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -29,149 +31,231 @@ import static java.util.Arrays.asList;
/**
* Created by liangxianyou at 2019/1/7 13:31.
*/
public final class MetaKit {
public class MetaKit extends AbstractService {
//基础数据缓存
@Getter
private static List<MetaTable> metaTables;
private static List<MTable> mTables;
@Getter
private static List<MetaLink> metaLinks;
private static List<MLink> metaLinks;
@Getter
private static List<MetaService> metaServices;
private static List<MService> metaServices;
@Getter
private static List<DbAccount> dbPlats;
@Getter
private static List<MetaPlat> sysPlats;
private static List<MPlat> mPlats;
@Getter
private static List<MetaUser> users;
private static List<MUser> users;
@Getter
private static List<DbTask> taskEntities;
private static List<QTask> qTasks;
@Getter
private static List<Dict> dicts;
private static List<MDict> dicts;
protected static String dcate = "db";
protected static String dataPath;
private static final JsonConvert convert = JsonConvert.root();
@Resource(name = "property.dataCate")
protected String dcate = "db";
@Resource(name = "property.dataPath")
protected String dataPath;
// private static final JsonConvert convert = JsonConvert.root();
@Resource(name = "meta")
protected DataSource metaSource;
public <T> void reloadxAsync(Class<T> clazz) {
CompletableFuture.runAsync(() -> {
if (clazz == QTask.class) {
qTasks = metaSource.queryList(QTask.class);
TaskKit.init(qTasks);
} else if (clazz == MPlat.class) mPlats = metaSource.queryList(MPlat.class);
else if (clazz == DbAccount.class) dbPlats = metaSource.queryList(DbAccount.class);
else if (clazz == MTable.class) mTables = metaSource.queryList(MTable.class);
else if (clazz == MService.class) metaServices = metaSource.queryList(MService.class);
else if (clazz == MLink.class) metaLinks = metaSource.queryList(MLink.class);
else if (clazz == MDict.class) {
dicts = metaSource.queryList(MDict.class);
DictKit.cleanCache();
}
/*if (clazz == MUser.class) {
users = metaSource.queryList(MUser.class);
}*/
});
}
@Override
public void init(AnyValue config) {
reloadxAsync(QTask.class);
reloadxAsync(MPlat.class);
reloadxAsync(DbAccount.class);
reloadxAsync(MService.class);
reloadxAsync(MTable.class);
reloadxAsync(MLink.class);
reloadxAsync(MDict.class);
/*metaTables.forEach(x -> {
// 写入到 MTable
MTable mTable = new MTable();
mTable.setTableid(Integer.parseInt(x.getKey()));
mTable.setCatalog(x.getCatalog());
mTable.setDbid(x.getDbid());
mTable.setAlias(x.getAlias());
mTable.setTablename(x.getName());
mTable.setPlatid(x.getPlatid());
mTable.setComment(x.getComment());
mTable.setItems(x.getItems());
metaSource.insertAsync(mTable);
});*/
/*metaServices.forEach(x -> {
// 写入到 MService
MService service = new MService();
service.setServid(Integer.parseInt(x.getKey()));
service.setName(x.getName());
service.setTablealias(x.getTable());
service.setShows(x.getShows());
service.setExports(x.getExports());
service.setEdits(x.getEdits());
service.setDetails(x.getDetails());
service.setFilters(x.getFilters());
service.setComment(x.getComment());
//service.setDels(x.getDels());
service.setPlatid(x.getPlatid());
metaSource.insert(service);
});*/
/*metaLinks.forEach(x -> {
MxLink link = new MxLink();
link.setLinkid(Integer.parseInt(x.getKey()));
link.setTables(x.getTables());
link.setLinks(x.getLink());
metaSource.insert(link);
});*/
}
// -----------------------------------
public static void init() {
reload(MetaTable.class);
reload(MetaLink.class);
reload(MetaService.class);
reload(DbAccount.class);
reload(MetaPlat.class);
reload(MetaUser.class);
reload(DbTask.class);
reload(Dict.class);
/*public static void init() {
// reload(MetaTable.class);
// reload(MLink.class);
// reload(MetaService.class);
// reload(DbAccount.class);
// reload(MetaPlat.class);
// reload(MetaUser.class);
// reload(DbTask.class);
// reload(Dict.class);
/*
同步 本地文件配置数据到 数据库
// 同步 本地文件配置数据到 数据库
List<List<? extends Doc>> list = asList(metaTables, metaLinks, metaServices, dbPlats, sysPlats, users, taskEntities, dicts);
for (List<? extends Doc> docs : list) {
for (Doc doc : docs) {
doc.save();
}
}*/
}
public static <T extends Doc> void reload(Class<T> clazz) {
}*/
/*public static <T extends Doc> void reload(Class<T> clazz) {
reload(clazz, null);
}
public static <T extends Doc> void reload(T t) {
reload(t.getClass(), t.getKey());
}
}*/
public static void main(String[] args) throws IOException {
/*public static void main(String[] args) throws IOException {
Type type = new TypeToken<List<DbAccount>>() {
}.getType();
dbPlats = FileKit.readAs(new File("D:\\Java\\meta-kit\\conf\\data\\DbAccount.json"), type);
//convert.convertFrom(type,"[{\"catalogs\":[\"test\"],\"cate\":\"mysql\",\"id\":\"db_plat/67275393\",\"key\":\"67275393\",\"name\":\"ylz测试\",\"url\":\"jdbc:mysql://119.3.106.117:3306\",\"user\":\"root\"},{\"catalogs\":[\"v09x_platf_core\"],\"cate\":\"mysql\",\"id\":\"db_plat/67275392\",\"key\":\"67275392\",\"name\":\"platf_qc\",\"url\":\"jdbc:mysql://121.196.17.55:6063\",\"user\":\"root\"},{\"catalogs\":[\"official_core\",\"official_ipci\",\"v09x_platf_core\",\"platf_quest\",\"platf_pay\",\"platf_mall\",\"platf_oth\",\"platf_im\",\"z_core\"],\"cate\":\"mysql\",\"id\":\"db_plat/67275391\",\"key\":\"67275391\",\"name\":\"platf_pro\",\"url\":\"jdbc:mysql://122.112.180.156:6033\",\"user\":\"guest\"},{\"catalogs\":[\"db_diamond\"],\"id\":\"db_plat/53533152\",\"key\":\"53533152\",\"name\":\"钻石项目\",\"url\":\"jdbc:mysql://192.168.201.51:3306/db_diamond?characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false\",\"user\":\"root\"},{\"catalogs\":[\"db_diamond\"],\"id\":\"db_plat/53532996\",\"key\":\"53532996\",\"name\":\"钻石项目\",\"url\":\"jdbc:mysql://192.168.201.51:3306/db_diamond?characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false\",\"user\":\"root\"},{\"catalogs\":[\"platf_im\",\"v09x_platf_core\",\"platf_oss\",\"platf_quest\",\"platf_oth\",\"sport_oss\",\"zhub\",\"cpg_core\",\"z_core\",\"z_config\",\"z_im\",\"z_mall\",\"z_quest\",\"z_oss\",\"z_oth\",\"cmt_oss\",\"cmt_depot_core\",\"cmt_core\",\"sport_core\"],\"cate\":\"mysql\",\"id\":\"db_plat/52481174\",\"key\":\"52481174\",\"name\":\"platf_dev\",\"url\":\"jdbc:mysql://47.111.150.118:6063\",\"user\":\"root\"},{\"catalogs\":[],\"cate\":\"mysql\",\"id\":\"db_plat/4375768\",\"key\":\"4375768\",\"name\":\"mysql数据库\",\"url\":\"jdbc:mysql://192.168.50.124:3306/mytest?characterEncoding=utf-8&autoReconnect=true&useSSL=false&connectTimeout=3000\",\"user\":\"root\"},{\"catalogs\":[],\"cate\":\"mysql\",\"id\":\"db_plat/4267761\",\"key\":\"4267761\",\"name\":\"测试\",\"remark\":\"sadfdsaf\",\"url\":\"123&connectTimeout=5000\",\"user\":\"root\"},{\"catalogs\":[\"db_art\",\"db_jsons_bbs\",\"db_mater\",\"db_redbbs\",\"jfly\",\"redbbs_dev\",\"meta_kit_test\"],\"cate\":\"mysql\",\"id\":\"db_plat/3321254\",\"key\":\"3321254\",\"name\":\"测试-DB【可用】\",\"url\":\"jdbc:mysql://120.24.230.60:3306/redbbs?characterEncoding=utf-8&autoReconnect=true&useSSL=false&connectTimeout=3000\",\"user\":\"guest\"},{\"catalogs\":[\"blockchain\",\"gxbii_dev\",\"gxbii_all\",\"gxbii_cmd\",\"fzexp\",\"db_fz\",\"a_test\",\"meta_xx\",\"ipsm_v4\"],\"cate\":\"mysql\",\"id\":\"db_plat/3305916\",\"key\":\"3305916\",\"name\":\"测试库-11测试库【可用】\",\"remark\":\"描述\",\"url\":\"jdbc:mysql://192.168.202.11:3306/gxbii_dev?characterEncoding=utf-8&autoReconnect=true&connectTimeout=3000\",\"user\":\"root\"},{\"catalogs\":[\"ipsm_v4\"],\"cate\":\"mysql\",\"id\":\"db_plat/32822760\",\"key\":\"32822760\",\"name\":\"ceshi1111\",\"url\":\"jdbc:mysql://192.168.202.11:3306/ipsm_v4?characterEncoding=utf-8&autoReconnect=true\",\"user\":\"root\"},{\"catalogs\":[\"zbd_v1\"],\"cate\":\"mysql\",\"id\":\"db_plat/27166384\",\"key\":\"27166384\",\"name\":\"测试1\",\"url\":\"jdbc:mysql://192.168.50.124:3306/mytest?characterEncoding=utf-8&autoReconnect=true&useSSL=false&connectTimeout=3000\",\"user\":\"root\"},{\"catalogs\":[],\"cate\":\"mysql\",\"id\":\"db_plat/25668979\",\"key\":\"25668979\",\"name\":\"测试Mysql数据库\",\"url\":\"jdbc:mysql://558cfc37a10ef.sh.cdb.myqcloud.com:3817/demo?autoReconnect=true\",\"user\":\"cdb_outerroot\"},{\"catalogs\":[],\"cate\":\"localApi\",\"id\":\"db_plat/23090860\",\"key\":\"23090860\",\"name\":\"平台本地API\"},{\"catalogs\":[],\"cate\":\"http\",\"id\":\"db_plat/21561306\",\"key\":\"21561306\",\"name\":\"http地址调用\",\"url\":\"http://127.0.0.1/plat/db_list\"},{\"catalogs\":[\"tc\",\"tc_bbs\",\"redbbs\",\"redoss\",\"material\",\"keeper_dev\",\"art123\",\"keeper\",\"db_party\"],\"cate\":\"mysql\",\"id\":\"db_plat/21558770\",\"key\":\"21558770\",\"name\":\"TX-cloud\",\"url\":\"jdbc:mysql://558cfc37a10ef.sh.cdb.myqcloud.com:3817/demo?autoReconnect=true\",\"user\":\"cdb_outerroot\"},{\"catalogs\":[\"feature_test\",\"intelligence\",\"ma\",\"mysql\",\"ma1\",\"ma2\",\"maintenance\",\"zhaobiao\",\"zhaobiao2\"],\"cate\":\"mysql\",\"id\":\"db_plat/21449811\",\"key\":\"21449811\",\"name\":\"物联网-jj【可用】\",\"url\":\"jdbc:mysql://192.168.50.21:3306/wlw?characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai\",\"user\":\"root\"},{\"catalogs\":[],\"id\":\"db_plat/20982257\",\"key\":\"20982257\",\"name\":\"数据平台abc\",\"remark\":\"sadfdsaf\",\"url\":\"123&connectTimeout=5000\",\"user\":\"root\"}]");
System.out.println(dbPlats.size());
}
}*/
public static <T extends Doc> void reload(Class<T> clazz, String key) {
/*public static <T extends Doc> void reload(Class<T> clazz, String key) {
try {
File file = new File(String.format("%s%s.json", dataPath, clazz.getSimpleName()));
if ("file".equals(dcate)) {
if (MetaTable.class == clazz) {
*//*if (MetaTable.class == clazz) {
Type type = new TypeToken<List<MetaTable>>() {
}.getType();
metaTables = FileKit.readAs(file, type);
} else if (MetaLink.class == clazz) {
Type type = new TypeToken<List<MetaLink>>() {
} else*//*
*//*if (MLink.class == clazz) {
Type type = new TypeToken<List<MLink>>() {
}.getType();
metaLinks = FileKit.readAs(file, type);;
} else if (MetaService.class == clazz) {
metaLinks = FileKit.readAs(file, type);
}*//* *//*else if (MetaService.class == clazz) {
Type type = new TypeToken<List<MetaService>>() {
}.getType();
metaServices = FileKit.readAs(file, type);;
} else if (DbAccount.class == clazz) {
metaServices = FileKit.readAs(file, type);
}*//* *//*else if (DbAccount.class == clazz) {
Type type = new TypeToken<List<DbAccount>>() {
}.getType();
dbPlats = FileKit.readAs(file, type);
} else if (MetaDb.class == clazz) {
}*//* *//*else if (MetaDb.class == clazz) {
Type type = new TypeToken<List<DbAccount>>() {
}.getType();
dbPlats = FileKit.readAs(file, type);;
} else if (MetaPlat.class == clazz) {
}*//* *//*else if (MetaPlat.class == clazz) {
Type type = new TypeToken<List<MetaPlat>>() {
}.getType();
sysPlats = FileKit.readAs(file, type);;
} else if (MetaUser.class == clazz) {
mPlats = FileKit.readAs(file, type);;
} *//* *//*else if (MetaUser.class == clazz) {
Type type = new TypeToken<List<MetaUser>>() {
}.getType();
users = FileKit.readAs(file, type);;
} else if (DbTask.class == clazz) {
}*//* *//*else if (DbTask.class == clazz) {
Type type = new TypeToken<List<DbTask>>() {
}.getType();
taskEntities = FileKit.readAs(file, type);;
} else if (Dict.class == clazz) {
} *//* *//*else if (Dict.class == clazz) {
Type type = new TypeToken<List<Dict>>() {
}.getType();
dicts = FileKit.readAs(file, type);;
}
dicts = FileKit.readAs(file, type);
}*//*
} else {
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 (MetaDb.class == clazz) dbPlats = DbAccount.dao.find();
else if (MetaPlat.class == clazz) sysPlats = MetaPlat.dao.find();
else if (MetaUser.class == clazz) users = MetaUser.dao.find();
else if (DbTask.class == clazz) {
taskEntities = DbTask.dao.find();
TaskKit.init();
} else if (Dict.class == clazz) {
dicts = Dict.dao.find();
*//*if (MetaTable.class == clazz) {
metaTables = MetaTable.dao.find();
}
else*//*
//if (MLink.class == clazz) metaLinks = MLink.dao.find();
//else if (MetaService.class == clazz) metaServices = MetaService.dao.find();
//else if (DbAccount.class == clazz) dbPlats = DbAccount.dao.find();
//else if (MetaDb.class == clazz) dbPlats = DbAccount.dao.find();
//else if (MetaPlat.class == clazz) mPlats = MetaPlat.dao.find();
//else if (MetaUser.class == clazz) users = MetaUser.dao.find();
*//*else if (DbTask.class == clazz) {
// taskEntities = DbTask.dao.find();
// TaskKit.init();
}*//*
//else
*//*if (Dict.class == clazz) {
dicts = Dict.dao.find();
}*//*
}
} catch (Exception e) {
e.printStackTrace();
}
}
}*/
public static void cacheSave() {
cacheSave(MetaTable.class);
cacheSave(MetaLink.class);
cacheSave(MetaService.class);
cacheSave(DbAccount.class);
cacheSave(MetaPlat.class);
cacheSave(MetaUser.class);
cacheSave(DbTask.class);
cacheSave(Dict.class);
}
/*public static void cacheSave() {
//cacheSave(MetaTable.class);
//cacheSave(MLink.class);
//cacheSave(MService.class);
//cacheSave(DbAccount.class);
//cacheSave(MetaPlat.class);
//cacheSave(MetaUser.class);
//cacheSave(DbTask.class);
//cacheSave(Dict.class);
}*/
private static void cacheSave(Class clazz) {
/*private static void cacheSave(Class clazz) {
List list = null;
if (MetaTable.class == clazz) list = metaTables;
else if (MetaLink.class == clazz) list = metaLinks;
else if (MetaService.class == clazz) list = metaServices;
else if (DbAccount.class == clazz) list = dbPlats;
else if (MetaPlat.class == clazz) list = sysPlats;
else if (MetaUser.class == clazz) list = users;
else if (DbTask.class == clazz) list = taskEntities;
*//*if (MetaTable.class == clazz) list = metaTables;
else*//*
if (MLink.class == clazz) list = metaLinks;
else if (MService.class == clazz) list = metaServices;
//else if (DbAccount.class == clazz) list = dbPlats;
//else if (MetaPlat.class == clazz) list = mPlats;
//else if (MetaUser.class == clazz) list = users;
// else if (DbTask.class == clazz) list = taskEntities;
else if (Dict.class == clazz) list = dicts;
if (list == null || list.size() == 0) return;
@@ -179,7 +263,7 @@ public final class MetaKit {
File file = new File(String.format("%s%s.json", dataPath, list.get(0).getClass().getSimpleName()));
file.getParentFile().mkdirs();
FileKit.strToFile(MetaKit.convert.convertTo(list), file);
}
}*/
/**
* 得到业务主表
@@ -188,20 +272,21 @@ public final class MetaKit {
* @param token
* @return
*/
public static MetaTable getMainTable(String serviceName, String token) {
MetaService metaService = MetaKit.getMetaService(serviceName, token);
return MetaKit.getMetaTableByAlias(metaService.getTable());
public static MTable getMainTable(String serviceName, String token) {
MService metaService = MetaKit.getMetaService(serviceName, token);
return MetaKit.getMetaTableByAlias(metaService.getTablealias());
}
/**
* 通过平台token 得到平台字典数据
*
* @param platToken
* @param plattoken
*/
public static Map<String, List<Dict>> getDictData(String platToken) {
String platId = MetaKit.getPlatId(platToken);
Map<String, List<Dict>> dicts = MetaKit.dicts.stream().filter(x -> x.getSysPlatId().equals(platId)).collect(Collectors.groupingBy(Dict::getType));
public static Map<String, List<MDict>> getDictData(String plattoken) {
int platid = MetaKit.getPlatId(plattoken);
Map<String, List<MDict>> dicts = MetaKit.dicts.stream().filter(x -> x.getPlatid() == platid).collect(Collectors.groupingBy(MDict::getType));
return dicts;
// return new HashMap<>();
}
// -----------------------------------
@@ -215,28 +300,28 @@ public final class MetaKit {
* @param alias
* @return
*/
public static MetaTable getMetaTableByAlias(String alias) {
Optional<MetaTable> table = metaTables.stream().filter(x -> x.getAlias().equals(alias)).findAny();
public static MTable getMetaTableByAlias(String alias) {
Optional<MTable> table = mTables.stream().filter(x -> x.getAlias().equals(alias)).findAny();
return table.orElse(null);
}
public static MetaTable getMetaTable(String name, String token) {
Optional<MetaTable> any = getMetaTables().stream().filter(x -> {
return x.getName().equals(name) && x.getSysPlatId().equals(getPlatId(token));
public static MTable getMetaTable(String name, String token) {
Optional<MTable> any = getMTables().stream().filter(x -> {
return x.getTablename().equals(name) && x.getPlatid().equals(getPlatId(token));
}).findAny();
return any.get();
}
public static MetaService getMetaService(String name, String token) {
Optional<MetaService> service = metaServices.stream()
.filter(x -> x.getName().equals(name) && x.getSysPlatId().equals(getPlatId(token)))
public static MService getMetaService(String name, String token) {
Optional<MService> service = metaServices.stream()
.filter(x -> x.getName().equals(name) && x.getPlatid().equals(getPlatId(token)))
.findAny();
return service.orElse(null);
}
//字段特征排序
public static BiFunction<MetaTable, String[], MetaTable> sortItem = (t, arr) -> {
public static BiFunction<MTable, String[], MTable> sortItem = (t, arr) -> {
List<Field> items = t.getItems();
//x 是跨越值
@@ -263,8 +348,8 @@ public final class MetaKit {
};
public static Map cfg(String name, String token) {
MetaService metaService = getMetaService(name, token);
Kv<String, MetaTable> metaTables = getMetaTables(metaService, false);
MService metaService = getMetaService(name, token);
Kv<String, MTable> metaTables = getMTables(metaService, false);
List<Map<String, String>> shows = metaService.getShows();
List<FromItem> edits = metaService.getEdits();
@@ -384,18 +469,18 @@ public final class MetaKit {
//pk业务主表的主键
StringBuffer _pks = new StringBuffer();
MetaTable mainTable = metaTables.get(metaService.getTable());
MTable mainTable = metaTables.get(metaService.getTablealias());
mainTable.getItems().stream().filter(x -> x.getPk() != null && x.getPk()).forEach(x -> {
_pks.append(String.format("%s.%s,", metaService.getTable(), x.getName()));
_pks.append(String.format("%s.%s,", metaService.getTablealias(), x.getName()));
});
if (_pks.length() > 0) {
_pks.deleteCharAt(_pks.length() - 1);
}
if (_pks.length() == 0) { // 默认主键
List<Field> items = metaTables.get(metaService.getTable()).getItems();
List<Field> items = metaTables.get(metaService.getTablealias()).getItems();
//存在id字段取id
items.stream().filter(x -> x.getName().equalsIgnoreCase("id")).findAny().ifPresent(x -> {
_pks.append(String.format("%s.%s", metaService.getTable(), x.getName()));
_pks.append(String.format("%s.%s", metaService.getTablealias(), x.getName()));
});
}
@@ -411,7 +496,7 @@ public final class MetaKit {
@Comment("获取导出excel表头配置k-v")
public static Kv cfgExport(String name, String token) {
MetaService metaService = getMetaService(name, token);
MService metaService = getMetaService(name, token);
List<Map<String, String>> exports = metaService.getExports();
Kv kv = Kv.of(); // {col:label}
@@ -422,7 +507,7 @@ public final class MetaKit {
}
//itemUpdate
public static BiFunction<MetaTable, List<Field>, MetaTable> itemUpdate = (t, fields) -> {
public static BiFunction<MTable, List<Field>, MTable> itemUpdate = (t, fields) -> {
List<Field> items = t.getItems();
for (int i = 0; i < fields.size(); i++) {
for (int j = 0; j < items.size(); j++) {
@@ -448,11 +533,11 @@ public final class MetaKit {
};*/
public static MetaTable getMetaTableByKey(String key) {
return metaTables.stream().filter(x -> x.getKey().equals(key)).findAny().orElse(null);
public static MTable getMetaTableByKey(int key) {
return mTables.stream().filter(x -> x.getTableid() == key).findAny().orElse(null);
}
public static List<MetaLink> getMetaLinks(String t, List<String> shows, List<String> filters) {
public static List<MLink> getMetaLinks(String t, List<String> shows, List<String> filters) {
Predicate<String> contain = s -> {
@@ -473,7 +558,7 @@ public final class MetaKit {
//1、直接关联 表: t.equals(x.getTables()[0]) || t.equals(x.getTables()[1]
//2、关联且有过滤
//3、关联有展示
List<MetaLink> links = metaLinks.stream()
List<MLink> links = metaLinks.stream()
.filter(x -> {
return (t.equals(x.getTables()[0]) || t.equals(x.getTables()[1]))
&& (contain.test(x.getTables()[0]) || contain.test(x.getTables()[1]));
@@ -482,17 +567,17 @@ public final class MetaKit {
return links;
}
public static Kv buildeDetail(MetaService metaService) {
public static Kv buildeDetail(MService metaService) {
//tables
Kv<String, MetaTable> tables = getMetaTables(metaService, true);
Kv<String, MTable> tables = getMTables(metaService, true);
return Kv.of("tables", tables)
.set("links", Kv.of());
}
public static Kv<String, MetaTable> getMetaTables(MetaService metaService, Boolean all) {
Kv<String, MetaTable> tables = Kv.of();
public static Kv<String, MTable> getMTables(MService metaService, Boolean all) {
Kv<String, MTable> tables = Kv.of();
String table = metaService.getTable();//
String table = metaService.getTablealias();//
tables.set(table, getMetaTableByAlias(table));
//收集所有的col
@@ -525,34 +610,35 @@ public final class MetaKit {
return tables;
}
/*public static DbKit getDbKit(String dbPlatId) {
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getKey().equals(dbPlatId)).findAny();
/*public static DbKit getDbKit(int dbid) {
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getKey().equals(dbid)).findAny();
return new DbKit(dbAccount.get());
}*/
public static DbKit getDbKit(String dbPlatId, String catalog) {
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getKey().equals(dbPlatId)).findAny();
public static DbKit getDbKit(int dbid, String catalog) {
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getDbid() == dbid).findAny();
return new DbKit(dbAccount.get(), catalog);
}
public static DbAccount getDbPlat(String dbPlatId) {
Optional<DbAccount> dbAccount = dbPlats.stream().filter(x -> x.getKey().equals(dbPlatId)).findFirst();
public static DbAccount getDbPlat(int dbid) {
Optional<DbAccount> db = dbPlats.stream().filter(x -> x.getDbid() == dbid).findFirst();
return dbAccount.get();
return db.get();
}
@Comment("通过平台token 得到平台id")
public static String getPlatId(String platToken) { //
Optional<MetaPlat> plat = sysPlats.stream().filter(x -> x.getToken().equals(platToken)).findAny();
return plat.get().getKey();
public static Integer getPlatId(String plattoken) { //
Optional<MPlat> plat = mPlats.stream().filter(x -> x.getPlattoken().equals(plattoken)).findAny();
return plat.get().getPlatid();
}
public static String lastAlias;
public static String nextAlias() {
public String nextAlias() {
if (lastAlias == null) {
String aql = TplKit.use(true).getTpl("metaTable.lastAlias");
lastAlias = MetaTable.dao.findFirst(aql, String.class);
//String aql = TplKit.use(true).getTpl("metaTable.lastAlias");
lastAlias = findColumn("mable.lastAlias", Kv.of(), String.class);
// lastAlias = MetaTable.dao.findFirst(aql, String.class); // TODO....
}
return lastAlias = next(lastAlias, "");
}
@@ -574,15 +660,80 @@ public final class MetaKit {
public static List<String> tableExist(String[] tableArr, String token) {
List<String> _tableArr = asList(tableArr);
List<String> hv = metaTables.stream()
.filter(x -> _tableArr.contains(x.getName()) && x.getSysPlatId().equals(getPlatId(token)))
.map(MetaTable::getName)
List<String> hv = mTables.stream()
.filter(x -> _tableArr.contains(x.getTablename()) && x.getPlatid().equals(getPlatId(token)))
.map(MTable::getTablename)
.collect(Collectors.toList());
return hv;
}
// ---------------------- repository -------------------
public static <T extends Doc> void save(T... ts) {
public void save(MTable table) {
if (table.getTableid() == null || table.getTableid() == 0) {
metaSource.insert(table);
// 查询回来带id的记录
FilterNode node = FilterNode.create("alias", table.getAlias()); // alias 唯一
MTable _table = metaSource.find(MTable.class, node);
mTables.add(_table);
} else {
metaSource.update(table);
// 更新缓存
mTables.stream().filter(x -> x.getTableid().equals(table.getTableid())).forEach(x -> {
x.setCatalog(table.getCatalog());
x.setComment(table.getComment());
x.setDbid(table.getDbid());
x.setItems(table.getItems());
x.setPlatid(table.getPlatid());
x.setStatus(table.getStatus());
x.setTablename(table.getTablename());
x.setAlias(table.getAlias());
});
}
}
public void save(MService mservice) {
if (mservice.getServid() == 0) {
metaSource.insert(mservice);
// 查询回来带id的记录
FilterNode node = FilterNode.create("name", mservice.getName()).and("platid", mservice.getPlatid());
MService _mservice = metaSource.find(MService.class, node);
metaServices.add(_mservice);
} else {
metaSource.update(mservice);
metaServices.stream().filter(x -> x.getServid() == mservice.getServid()).forEach(x -> {
x.setComment(mservice.getComment());
x.setEdits(mservice.getEdits());
x.setDetails(mservice.getDetails());
x.setExports(mservice.getExports());
x.setFilters(mservice.getFilters());
x.setName(mservice.getName());
x.setPlatid(mservice.getPlatid());
x.setShows(mservice.getShows());
x.setTablealias(mservice.getTablealias());
});
}
}
public void save(MLink link) {
if (link.getLinkid() == 0) {
metaSource.insert(link);
// 查询回来带id的记录 (暂未考虑多人并发操作)
List<MLink> _links = metaSource.queryList(MLink.class, new Flipper("linkid DESC"));
metaLinks.add(_links.get(0));
} else {
metaSource.update(link);
metaLinks.stream().filter(x -> x.getLinkid() == link.getLinkid()).forEach(x -> {
x.setLinks(link.getLinks());
x.setTables(link.getTables());
});
}
}
/*public static <T extends Doc> void save(T... ts) {
if (ts == null || ts.length == 0) return;
for (T t : ts) {
@@ -599,21 +750,21 @@ public final class MetaKit {
t.save();
} else {
if (t instanceof MetaLink) {
*//*if (t instanceof MLink) {
//避免删除属性无效
if (((MetaLink) t).getLink() != null && ((MetaLink) t).getLink().size() > 0) {
if (((MLink) t).getLink() != null && ((MLink) t).getLink().size() > 0) {
t.find(String.format("UPDATE '%s' WITH { link:null } IN MetaLink", t.getKey()), Map.class);
}
}
}*//*
t.update();
}
}
reload(ts[0].getClass());
}
}*/
public static <T extends Doc> T findFirst(T t) {
/*public static <T extends Doc> T findFirst(T t) {
Objects.nonNull(t);
List<T> list = asList();
@@ -634,5 +785,13 @@ public final class MetaKit {
}).findAny();
return (T) any.orElse(null);
}*/
protected static TplKit tplKit = TplKit.use(true);
protected <T> T findColumn(String tpl, Map params, Class<T> type) {
String sql = tplKit.getTpl(tpl, params);
return ((DataJdbcSource) metaSource).nativeQueryOne(type, sql);
}
}

View File

@@ -1,10 +1,10 @@
package net.tccn.base;
import org.redkale.annotation.Resource;
import org.redkale.boot.Application;
import org.redkale.boot.ApplicationListener;
import org.redkale.util.ResourceFactory;
import javax.annotation.Resource;
import java.io.File;
import java.util.concurrent.CompletableFuture;
@@ -13,12 +13,12 @@ import java.util.concurrent.CompletableFuture;
*/
public class MetaListenter implements ApplicationListener {
@Resource(name = "property.dataCate")
/*@Resource(name = "property.dataCate")
private String dcate;
@Resource(name = "property.dataPath")
private String dataPath;*/
@Resource(name = "property.tplPath")
private String tplPath;
@Resource(name = "property.dataPath")
private String dataPath;
public static ResourceFactory resourceFactory;
@@ -29,18 +29,17 @@ public class MetaListenter implements ApplicationListener {
resourceFactory = rf;
rf.inject(this);
MetaKit.dcate = dcate;
MetaKit.dataPath = dataPath;
MetaKit.init();
/*MetaKit.dcate = dcate;
MetaKit.dataPath = dataPath;*/
TplKit.use(true).addTpl(new File(FileKit.rootPath(), tplPath));
});
}
@Override
public void preShutdown(Application application) {
if ("db".equals(dcate)) {
/*if ("db".equals(dcate)) {
MetaKit.cacheSave();
}
}*/
}
}

View File

@@ -1,5 +1,10 @@
package net.tccn.base;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.select.*;
import net.tccn.base.dbq.jdbc.api.DbSource;
import java.lang.reflect.Array;
@@ -211,4 +216,57 @@ public class Utils {
return _group;
}
public static String parserSql(String originalSql) {
try {
Select select = (Select) CCJSqlParserUtil.parse(originalSql);
// 如果未设置分页,设置默认分页 99
if (select.getLimit() == null) {
Limit limit = new Limit().withRowCount(new LongValue(10));
select.setLimit(limit);
originalSql = select.toString();
}
return originalSql;
} catch (JSQLParserException e) {
throw new RuntimeException(e);
}
}
public static String parserCountSql(String originalSql) {
String sqlCount = "SELECT COUNT(1)";
try {
Select select = (Select) CCJSqlParserUtil.parse(originalSql);
PlainSelect plainSelect = select.getPlainSelect();
FromItem fromItem = plainSelect.getFromItem();
List<Join> joins = plainSelect.getJoins();
Expression where = plainSelect.getWhere();
GroupByElement group = plainSelect.getGroupBy();
if (fromItem == null) {
return null;
}
sqlCount += " FROM " + fromItem;
if (joins != null) {
for (Join join : joins) {
sqlCount += " " + join;
}
}
if (!Utils.isEmpty(where)) {
sqlCount += " WHERE " + where;
}
if (!Utils.isEmpty(group)) {
sqlCount += " " + group;
sqlCount = "SELECT COUNT(1) FROM (" + sqlCount + ") _";
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return sqlCount;
}
}

View File

@@ -1,216 +0,0 @@
package net.tccn.base.arango;
import com.arangodb.ArangoCollection;
import com.arangodb.ArangoDB;
import com.arangodb.ArangoDatabase;
import com.arangodb.entity.DocumentCreateEntity;
import com.arangodb.entity.DocumentDeleteEntity;
import com.arangodb.entity.MultiDocumentEntity;
import net.tccn.base.MetaListenter;
import net.tccn.base.Utils;
import javax.annotation.Resource;
import javax.persistence.Table;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.Arrays.asList;
/**
* 管理 数据源连接对象
*
* @author: liangxianyou at 2018/12/15 11:35.
*/
public class ArangoSource {
@Resource(name = "property.arango.host")
private String host = "127.0.0.1";
@Resource(name = "property.arango.user")
private String user = "root";
@Resource(name = "property.arango.password")
private String password = "123456";
@Resource(name = "property.arango.port")
private int port = 8529;
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
private ArangoDB arangoDb;
private static Map<String, ArangoSource> sourceMap = new HashMap();
private ArangoSource() {
MetaListenter.resourceFactory.inject(this);
arangoDb = new ArangoDB.Builder().host(host, port).user(user).password(password).build();
}
private ArangoSource(ArangoDB arangoDb) {
MetaListenter.resourceFactory.inject(this);
this.arangoDb = arangoDb;
}
public static ArangoSource use(String unit) {
ArangoSource arangoSource = new ArangoSource();
return arangoSource;
}
public ArangoDatabase db(String db) {
return arangoDb.db(db);
}
public <T extends Doc> ArangoCollection collection(Doc<T> doc) {
return collection(doc.getClass());
}
public <T extends Doc> ArangoCollection collection(Class<T> type) {
Table table = type.getAnnotation(Table.class);
//createDb(table.catalog());
return arangoDb.db(table.catalog()).collection(table.name());
}
public boolean createDb(String db) {
ArangoDatabase database = arangoDb.db(db);
if (!database.exists()) {
return database.create();
}
logger.log(Level.INFO, "arango database exists");
return true;
}
public <T extends Doc> ArangoCollection createDocument(Doc<T> doc) {
Class<? extends Doc> type = doc.getClass();
Table table = type.getAnnotation(Table.class);
ArangoDatabase database = arangoDb.db(table.catalog());
if (!database.exists()) {
database.create();
}
ArangoCollection collection = database.collection(table.name());
if (!collection.exists()) {
collection.create();
}
return collection;
}
// 首字母大写
private static Function<String, String> upFirst = (s) -> {
return s.substring(0, 1).toUpperCase() + s.substring(1);
};
/**
* Doc 转为查询对象
*
* @param t
* @param <T>
* @return
*/
private Function<Doc, StringBuilder> filterBuilder = (t) -> {
Table table = t.getClass().getAnnotation(Table.class);
StringBuilder buf = new StringBuilder();
buf.append("for d in ").append(table.name());
buf.append(" filter 1==1");
t.toDoc().forEach((k, v) -> {
if (v != null && (v.getClass() == String.class || v instanceof Number)) {
buf.append(" and d.").append(k).append("==");
}
if (v.getClass() == String.class) {
buf.append("'").append(v).append("'");
} else if (v instanceof Number) {
buf.append(v);
}
});
return buf;
};
private Function<Doc, StringBuilder> orderBuilder = (t) -> {
StringBuilder buf = new StringBuilder();
Map<String, Integer> order = t.getOrder();
if (Utils.isEmpty(order)) {
return buf.append(" sort d._key desc");
}
buf.append(" sort ");
order.forEach((k, v) -> {
buf.append("d.").append(k).append(v == 1 ? " desc," : " asc,");
});
buf.deleteCharAt(buf.length() - 1);
return buf;
};
private Function<Doc, StringBuilder> returnBuilder = (t) -> {
StringBuilder buf = new StringBuilder();
if (Utils.isEmpty(t.get_Shows())) {
return buf.append(" return d");
}
buf.append(" return {");
t.get_Shows().forEach(x -> {
buf.append(x).append(":d.").append(x).append(",");
});
buf.deleteCharAt(buf.length() - 1).append("}");
return buf;
};
public <T extends Doc> String parseAqlCount(T t) {
StringBuilder buf = new StringBuilder();
buf.append(filterBuilder.apply(t));
buf.append(" COLLECT WITH COUNT INTO total");
buf.append(" return total");
//logger.log(Level.INFO, buf.toString());
return buf.toString();
}
public <T extends Doc> String parseAql(T t, int offset, int ps) {
if (offset < 0) offset = 0;
if (ps <= 0) ps = 1000;
StringBuilder buf = new StringBuilder();
buf.append(filterBuilder.apply(t));
buf.append(orderBuilder.apply(t));
buf.append(" limit ").append(offset).append(",").append(ps);
buf.append(returnBuilder.apply(t));
//logger.log(Level.INFO, buf.toString());
return buf.toString();
}
//----------------------------------------
//ok
public <T extends Doc> T save(T doc) {
DocumentCreateEntity<Map> tmap = collection(doc).insertDocument(doc.toDoc());
doc.setKey(tmap.getKey());
doc.setId(tmap.getId());
return doc;
}
//ok
public <T extends Doc> void update(T doc) {
collection(doc).updateDocument(doc.getKey(), doc.toDoc());
}
//ok
public <T extends Doc> T getDoc(Object key, Class<T> type) {
return collection(type).getDocument(String.valueOf(key), type);
}
//ok
public <T extends Doc> DocumentDeleteEntity<Void> delete(String key, Class<T> type) {
return collection(type).deleteDocument(key);
}
//ok
public <T extends Doc> MultiDocumentEntity<DocumentDeleteEntity<Void>> deleteAll(Doc<T>... docs) {
return collection(docs[0]).deleteDocuments(asList(docs));
}
public <T extends Doc> MultiDocumentEntity find(Collection keys, Class<T> type) {
return collection(type).getDocuments(keys, type);
}
}

View File

@@ -1,271 +0,0 @@
package net.tccn.base.arango;
import com.arangodb.ArangoCollection;
import com.arangodb.ArangoDBException;
import com.arangodb.ArangoDatabase;
import com.arangodb.entity.DocumentCreateEntity;
import net.tccn.base.PageBean;
import org.redkale.source.Flipper;
import javax.persistence.Table;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
* @author: liangxianyou at 2018/12/1 22:59.
*/
public abstract class Doc<T extends Doc> {
private HashMap attr = new HashMap();
private String _id;
private String _key;
private Set<String> _shows;
private Map _order;
private List<Map> _filters;//[{col, value, expr}]
public String getId() {
return _id;
}
public void setId(String id) {
this._id = id;
}
public String getKey() {
return _key;
}
public void setKey(String key) {
this._key = key;
}
protected Doc<T> set(String k, Object v) {
attr.put(k, v);
return this;
}
protected <V> V get(String k) {
return (V)attr.get(k);
}
/*public T setShows(String... show) {
if (_shows == null) {
_shows = new HashSet<>();
}
for (String s : show) {
_shows.add(s);
}
return (T) this;
}*/
public Set<String> get_Shows() {
return _shows;
}
/*public void set_Shows(Set<String> shows) {
this._shows = shows;
}*/
public T setOrder(String col, int desc) {
if (_order == null) {
_order = new LinkedHashMap();
}
_order.put(col, desc);
return (T) this;
}
public Map<String, Integer> getOrder() {
return _order;
}
/*public void setOrder(Map order) {
this._order = order;
}*/
/*@Override
public String toString() {
//convert.
String doc = convert.convertTo(this);
if (attr.size() == 0) {
return doc;
}
StringBuilder builder = new StringBuilder();
if (attr.size() != 0) {
String attrStr = convert.convertTo(attr);
builder.append("{");
builder.append(attrStr, 1, attrStr.length() - 1);
builder.append(",");
builder.append(doc, 1, doc.length()); //builder.append(doc.substring(1));
}
return builder.toString();
}*/
private Function<String, String> fieldName = (s) -> {
return s.replace("get", "").substring(0, 1).toLowerCase() + s.substring(4);
};
/**
* 提取Doc 属性到 Map用于存贮到Arango中
* 提取规则:
* 1、将doc中自带非空 !=null 属性提取都map中
* 2、将attr中属性覆盖到map中如果attr中存在同名属性attr为主
* @return
*/
public Map toDoc() {
HashMap clone = (HashMap) attr.clone();
Class<? extends Doc> type = this.getClass();
Method[] methods = type.getDeclaredMethods();
for (Method method : methods) {
String name = method.getName();
if (name.startsWith("get") && method.getParameterCount() == 0) {
//Type mt = method.getAnnotatedReturnType().getType();
try {
//System.out.println(method.getName());
Object v = method.invoke(this);
if (v != null) {
clone.put(fieldName.apply(name), v);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return clone;
}
//---------------------------------------------------------------------------------------------------
private ArangoSource arangoSource;
private ArangoDatabase db;
private ArangoCollection collection;
private static ConcurrentHashMap<Class, Doc> daos = new ConcurrentHashMap();
public Doc() {
Table table = this.getClass().getAnnotation(Table.class);
String sourceName = null;
Source source = this.getClass().getAnnotation(Source.class);
if (source != null) {
sourceName = source.name();
}
try {
arangoSource = ArangoSource.use(sourceName);
this.db = arangoSource.db(table.catalog());
this.collection = arangoSource.collection(this);
} catch (Exception e) {
e.printStackTrace();
}
}
protected final static <T extends Doc> T dao(Class<T> type) {
if (daos.get(type) == null) {
try {
daos.put(type, type.newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return (T) daos.get(type);
}
//ok
public T save() {
DocumentCreateEntity<Map> tmap = collection.insertDocument(this.toDoc());
this.setId(tmap.getId());
this.setKey(tmap.getKey());
return (T) this;
}
//ok
public void update() {
collection.updateDocument(this.getKey(), this.toDoc());
}
public <T extends Doc> PageBean<T> findPage(T t, Flipper flipper) {
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);
return PageBean.by(list, count);
}
public T findFirst(T t) {
return findFirst(arangoSource.parseAql(t, 0, 1), (Class<T>) t.getClass());
}
public List<T> find() {
int count = count(this);
return find((T) this, 0, count);
}
public List<T> find(T t) {
return find(t, 0, 1000);
}
public <T extends Doc> List<T> find(T t, int offset, int ps) {
if (t == null) {
t = (T) this;
}
return find(arangoSource.parseAql(t, offset, ps), (Class<T>)this.getClass());
}
public <T> List<T> find(String aql, Class<T> clazz) {
try {
return db.query(aql, clazz).asListRemaining();
} catch (ArangoDBException e) {
System.out.println(aql);
e.printStackTrace();
}
return db.query(aql, clazz).asListRemaining();
}
public <T> T findFirst(String aql, Class<T> clazz) {
try {
return db.query(aql, clazz).first();
} catch (ArangoDBException e) {
System.out.println(aql);
e.printStackTrace();
}
return db.query(aql, clazz).first();
}
public int count() {
return count(this);
}
public <T extends Doc> int count(T t) {
if (t == null) {
t = (T) this;
}
// arangoSource.createDocument(this);
return db.query(arangoSource.parseAqlCount(t), int.class).first();
}
//ok
public <T extends Doc> T findByKey(Object key) {
return (T) collection.getDocument(String.valueOf(key), this.getClass());
}
// ok todo: 将数据放入回收库
public void delete() {
collection.deleteDocument(getKey());
}
public void delete(Collection<String> key) {
collection.deleteDocuments(key);
}
}

View File

@@ -1,15 +0,0 @@
package net.tccn.base.arango;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: liangxianyou at 2018/12/22 0:32.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Source {
String name() default "";
}

View File

@@ -1,12 +1,13 @@
package net.tccn.base.dbq;
import net.tccn.base.Kv;
import net.tccn.base.MetaKit;
import net.tccn.base.PageBean;
import net.tccn.base.dbq.fbean.FBean;
import net.tccn.base.dbq.jdbc.api.DbKit;
import net.tccn.base.dbq.parser.ParseMysql;
import net.tccn.meta.MetaService;
import net.tccn.meta.MetaTable;
import net.tccn.meta.MService;
import net.tccn.meta.MTable;
import java.util.List;
import java.util.Map;
@@ -24,10 +25,10 @@ public class DbExecutors {
String[] sqls = PARSER.parseList(fBean);
//当前的业务 => 获取主表 信息 => 数据源信息 => 数据源对象 => 创建数据工具对象 => 查询数据
MetaService metaService = MetaKit.getMetaService(fBean.getName(), fBean.getPlatToken());
MetaTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTable());
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbPlatId(), mainTable.getCatalog());
//System.out.printf("----------------%n countSql:%s%n findSql:%s%n----------------%n", sqls[0], sqls[1]);
MService metaService = MetaKit.getMetaService(fBean.getName(), fBean.getPlattoken());
MTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTablealias());
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbid(), mainTable.getCatalog());
System.out.printf("----------------%n countSql:%s%n findSql:%s%n----------------%n", sqls[0], sqls[1]);
CompletableFuture<Integer> countFuture = CompletableFuture.supplyAsync(() -> dbKit.findColumn(sqls[0], int.class));
CompletableFuture<List<Map>> listFuture = CompletableFuture.supplyAsync(() -> dbKit.queryList(sqls[1], Map.class));
@@ -35,33 +36,37 @@ public class DbExecutors {
List<Map> rows = listFuture.get();
Integer total = countFuture.get();
/*rows.forEach(x -> {
x.forEach((k,v) -> {
if ("[B".equals(v.getClass().getName())) {
rows.forEach(m -> {
m.forEach((k, v) -> {
/*if ("[B".equals(v.getClass().getName())) {
try {
//System.out.println(k + " : " + new String((byte[]) v, "UTF-8"));
x.put(k, new String((byte[]) v, "UTF-8"));
m.put(k, new String((byte[]) v, "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}*/
// 避免前端 解析丢失精度
if (v instanceof Long && (Long) v > 9007199254740991L) {
m.put(k, Kv.toAs(v, String.class));
}
});
});*/
});
return PageBean.by(rows, total);
}
public static void del(String name, Map data, String token) {
MetaService metaService = MetaKit.getMetaService(name, token);
MetaTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTable());
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbPlatId(), mainTable.getCatalog());
/*public static void del(String name, Map data, String token) {
MService metaService = MetaKit.getMetaService(name, token);
MTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTablealias());
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbid(), mainTable.getCatalog());
String delSql = PARSER.parseDel(name, data, token);
dbKit.exetute(delSql);
}
}*/
public static void save(String name, Map data, String token) {
MetaTable mainTable = MetaKit.getMainTable(name, token);
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbPlatId(), mainTable.getCatalog());
MTable mainTable = MetaKit.getMainTable(name, token);
DbKit dbKit = MetaKit.getDbKit(mainTable.getDbid(), mainTable.getCatalog());
String sql = PARSER.parseSave(name, data, token);
dbKit.exetute(sql);

View File

@@ -13,7 +13,7 @@ import java.util.List;
@Setter
public class FBean {
private String platToken; // 平台token
private String plattoken; // 平台token
private String name; // 业务名称
private String type; // 操作类型 list列表export导出

View File

@@ -57,7 +57,7 @@ public class Filter {
filters.forEach(x -> {
buf.append(" and d.").append(x.col).append(" " + (x.type == null ? "==" : x.type) + " ");
//处理数值型字段查询
if ("sysPlatId".equals(x.col) || "platId".equals(x.col) || "status".equals(x.col) || false) {
if ("platid".equals(x.col) || "platId".equals(x.col) || "status".equals(x.col)) {
buf.append(x.value);
} else {
buf.append("'" + x.value + "'");

View File

@@ -2,34 +2,51 @@ package net.tccn.base.dbq.jdbc.api;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.arango.Doc;
import org.redkale.annotation.Comment;
import org.redkale.convert.ConvertColumn;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
import javax.persistence.Table;
import java.util.List;
/**
* 数据库平台
*
* @author: liangxianyou at 2018/11/14 12:58.
*/
@Getter
@Setter
@Table(name = "MetaDb", catalog = "db_meta")
public class DbAccount extends Doc<DbAccount> {
public static DbAccount dao = dao(DbAccount.class);
@Entity(comment = "[数据库平台表]")
public class DbAccount {
@Id
@Comment("[数据库ID]")
private int dbid;
private String name; //名称
private String cate; //类型 mysql|ArangoDb
private String remark; //备注
private String url; //数据库连接地址
private String user; //账号
private String pwd; //密码
private List<String> catalogs; //库
private Integer status;//状态 1启用 0 未启用
@Column(length = 64, comment = "[名称]")
private String dbname;
//----------------------------
private boolean tmp; // TODO: 处理临时连接对象
@Comment("[类型mysql|ArangoDb]")
@Column(length = 32, comment = "[类型]")
private String cate;
@Comment("[备注]")
@Column(comment = "[备注]")
private String remark;
@Column(length = 128, comment = "[数据库连接地址]")
private String url;
@Column(length = 32, comment = "[账号]")
private String user;
@Column(length = 64, comment = "[密码]")
private String pwd;
// 将catalogs作为JSON字符串存储但此处为了方便解析将其转换为List<String>
@Column(length = 255, comment = "[库]JSON格式存储多个库名")
private List<String> catalogs;
@Column(comment = "[状态] 1启用0未启用")
private short status;
@Column(updatable = false, comment = "[创建时间]")
private long createtime;
public String accountKey() {
int start = url.indexOf("//") + 2;
@@ -46,4 +63,5 @@ public class DbAccount extends Doc<DbAccount> {
public String getPwd() {
return pwd;
}
}

View File

@@ -33,7 +33,7 @@ public class DbKit implements DbSource {
try {
if (Utils.isEmpty(dbAccount.getPwd())) {
DbAccount account = MetaKit.getDbPlat(dbAccount.getKey());
DbAccount account = MetaKit.getDbPlat(dbAccount.getDbid());
dbAccount.setPwd(account.getPwd());
}
@@ -43,7 +43,8 @@ public class DbKit implements DbSource {
this.dbSource = dbSource;
} catch (Exception e) {
throw new IllegalArgumentException(String.format("创建DbKit失败数据库类型[cate:%s]未知", dbAccount.getCate()));
e.printStackTrace();
// throw new IllegalArgumentException(String.format("创建DbKit失败数据库类型[cate:%s]未知", dbAccount.getCate()));
}
}
@@ -89,6 +90,11 @@ public class DbKit implements DbSource {
return dbSource.exetute(sql);
}
@Override
public int exetuteUpdate(String sql) {
return dbSource.exetuteUpdate(sql);
}
// -----------------------------------------
public <T> CompletableFuture<T> findAsync(String sql, Class<T> type) {
return CompletableFuture.supplyAsync(() -> find(sql, type));

View File

@@ -42,4 +42,6 @@ public interface DbSource extends IService {
void dropTable(String tableName);
boolean exetute(String sql);
int exetuteUpdate(String sql);
}

View File

@@ -5,9 +5,7 @@ import net.tccn.base.Kv;
import java.sql.*;
import java.util.ArrayList;
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;
@@ -24,6 +22,49 @@ public class DbSourceMysql implements DbSource {
private DbAccount dbAccount;
private String catalog;
private static boolean ping;
static {
// MYSQL PING
synchronized (DbSourceMysql.class) {
if (!ping) {
new Thread(() -> {
while (true) {
conns.forEach((k, vs) -> {
if (vs.isEmpty()) {
return;
}
try {
for (int i = 0; i < counter.get(k).get(); i++) {
Connection conn = vs.poll();
if (conn == null) {
return;
}
try {
conn.prepareStatement("SELECT 1").executeQuery();
vs.put(conn);
} catch (SQLException e) {
counter.get(k).decrementAndGet(); // 连接总数减去1
e.printStackTrace();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException ignored) {
}
}
}).start();
ping = true;
}
}
}
public DbSourceMysql() {
}
@@ -65,7 +106,7 @@ public class DbSourceMysql implements DbSource {
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
while (rs.next()) {
Map row = new HashMap();
Kv row = Kv.of();
for (int i = 1; i <= count; i++) {
String columnTypeName = metaData.getColumnTypeName(i);
//String columnName = metaData.getColumnName(i);
@@ -74,8 +115,15 @@ public class DbSourceMysql implements DbSource {
if (rs.getObject(i) != null) {
switch (columnTypeName) {
case "DATETIME", "TIMESTAMP", "DATE" -> {
row.put(columnLabel, rs.getTimestamp(i).getTime());
case "DATETIME", "TIMESTAMP" -> {
// row.put(columnLabel, rs.getTimestamp(i).getTime());
row.put(columnLabel, rs.getTimestamp(i));
}
case "DATE" -> {
row.put(columnLabel, rs.getDate(i));
}
case "BIT" -> {
row.put(columnLabel, rs.getShort(i));
}
default -> {
row.put(columnLabel, rs.getObject(i));
@@ -132,6 +180,7 @@ public class DbSourceMysql implements DbSource {
return Kv.toAs(v, type);
} catch (SQLException e) {
System.out.println("sql execute error: " + sql);
e.printStackTrace();
return null;
} finally {
@@ -164,6 +213,20 @@ public class DbSourceMysql implements DbSource {
}
}
@Override
public int exetuteUpdate(String sql) {
Connection connection = connection();
try (
PreparedStatement ps = connection.prepareStatement(sql)
) {
return ps.executeUpdate();
} catch (SQLException e) {
throw new CfgException("SQL 执行失败:", sql);
} finally {
release(connection);
}
}
//fixme: lxy 处理连接超过8小时失效问题
private Connection connection() {
Connection connection = null;
@@ -179,21 +242,34 @@ public class DbSourceMysql implements DbSource {
}
private synchronized Connection connection(int n) throws InterruptedException, SQLException {
LinkedBlockingQueue<Connection> queue = conns.getOrDefault(accountKey, new LinkedBlockingQueue<>(15));
LinkedBlockingQueue<Connection> queue = conns.get(accountKey);
if (queue == null) {
queue = new LinkedBlockingQueue<>(15);
conns.put(accountKey, queue);
}
AtomicInteger num = counter.get(accountKey);
if (num == null) {
num = new AtomicInteger(0);
}
Connection conn = null;
AtomicInteger num = counter.getOrDefault(accountKey, new AtomicInteger(0));
if (queue.size() == 0 && num.get() < 15) { // 创建总连接数小于15且暂无可用连接
conn = DriverManager.getConnection(dbAccount.getUrl(), dbAccount.getUser(), dbAccount.getPwd());
if (queue.isEmpty() && num.get() < 15) { // 创建总连接数小于15且暂无可用连接
String url = dbAccount.getUrl();
String user = dbAccount.getUser();
String pwd = dbAccount.getPwd();
conn = DriverManager.getConnection(url, user, pwd);
int x = num.incrementAndGet();
counter.put(accountKey, num);
System.out.println("创建新的连接:" + x);
System.out.printf("创建新的连接[%s]:%s\n", x, url + "@" + user);
} else {
conn = queue.take();
if (!conn.isValid(5)) {
conn = connection(++n);
}
}
conns.put(accountKey, queue);
//conns.put(accountKey, queue);
return conn;
}

View File

@@ -1,10 +1,13 @@
package net.tccn.base.dbq.parser;
import net.tccn.base.*;
import net.tccn.base.CfgException;
import net.tccn.base.Kv;
import net.tccn.base.MetaKit;
import net.tccn.base.Utils;
import net.tccn.base.dbq.fbean.*;
import net.tccn.meta.MetaLink;
import net.tccn.meta.MetaService;
import net.tccn.meta.MetaTable;
import net.tccn.meta.MLink;
import net.tccn.meta.MService;
import net.tccn.meta.MTable;
import java.util.List;
import java.util.Map;
@@ -19,12 +22,12 @@ import java.util.stream.Collectors;
*/
public class ParseMysql implements Parser {
Predicate<Kv<String, MetaTable>> sameDbFun = (kv) -> {
String dbPlatId = null;
for (MetaTable metaTable : kv.values()) {
if (dbPlatId == null) {
dbPlatId = metaTable.getDbPlatId();
} else if (!dbPlatId.equals(metaTable.getDbPlatId())) {
Predicate<Kv<String, MTable>> sameDbFun = (kv) -> {
int dbid = 0;
for (MTable mTable : kv.values()) {
if (dbid == 0) {
dbid = mTable.getDbid();
} else if (dbid != mTable.getDbid()) {
return false;
}
}
@@ -38,16 +41,16 @@ public class ParseMysql implements Parser {
*/
@Override
public String[] parseList(FBean fBean) {
MetaService metaService = MetaKit.getMetaService(fBean.getName(), fBean.getPlatToken());
MService metaService = MetaKit.getMetaService(fBean.getName(), fBean.getPlattoken());
Kv<String, MetaTable> tables = MetaKit.getMetaTables(metaService, false);//所有的关联表信息
MetaTable metaTable = tables.get(metaService.getTable());//基础元数据
Kv<String, MTable> tables = MetaKit.getMTables(metaService, false);//所有的关联表信息
MTable metaTable = tables.get(metaService.getTablealias());//基础元数据
List<Map<String, String>> shows = metaService.getShows();//查询的属性-列表
List<Map<String, String>> exports = metaService.getExports();//查询的属性-导出
List<String> _filters = fBean.getFilters().stream().map(Filter::getCol).collect(Collectors.toList());
List<MetaLink> links = MetaKit.getMetaLinks(
metaService.getTable(),
List<MLink> links = MetaKit.getMetaLinks(
metaService.getTablealias(),
shows.stream().map(x -> x.get("col")).collect(Collectors.toList()),
_filters
);
@@ -75,8 +78,7 @@ public class ParseMysql implements Parser {
bufSelect.append(x.get("col")).append(" as ").append("'").append(x.get("col")).append("',");
});
bufSelect.deleteCharAt(bufSelect.length() - 1);
}
else if ("list".equals(fBean.getType()) && !Utils.isEmpty(shows)) {
} else if ("list".equals(fBean.getType()) && !Utils.isEmpty(shows)) {
shows.forEach(x -> {
bufSelect.append(x.get("col")).append(" as ").append("'").append(x.get("col")).append("',");
});
@@ -87,15 +89,15 @@ public class ParseMysql implements Parser {
//from
StringBuilder bufFrom = new StringBuilder();
bufFrom.append(" from `").append(metaTable.getCatalog()).append("`.`").append(metaTable.getName()).append("` `").append(metaTable.getAlias()).append("`");
bufFrom.append(" from `").append(metaTable.getCatalog()).append("`.`").append(metaTable.getTablename()).append("` `").append(metaTable.getAlias()).append("`");
//left join
if (!Utils.isEmpty(links)) {
links.forEach(x -> {
MetaTable rightTable = tables.get(metaTable.getAlias().equals(x.getTables()[0]) ? x.getTables()[1] : x.getTables()[0]);
MTable rightTable = tables.get(metaTable.getAlias().equals(x.getTables()[0]) ? x.getTables()[1] : x.getTables()[0]);
if (rightTable != null) {
bufFrom.append(" left join ").append(rightTable.getCatalog()).append(".").append(rightTable.getName()).append(" `").append(rightTable.getAlias()).append("` on ");
bufFrom.append(" left join ").append(rightTable.getCatalog()).append(".").append(rightTable.getTablename()).append(" `").append(rightTable.getAlias()).append("` on ");
int tag = bufFrom.length();
x.getLink().forEach((k, v) -> {
x.getLinks().forEach((k, v) -> {
if (bufFrom.length() > tag) {
bufFrom.append(" and ");
}
@@ -129,14 +131,14 @@ public class ParseMysql implements Parser {
* @param token
* @return
*/
public String parseDel(String name, Map data, String token) {
MetaService metaService = MetaKit.getMetaService(name, token);
/*public String parseDel(String name, Map data, String token) {
MService metaService = MetaKit.getMetaService(name, token);
Map<String, String> dels = metaService.getDels();
MetaTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTable());
MTable mainTable = MetaKit.getMetaTableByAlias(metaService.getTable());
String sql = "";
if ("UP_FIELD".equalsIgnoreCase(dels.get("cate"))) {
data.put("table", mainTable.getName());
data.put("table", mainTable.getTablename());
sql = TplKit.parseTpl("update #(table) set status=9 where id=#(id)", data);
} else if ("SQL".equalsIgnoreCase(dels.get("cate"))) {
sql = TplKit.parseTpl(dels.get("sql"), data);
@@ -145,7 +147,7 @@ public class ParseMysql implements Parser {
}
return sql;
}
}*/
/**
* 保存数据解析逻辑:
@@ -157,7 +159,7 @@ public class ParseMysql implements Parser {
* @return sql 待执行的sql语句
*/
public String parseSave(String serviceName, Map<String, String> data, String token) {
MetaTable mainTable = MetaKit.getMainTable(serviceName, token);
MTable mainTable = MetaKit.getMainTable(serviceName, token);
String alias = mainTable.getAlias();
String[] pks = mainTable.pk();
@@ -170,7 +172,7 @@ public class ParseMysql implements Parser {
x.startsWith(alias + ".") || !Utils.isEmpty(data.get(alias + "." + x))
).collect(Collectors.toList());
if (pks.length == 0) {
throw new CfgException("保存数据失败,检查业务主表[%s-%S]主键配置", mainTable.getName(), mainTable.getComment());
throw new CfgException("保存数据失败,检查业务主表[%s-%S]主键配置", mainTable.getTablename(), mainTable.getComment());
} else if (keys.size() == 0) {
throw new CfgException("保存数据失败,提交数据不能改空");
}
@@ -192,10 +194,8 @@ public class ParseMysql implements Parser {
vs.deleteCharAt(vs.length() - 1);
}
return String.format(sqlTpl, mainTable.getName(), ks, vs);
}
else { //修改
return String.format(sqlTpl, mainTable.getTablename(), ks, vs);
} else { //修改
String sqlTpl = "update `%s` set %s where `%s` = '%s';"; // para: table、 kvs、 pk、 pv
StringBuilder kvs = new StringBuilder(); // `k1`='v1',`k2`='v2', ...
String pk = pks[0];
@@ -208,7 +208,7 @@ public class ParseMysql implements Parser {
kvs.deleteCharAt(kvs.length() - 1);
}
return String.format(sqlTpl, mainTable.getName(), kvs, pk, pv);
return String.format(sqlTpl, mainTable.getTablename(), kvs, pk, pv);
}
}
}

View File

@@ -1,3 +1,4 @@
/*
package net.tccn.base.dbq.qtask;
import lombok.Getter;
@@ -6,9 +7,11 @@ import net.tccn.base.arango.Doc;
import javax.persistence.Table;
*/
/**
* @author: liangxianyou at 2018/11/13 14:59.
*/
*//*
@Getter
@Setter
@Table(name = "DbTask", catalog = "db_meta")
@@ -21,7 +24,7 @@ public class DbTask extends Doc<DbTask> {
private String sql; //SQL
private String para; //默认查询参数
private String cate; //任务类型 find|update
private Integer sysPlatId; //数据平台id
private Integer platid; //数据平台id
private Integer platId; //数据平台id
private String catalog; //数据库名
private Integer status; //状态 1启用|0未启用|-1删除
@@ -29,3 +32,4 @@ public class DbTask extends Doc<DbTask> {
//-------------------------------------
}
*/

View File

@@ -1,25 +0,0 @@
package net.tccn.dict;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
import java.io.Serializable;
/**
* @author: liangxianyou
*/
@Getter
@Setter
@Table(name = "Dict", catalog = "db_meta")
public class Dict extends Doc<Dict> implements Serializable {
public static Dict dao = Doc.dao(Dict.class);
private String type; // 字典类型
private String value; // 字典值
private String label; // 中文名
private String pValue; // 父级字典值
private String code; //
private String sysPlatId; // 系统平台id
}

View File

@@ -12,25 +12,25 @@ import java.util.*;
*/
public final class DictKit {
private static Map<String, DictKit> kits = new HashMap<>();
private String platToken;
private Map<String, List<Dict>> dicts;
private String plattoken;
private Map<String, List<MDict>> dicts;
private DictKit() {
}
public synchronized static DictKit use(String platToken) {
DictKit dictKit = kits.get(platToken);
public synchronized static DictKit use(String plattoken) {
DictKit dictKit = kits.get(plattoken);
if (dictKit == null) {
dictKit = new DictKit();
dictKit.platToken = platToken;
dictKit.dicts = MetaKit.getDictData(platToken);
kits.put(platToken, dictKit);
dictKit.plattoken = plattoken;
dictKit.dicts = MetaKit.getDictData(plattoken);
kits.put(plattoken, dictKit);
}
return dictKit;
}
public synchronized void reload() {
this.dicts = MetaKit.getDictData(platToken);
public static synchronized void cleanCache() {
kits.clear();
}
// 初始化字典,不同模式下,数据来源不同
@@ -55,8 +55,8 @@ public final class DictKit {
ArangoDB arangoDb = new ArangoDB.Builder().host(host, port).user(user).password(passwd).build();
ArangoDatabase dbDemo = arangoDb.db("db_demo");
String platId = "28121369";//MetaKit.getPlatId(platToken);
String dictAQL = String.format("for d in Dict filter d.sysPlatId=='%s'return d", platId);
String platId = "28121369";//MetaKit.getPlatId(plattoken);
String dictAQL = String.format("for d in Dict filter d.platid=='%s'return d", platId);
List<Dict> list = (List) dbDemo.query(dictAQL, Map.class).asListRemaining();
String[] fields = {"label", "value", "pValue"};
@@ -123,20 +123,20 @@ public final class DictKit {
* @param code
* @return
*/
public List<Dict> getDicts(String code) {
public List<MDict> getDicts(String code) {
Objects.requireNonNull(code, "code 不能为空");
return dicts.getOrDefault(code, new ArrayList<>());
}
public Map<String, List<Dict>> getDicts() {
public Map<String, List<MDict>> getDicts() {
return dicts;
}
public String getDictLabel(String code, String value) {
Objects.requireNonNull(code, "code 不能为空");
Objects.requireNonNull(value, "value 不能为空");
List<Dict> dicts = getDicts(code);
Optional<Dict> any = dicts.stream().filter(x -> value.equals(x.getValue())).findAny();
List<MDict> dicts = getDicts(code);
Optional<MDict> any = dicts.stream().filter(x -> value.equals(x.getValue())).findAny();
return any.isPresent() ? any.get().getLabel() : "";
}
@@ -144,8 +144,8 @@ public final class DictKit {
Objects.requireNonNull(code, "code 不能为空");
Objects.requireNonNull(label, "label 不能为空");
List<Dict> dicts = getDicts(code);
Optional<Dict> any = dicts.stream().filter(x -> label.equals(x.getLabel())).findAny();
List<MDict> dicts = getDicts(code);
Optional<MDict> any = dicts.stream().filter(x -> label.equals(x.getLabel())).findAny();
return any.isPresent() ? any.get().getValue() : "";
}

View File

@@ -18,12 +18,12 @@ import java.util.Map;
public class DictService extends BaseService {
@RestMapping(name = "list", comment = "根据type 加载对应的字典列表")
public JBean list(@RestParam(name = "platToken") String token, String type) {
public JBean list(@RestParam(name = "plattoken") String token, String type) {
JBean jBean = new JBean();
DictKit dictKit = DictKit.use(token);
if (!isEmpty(type)) {
List<Dict> dicts = dictKit.getDicts(type);
List<MDict> dicts = dictKit.getDicts(type);
jBean.setBody(dicts);
} else {
Map dicts = dictKit.getDicts();

View File

@@ -0,0 +1,37 @@
package net.tccn.dict;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.BaseEntity;
import org.redkale.convert.ConvertColumn;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
import org.redkale.persistence.Table;
/**
* @author: liangxianyou
*/
@Getter
@Setter
@Entity
@Table(comment = "字典表")
public class MDict extends BaseEntity {
@Id
@Column(comment = "[主键 ID]自增")
private int dictid;
@Column(comment = "[字典类型]")
private String type = "";
@Column(comment = "[字典值]")
private String value = "";
@Column(comment = "[中文名]")
private String label = "";
@ConvertColumn(ignore = true)
@Column(comment = "[系统平台 ID]")
private int platid;
}

View File

@@ -2,11 +2,11 @@ package net.tccn.file;
import net.tccn.base.*;
import net.tccn.base.dbq.table.Field;
import net.tccn.meta.MetaTable;
import net.tccn.plat.MetaPlat;
import net.tccn.meta.MTable;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
import org.redkale.source.FilterNode;
import java.io.File;
import java.util.ArrayList;
@@ -41,19 +41,19 @@ public class _FileService extends BaseService {
}).collect(Collectors.toList());
}
public MetaPlat getSysPlat(String token) {
/*public MetaPlat getSysPlat(String token) {
return getT(token, MetaPlat.class, () -> MetaPlat.dao.findFirst(new MetaPlat(token)));
}
}*/
@RestMapping(name = "data", comment = "得到文件数据")
public JBean data(String filePath, @RestParam(name = "platToken") String token) {
public JBean data(String filePath, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
//SysPlat sysPlat = getSysPlat(token);
File file = new File(webroot, filePath);
if (file.exists()) {
Map<String, List<Map>> map = ExcelKit.readExcelAll(file, FIELDS);
Kv<String, MetaTable> data = Kv.of();
Kv<String, MTable> data = Kv.of();
map.forEach((k, v) -> {
if (v.size() > 2) {
data.put(k.replace(" ", ""), toMetaTable(v));
@@ -67,8 +67,8 @@ public class _FileService extends BaseService {
data.forEach((k, v) -> {
Kv kv = Kv.of();
res.put(k,
kv.set("name", v.getName())
.set("hv", hv.contains(v.getName()) ? 1 : 0)
kv.set("name", v.getTablename())
.set("hv", hv.contains(v.getTablename()) ? 1 : 0)
.set("comment", v.getComment())
);
});
@@ -80,11 +80,11 @@ public class _FileService extends BaseService {
}
@RestMapping(name = "sheet_data", comment = "得到sheet数据")
public JBean sheetData(String filePath, String sheetName, @RestParam(name = "platToken") String token) {
public JBean sheetData(String filePath, String sheetName, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
File file = new File(webroot, filePath);
List<Map> list = ExcelKit.readExcel(file, FIELDS, sheetName);
MetaTable metaTable = toMetaTable(list);
MTable metaTable = toMetaTable(list);
jBean.setBody(metaTable);
@@ -94,7 +94,7 @@ public class _FileService extends BaseService {
@RestMapping(ignore = true, comment = "导入excel数据到metatable")
public JBean saveSheet(@RestParam(name = "sheetArr", comment = "sheet名") String[] sheetArr,
@RestParam(name = "filePath", comment = "文件路径") String filePath,
@RestParam(name = "platToken") String token) {
@RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
File file = new File(webroot, filePath);
@@ -103,31 +103,31 @@ public class _FileService extends BaseService {
Set<String> ks = map.keySet();
// 找到需要导入的sheet名并组装对应的数据
MetaTable[] metaTables = Stream.of(sheetArr).filter(x -> {
MTable[] metaTables = Stream.of(sheetArr).filter(x -> {
if (!ks.contains(x)) return false;
MetaTable bean = new MetaTable();
bean.setSysPlatId(platId(token));
bean.setName(x);
return MetaTable.dao.findFirst(bean) == null;
FilterNode node = FilterNode.create("platid", platId(token)).and("tablename", x);
return !metaSource.exists(MTable.class, node);
}).map(x -> {
MetaTable metaTable = toMetaTable(map.get(x));
metaTable.setSysPlatId(platId(token));
metaTable.setAlias(MetaKit.nextAlias());
MTable metaTable = toMetaTable(map.get(x));
metaTable.setPlatid(platId(token));
metaTable.setAlias(metaKit.nextAlias());
return metaTable;
}).toArray(MetaTable[]::new);
}).toArray(MTable[]::new);
MetaKit.save(metaTables);
for (MTable x : metaTables) {
metaKit.save(x);
}
return jBean;
}
/**
* 组装元数据
*/
private MetaTable toMetaTable(List<Map> list) {
private MTable toMetaTable(List<Map> list) {
//Kv col = Kv.of();
MetaTable metaTable = new MetaTable();
MTable metaTable = new MTable();
list.remove(1);//list[0] head info
Map rowHead = list.remove(0);
@@ -135,7 +135,7 @@ public class _FileService extends BaseService {
String comment = getComment(rowHead);//list[1] comment,
String tableName = getTableName(rowHead);
//col.set("name", tableName).set("comment", comment);
metaTable.setName(tableName);
metaTable.setTablename(tableName);
metaTable.setComment(comment);
//所有字段

View File

@@ -0,0 +1,31 @@
package net.tccn.meta;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.BaseEntity;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
import org.redkale.persistence.Table;
import java.util.HashMap;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/25 16:22.
*/
@Getter
@Setter
@Entity
@Table(name = "mlink", comment = "MLink表")
public class MLink extends BaseEntity {
@Id
@Column(comment = "[主键ID]自增")
private int linkid; // 根据您的说明移除了nonnull但通常主键不应该允许为空
@Column(comment = "[关联的表]存储表别名")
private String[] tables = new String[0];
@Column(comment = "[关联关系]")
private Map<String, String> links = new HashMap<>();
}

View File

@@ -0,0 +1,53 @@
package net.tccn.meta;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.BaseEntity;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
import org.redkale.persistence.Table;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/24 16:15.
*/
@Getter
@Setter
@Entity
@Table(name = "mservice", comment = "MService表")
public class MService extends BaseEntity {
@Id
@Column(comment = "[服务ID]")
private int servid;
@Column(length = 64, comment = "[业务标识]")
private String name;
@Column(updatable = false, length = 15, comment = "[主体表别名]")
private String tablealias;
@Column(length = 64, comment = "[业务中文名]")
private String comment;
@Column(updatable = false, comment = "[平台id]")
private Integer platid;
@Column(comment = "[SHOWS]")
private List<Map<String, String>> shows = new ArrayList<>();
@Column(comment = "[EDITS]")
private List<FromItem> edits = new ArrayList<>();
@Column(comment = "[DETAILS]")
private List<Map<String, String>> details = new ArrayList<>();
@Column(comment = "[FILTERS]")
private List<Filter> filters = new ArrayList<>();
@Column(comment = "[exports]")
private List<Map<String, String>> exports = new ArrayList<>();
}

View File

@@ -2,11 +2,10 @@ package net.tccn.meta;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.arango.Doc;
import net.tccn.base.BaseEntity;
import net.tccn.base.dbq.table.Field;
import org.redkale.persistence.*;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -18,26 +17,47 @@ import java.util.stream.Collectors;
*/
@Getter
@Setter
@Table(name = "MetaTable", catalog = "db_meta")
public class MetaTable extends Doc<MetaTable> implements Serializable {
public static final MetaTable dao = MetaTable.dao(MetaTable.class);
@Entity
@Table(name = "mtable", comment = "TABLE记录表")
//@Cacheable(value = true, interval = 60 * 60 * 1000, direct = true)
public class MTable extends BaseEntity {
@Id
@Column(comment = "[表ID]")
private Integer tableid;
private String name;
private String alias; //表别名全库唯一程序自动生成
private String comment;
@Column(length = 64, comment = "[表名称]")
private String tablename;
@Column(length = 15, unique = true, comment = "[表别名]全库唯一,程序自动生成")
private String alias;
@Column(comment = "[表字段]")
private List<Field> items;
private String sysPlatId; //所属系统平台
private String dbPlatId; //所属数据平台
private String catalog; //所在database
private Integer status; //状态 0 默认 9删除
private Integer hv;//临时
@Column(length = 64, comment = "[表注释]")
private String comment;
@Column(comment = "[临时]")
private int hv;
@Column(comment = "[状态]0 默认, 9删除'")
private int status;
@Column(updatable = false,comment = "[所属系统平台]")
private Integer platid;
@Column(comment = "[所属数据平台]")
private Integer dbid;
@Column(length = 32, comment = "[所在database]")
private String catalog;
// ------------------------------------------------
public static MetaTable toAs(net.tccn.base.dbq.table.Table table) {
public static MTable toAs(net.tccn.base.dbq.table.Table table) {
List<Field> fields = table.getColumns().stream().map(Field::toAs).collect(Collectors.toList());
MetaTable _bean = new MetaTable();
_bean.setName(table.getName());
MTable _bean = new MTable();
_bean.setTablename(table.getName());
_bean.setComment(table.getComment());
_bean.setCatalog(table.getCatalog());
_bean.setItems(fields);

View File

@@ -1,21 +0,0 @@
package net.tccn.meta;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/25 16:22.
*/
@Getter
@Setter
@Table(name = "MetaLink", catalog = "db_meta")
public class MetaLink extends Doc<MetaLink> {
public static MetaLink dao = Doc.dao(MetaLink.class);
private String[] tables;
private Map<String, String> link;
}

View File

@@ -1,36 +0,0 @@
package net.tccn.meta;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by liangxianyou at 2018/12/24 16:15.
*/
@Getter
@Setter
@Table(name = "MetaService", catalog = "db_meta")
public class MetaService extends Doc<MetaService> {
public static MetaService dao = Doc.dao(MetaService.class);
private String name; //业务标识
private String table; //主体表别名
private String comment; //业务中文名
private String sysPlatId; //平台id
private List<Map<String,String>> shows = new ArrayList<>();
private List<FromItem> edits = new ArrayList<>();
private List<Map<String,String>> details = new ArrayList<>();
private Map<String, String> dels = new HashMap<>();
private List<Filter> filters = new ArrayList<>();//{name:"", label:"", checked:true, }
private List<Map<String,String>> exports = new ArrayList<>();
//------
}

View File

@@ -2,11 +2,12 @@ package net.tccn.meta;
import net.tccn.base.*;
import net.tccn.base.dbq.table.Field;
import net.tccn.plat.MetaPlat;
import net.tccn.plat.MPlat;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -19,35 +20,38 @@ public class MetadataService extends BaseService { //arango
//----------- 元数据管理 ---------------
@RestMapping(name = "tablelist", comment = "table列表")
public JBean tableList(@RestParam(name = "platToken") String token, String catalog, String dbPlatId, String name) {
public JBean tableList(@RestParam(name = "plattoken") String token, String catalog, Integer dbid, String name) {
JBean jBean = new JBean();
List<Kv> list = MetaKit.getMetaTables().stream().filter(x
List<Kv> list = MetaKit.getMTables().stream().filter(x
-> (isEmpty(catalog) || catalog.equals(x.getCatalog())) &&
(isEmpty(dbPlatId) || dbPlatId.equals(x.getDbPlatId())) &&
(isEmpty(name) || x.getName().contains(name)) &&
(isEmpty(token) || x.getSysPlatId().equals(platId(token))) &&
(isEmpty(dbid) || dbid == (int) x.getDbid()) &&
(isEmpty(name) || x.getTablename().contains(name)) &&
(isEmpty(token) || x.getPlatid().equals(platId(token))) &&
(isEmpty(x.getStatus()) || x.getStatus() != 9)
).map(x -> Kv.of("name", x.getName())
).map(x -> Kv.of("tablename", x.getTablename())
.set("comment", x.getComment())
.set("catalog", x.getCatalog())
.set("alias", x.getAlias())
.set("dbPlatId", x.getDbPlatId())
.set("dbid", x.getDbid())
.set("tableid", x.getTableid())
.set("linkCount", MetaKit.getMetaLinks().stream().filter(link -> { // 关联表数量
String[] tables = link.getTables();
return x.getAlias().equals(tables[0]) || x.getAlias().equals(tables[1]);
}).count())
).collect(Collectors.toList());
).sorted(Comparator.comparing(x -> -x.getInt("tableid")))
.collect(Collectors.toList());
return jBean.setBody(list);
}
@RestMapping(name = "service_list", comment = "业务列表")
public JBean serviceList(@RestParam(name = "platToken") String token) {
public JBean serviceList(@RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
List<MetaService> list = MetaKit.getMetaServices().stream()
.filter(x -> platId(token).equals(x.getSysPlatId()))
List<MService> list = MetaKit.getMetaServices().stream()
.filter(x -> platId(token).equals(x.getPlatid()))
.sorted(Comparator.comparing(MService::getServid).reversed())
.collect(Collectors.toList());
jBean.setBody(list);
@@ -55,10 +59,10 @@ public class MetadataService extends BaseService { //arango
}
@RestMapping(name = "tableinfo", comment = "table详情")
public JBean tableInfo(@RestParam(name = "platToken") String token, String name, String alias) {
public JBean tableInfo(@RestParam(name = "plattoken") String token, String name, String alias) {
JBean jBean = new JBean();
MetaTable metaTable = null;
MTable metaTable = null;
if (!isEmpty(name)) {
metaTable = MetaKit.getMetaTable(name, token);
}
@@ -70,11 +74,11 @@ public class MetadataService extends BaseService { //arango
}
@RestMapping(name = "service_save", comment = "service信息保存")
public JBean serviceSave(@RestParam(name = "platToken") String token, @RestParam(name = "service") MetaService service) {
public JBean serviceSave(@RestParam(name = "plattoken") String token, @RestParam(name = "service") MService service) {
JBean jBean = new JBean();
do {
// 标识码非空校验
if (isEmpty(service.getTable())) {
if (isEmpty(service.getTablealias())) {
jBean.set(-1, "请选择业务主表");
break;
}
@@ -86,29 +90,29 @@ public class MetadataService extends BaseService { //arango
}
// 标识码重复校验
MetaService metaService = MetaKit.getMetaService(service.getName(), token);
if (metaService != null && !metaService.getKey().equals(service.getKey())) {
MService metaService = MetaKit.getMetaService(service.getName(), token);
if (metaService != null && metaService.getServid() != service.getServid()) {
jBean.set(-1, "业务标识码被占用,修改业务标识码重试");
break;
}
if (service.getKey() == null) {
service.setSysPlatId(platId(token));
if (service.getServid() == 0) {
service.setPlatid(platId(token));
}
MetaKit.save(service);
metaKit.save(service);
} while (false);
return jBean;
}
@RestMapping(name = "service_info", comment = "service基本信息")
public JBean serviceInfo(@RestParam(name = "platToken") String token, String name) {
MetaService metaService = MetaKit.getMetaService(name, token);
return JBean.by(0, "", metaService);
public JBean serviceInfo(@RestParam(name = "plattoken") String token, String name) {
MService mService = MetaKit.getMetaService(name, token);
return JBean.by(0, "", mService);
}
@RestMapping(name = "service_detail", comment = "service详情")
public JBean serviceDetail(@RestParam(name = "platToken") String token, String name) {
MetaService metaService = MetaKit.getMetaService(name, token);
public JBean serviceDetail(@RestParam(name = "plattoken") String token, String name) {
MService metaService = MetaKit.getMetaService(name, token);
Kv detail = MetaKit.buildeDetail(metaService);
return JBean.by(0, "", detail);
@@ -116,124 +120,125 @@ public class MetadataService extends BaseService { //arango
//修改item的排序
@RestMapping(name = "itemsort", comment = "字段排序")
public JBean itemSortSave(String alias, String[] items, @RestParam(name = "platToken") String token) {
public JBean itemSortSave(String alias, String[] items, @RestParam(name = "plattoken") String token) {
MetaTable metaTable = MetaKit.getMetaTableByAlias(alias);
MTable metaTable = MetaKit.getMetaTableByAlias(alias);
MetaKit.sortItem.apply(metaTable, items);
MetaKit.save(metaTable);
metaKit.save(metaTable);
return JBean.OK;
}
@RestMapping(name = "itemupdate", comment = "字段修改")
public JBean itemUpdate(String alias, List<Field> items, @RestParam(name = "platToken") String token) {
MetaTable metaTable = MetaKit.getMetaTableByAlias(alias);
public JBean itemUpdate(String alias, List<Field> items, @RestParam(name = "plattoken") String token) {
MTable metaTable = MetaKit.getMetaTableByAlias(alias);
MetaKit.itemUpdate.apply(metaTable, items);
MetaKit.save(metaTable);
metaKit.save(metaTable);
return JBean.OK;
}
@RestMapping(name = "showsort", comment = "展示字段修改")
public JBean showSort(String name, List<Map<String, String>> shows, @RestParam(name = "platToken") String token) {
public JBean showSort(String name, List<Map<String, String>> shows, @RestParam(name = "plattoken") String token) {
if (Utils.isEmpty(shows)) return null;
MetaService metaService = MetaKit.getMetaService(name, token);
MService metaService = MetaKit.getMetaService(name, token);
metaService.setShows(shows);
MetaKit.save(metaService);
metaKit.save(metaService);
return JBean.OK;
}
@RestMapping(name = "exportsave", comment = "导出配置保存")
public JBean exportSave(String name, List<Map<String, String>> exports, @RestParam(name = "platToken") String token) {
public JBean exportSave(String name, List<Map<String, String>> exports, @RestParam(name = "plattoken") String token) {
if (Utils.isEmpty(exports)) return null;
MetaService metaService = MetaKit.getMetaService(name, token);
MService metaService = MetaKit.getMetaService(name, token);
metaService.setExports(exports);
MetaKit.save(metaService);
metaKit.save(metaService);
return JBean.OK;
}
@RestMapping(name = "detailsave", comment = "详情配置保存")
public JBean detailSave(String name, List<Map<String, String>> details, @RestParam(name = "platToken") String token) {
public JBean detailSave(String name, List<Map<String, String>> details, @RestParam(name = "plattoken") String token) {
if (Utils.isEmpty(details)) return null;
MetaService metaService = MetaKit.getMetaService(name, token);
MService metaService = MetaKit.getMetaService(name, token);
metaService.setDetails(details);
MetaKit.save(metaService);
metaKit.save(metaService);
return JBean.OK;
}
@RestMapping(name = "editsave", comment = "表单配置保存")
public JBean editSave(String name, List<FromItem> edits, @RestParam(name = "platToken") String token) {
public JBean editSave(String name, List<FromItem> edits, @RestParam(name = "plattoken") String token) {
if (Utils.isEmpty(edits)) return null;
MetaService metaService = MetaKit.getMetaService(name, token);
MService metaService = MetaKit.getMetaService(name, token);
metaService.setEdits(edits);
MetaKit.save(metaService);
metaKit.save(metaService);
return JBean.OK;
}
@RestMapping(name = "delsave", comment = "删除配置保存")
public JBean delSave(String name, Map<String, String> dels, @RestParam(name = "platToken") String token) {
/*@RestMapping(name = "delsave", comment = "删除配置保存")
public JBean delSave(String name, Map<String, String> dels, @RestParam(name = "plattoken") String token) {
if (Utils.isEmpty(dels)) return null;
MetaService metaService = MetaKit.getMetaService(name, token);
MService metaService = MetaKit.getMetaService(name, token);
metaService.setDels(dels);
MetaKit.save(metaService);
return JBean.OK;
}
}*/
@RestMapping(name = "importsort", comment = "导入字段保存")
public JBean importSort(String serviceKey, List<String> items, @RestParam(name = "platToken") String token) {
public JBean importSort(String serviceKey, List<String> items, @RestParam(name = "plattoken") String token) {
if (Utils.isEmpty(items)) return null;
MetaTable metaTable = MetaKit.getMetaTable(serviceKey, token);
MTable metaTable = MetaKit.getMetaTable(serviceKey, token);
//fixme: metaTable.setImports(items);
MetaKit.save(metaTable);
metaKit.save(metaTable);
return JBean.OK;
}
@RestMapping(name = "dbplatupdate", comment = "数据平台修改")
public JBean dbPlatUpdate(MetaTable metaTable, @RestParam(name = "platToken") String token) {
public JBean dbPlatUpdate(MTable metaTable, @RestParam(name = "plattoken") String token) {
MetaTable _metaTable = MetaKit.getMetaTableByKey(metaTable.getKey());
_metaTable.setName(metaTable.getName());
MTable _metaTable = MetaKit.getMetaTableByKey(metaTable.getTableid());
_metaTable.setTablename(metaTable.getTablename());
_metaTable.setComment(metaTable.getComment());
_metaTable.setCatalog(metaTable.getCatalog());
_metaTable.setDbPlatId(metaTable.getDbPlatId());
_metaTable.setDbid(metaTable.getDbid());
_metaTable.setCatalog(metaTable.getCatalog());
MetaKit.save(_metaTable);
metaKit.save(_metaTable);
return JBean.OK;
}
@RestMapping(name = "filter_update", comment = "查询配置修改")
public JBean filterUpdate(String name, List<Filter> filters, @RestParam(name = "platToken") String token) {
MetaService metaService = MetaKit.getMetaService(name, token);
public JBean filterUpdate(String name, List<Filter> filters, @RestParam(name = "plattoken") String token) {
MService metaService = MetaKit.getMetaService(name, token);
metaService.setFilters(filters);
MetaKit.save(metaService);
metaKit.save(metaService);
return JBean.OK;
}
@RestMapping(name = "table_link_list", comment = "实体表包含link信息的列表,(metalink 管理页面使用)")
public JBean tableLinkList(@RestParam(name = "platToken") String token) {
public JBean tableLinkList(@RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
List<Kv> list = MetaKit.getMetaTables().stream()
.filter(x -> (isEmpty(token) || x.getSysPlatId().equals(platId(token)))
&& (x.getStatus() == null || x.getStatus() != 9)
List<Kv> list = MetaKit.getMTables().stream()
.filter(x -> (isEmpty(token) || x.getPlatid().equals(platId(token)))
&& (x.getStatus() != 9)
).map(x -> {
Kv kv = Kv.of("name", x.getName())
Kv kv = Kv.of("tablename", x.getTablename())
.set("comment", x.getComment())
.set("alias", x.getAlias())
.set("tableid", x.getTableid())
.set("linkCount", 0);
//关联表数量
@@ -244,7 +249,8 @@ public class MetadataService extends BaseService { //arango
kv.set("linkCount", count);
return kv;
}).collect(Collectors.toList());
}).sorted(Comparator.comparingInt(x -> -x.getInt("tableid")))
.collect(Collectors.toList());
return jBean.setBody(list);
}
@@ -257,12 +263,13 @@ public class MetadataService extends BaseService { //arango
List<Kv> list = MetaKit.getMetaLinks().stream().filter(x ->
x.getTables()[0].equals(alias) || x.getTables()[1].equals(alias)
).map(x -> {
MetaTable linkTable = MetaKit.getMetaTableByAlias(x.getTables()[0].equals(alias) ? x.getTables()[1] : x.getTables()[0]);
Kv kv = Kv.of("name", linkTable.getName())
MTable linkTable = MetaKit.getMetaTableByAlias(x.getTables()[0].equals(alias) ? x.getTables()[1] : x.getTables()[0]);
Kv kv = Kv.of("tablename", linkTable.getTablename())
.set("alias", linkTable.getAlias())
.set("comment", linkTable.getComment())
.set("linkSize", x.getLink().size())
.set("link", x.getLink());
.set("linkSize", x.getLinks().size())
.set("links", x.getLinks());
return kv;
}).collect(Collectors.toList());
@@ -273,7 +280,7 @@ public class MetadataService extends BaseService { //arango
public JBean linkList(String alias) {
JBean jBean = new JBean();
List<MetaLink> links = MetaKit.getMetaLinks();
List<MLink> links = MetaKit.getMetaLinks();
if (!isEmpty(alias)) {
links = Utils.filter(links, x -> x.getTables()[0].equals(alias) || x.getTables()[1].equals(alias));
@@ -283,8 +290,8 @@ public class MetadataService extends BaseService { //arango
}
@RestMapping(name = "link_save", comment = "实体关系列表")
public JBean linkSave(MetaLink link, @RestParam(name = "platToken") String token) {
MetaKit.save(link);
public JBean linkSave(MLink link, @RestParam(name = "plattoken") String token) {
metaKit.save(link);
return JBean.OK;
}
@@ -292,7 +299,7 @@ public class MetadataService extends BaseService { //arango
@RestMapping(name = "plat_list", comment = "平台列表")
public JBean platList() {
JBean jBean = new JBean();
List<MetaPlat> plats = MetaKit.getSysPlats();
List<MPlat> plats = MetaKit.getMPlats();
return jBean.setBody(plats);
}
@@ -300,13 +307,13 @@ public class MetadataService extends BaseService { //arango
@RestMapping(name = "refresh", comment = "刷新服务端缓存数据")
public JBean refresh() {
JBean jBean = new JBean();
MetaKit.init();
metaKit.init(null);
return jBean;
}
// ------------------------------------ 对外服务 --------------------------------------
@RestMapping(name = "cfg", auth = false, comment = " 功能配置")
public JBean cfg(String name, @RestParam(name = "platToken") String token) {
public JBean cfg(String name, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
Map cfg = MetaKit.cfg(name, token);

View File

@@ -1,10 +1,10 @@
package net.tccn.open;
import net.tccn.base.*;
import net.tccn.base.dbq.DbExecutors;
import net.tccn.base.dbq.fbean.FBean;
import net.tccn.base.dbq.*;
import net.tccn.dict.DictKit;
import net.tccn.meta.MetaService;
import net.tccn.meta.MService;
import org.redkale.net.http.HttpScope;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
@@ -23,10 +23,10 @@ import java.util.concurrent.ExecutionException;
public class DataService extends BaseService {
@RestMapping(name = "list", auth = false, comment = "数据分页列表")
public JBean findList(FBean fBean, @RestParam(name = "platToken") String token) {
public JBean findList(FBean fBean, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
try {
fBean.setPlatToken(token);
fBean.setPlattoken(token);
fBean.setType("list");
PageBean page = DbExecutors.findPage(fBean);
jBean.setBody(page);
@@ -38,7 +38,7 @@ public class DataService extends BaseService {
}
@RestMapping(name = "save", comment = "数据保存")
public JBean save(String name, Map<String, String> data, @RestParam(name = "platToken") String token) {
public JBean save(String name, Map<String, String> data, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
try {
DbExecutors.save(name, data, token);
@@ -50,9 +50,9 @@ public class DataService extends BaseService {
}
@RestMapping(name = "export", auth = false, comment = "数据导出excel")
public HttpScope export(FBean fBean, String fileName, @RestParam(name = "platToken") String token) {
public HttpScope export(FBean fBean, String fileName, @RestParam(name = "plattoken") String token) {
try {
fBean.setPlatToken(token);
fBean.setPlattoken(token);
fBean.setType("export");
PageBean page = DbExecutors.findPage(fBean);
Kv heads = MetaKit.cfgExport(fBean.getName(), token);
@@ -64,7 +64,7 @@ public class DataService extends BaseService {
List<Map> data = page.getRows();
//dataDeal
MetaService metaService = MetaKit.getMetaService(fBean.getName(), token);
MService metaService = MetaKit.getMetaService(fBean.getName(), token);
List<Map<String, String>> exports = metaService.getExports();
DictKit dictKit = DictKit.use(token);
//字典映射 、日期转换 、时间转换
@@ -107,8 +107,8 @@ public class DataService extends BaseService {
return HttpScope.refer("excel");
}
@RestMapping(name = "del", auth = false, comment = "数据删除")
public JBean del(String name, Map<String, String> data, @RestParam(name = "platToken") String token) {
/*@RestMapping(name = "del", auth = false, comment = "数据删除")
public JBean del(String name, Map<String, String> data, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
try {
DbExecutors.del(name, data, token);
@@ -116,5 +116,5 @@ public class DataService extends BaseService {
jBean.set(-1, "删除数据失败!");
}
return jBean;
}
}*/
}

View File

@@ -0,0 +1,30 @@
package net.tccn.plat;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.BaseEntity;
import org.redkale.annotation.Comment;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
@Getter
@Setter
@Entity
public class MPlat extends BaseEntity {
@Id
@Comment("[平台ID]")
private Integer platid;
@Comment("[平台名称]")
private String platname;
@Comment("[平台令牌]")
private String plattoken;
@Comment("[备注信息]")
private String remark;
/*@Comment("[创建时间]")
@Column(updatable = false)
private Long createtime;*/
}

View File

@@ -1,3 +1,4 @@
/*
package net.tccn.plat;
import lombok.Getter;
@@ -7,10 +8,12 @@ import org.redkale.convert.ConvertColumn;
import javax.persistence.Table;
*/
/**
* 数据库平台
* @author: liangxianyou at 2018/11/14 12:58.
*/
*//*
@Getter
@Setter
@Table(name = "MetaDb", catalog = "db_meta")
@@ -37,8 +40,9 @@ public class MetaDb extends Doc<MetaDb> {
return user + ":" + pwd + "@" + host;
}
@ConvertColumn(ignore = true)
//@ConvertColumn(ignore = true)
public String getPwd() {
return pwd;
}
}
*/

View File

@@ -1,3 +1,4 @@
/*
package net.tccn.plat;
import lombok.Getter;
@@ -5,9 +6,11 @@ import lombok.Setter;
import net.tccn.base.arango.Doc;
import javax.persistence.Table;
*/
/**
* @author: liangxianyou at 2018/11/26 17:46.
*/
*//*
@Getter
@Setter
@Table(name = "MetaPlat", catalog = "db_meta")
@@ -25,3 +28,4 @@ public class MetaPlat extends Doc<MetaPlat> {
}
}
*/

View File

@@ -3,32 +3,37 @@ package net.tccn.plat;
import net.tccn.base.BaseService;
import net.tccn.base.JBean;
import net.tccn.base.MetaKit;
import net.tccn.base.PageBean;
import net.tccn.base.Utils;
import net.tccn.base.dbq.jdbc.api.DbAccount;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.source.FilterBean;
import org.redkale.source.Flipper;
import org.redkale.util.Comment;
import java.util.List;
import org.redkale.util.Sheet;
@RestService(name = "plat", automapping = true, comment = "业务/数据平台")
public class PlatService extends BaseService {
@RestMapping(name = "list", comment = "平台列表")
public JBean list(MetaPlat plat, Flipper flipper) {
public JBean list(MPlat plat, Flipper flipper) {
JBean jBean = new JBean();
//PageBean<SysPlat> page = SysPlat.dao.findPage(plat, flipper);
List<MetaPlat> list = MetaKit.getSysPlats();
PageBean page = PageBean.by(list, list.size());
/*List<MetaPlat> list = MetaKit.getSysPlats();
PageBean page = PageBean.by(list, list.size());*/
return jBean.setBody(page);
Sheet<MPlat> sheet = metaSource.querySheet(MPlat.class, flipper, (FilterBean) null);
return jBean.setBody(sheet);
}
@Comment("平台信息保存")
public JBean save(MetaPlat plat) {
MetaKit.save(plat);
public JBean save(MPlat plat) {
if (!Utils.isEmpty(plat.getPlatid())) {
metaSource.update(plat);
} else {
metaSource.insert(plat);
}
return JBean.OK;
}
@@ -40,18 +45,29 @@ public class PlatService extends BaseService {
//------------------------
@RestMapping(name = "db_list", comment = "数据源列表")
public JBean dbList(MetaDb plat, Flipper flipper) {
public JBean dbList(DbAccount plat, Flipper flipper) {
JBean jBean = new JBean();
List<DbAccount> list = MetaKit.getDbPlats();
PageBean page = PageBean.by(list, list.size());
/*List<DbAccount> list = MetaKit.getDbPlats();
PageBean page = PageBean.by(list, list.size());*/
return jBean.setBody(page);
Sheet<DbAccount> sheet = metaSource.querySheet(DbAccount.class, flipper, (FilterBean) null);
return jBean.setBody(sheet);
}
@RestMapping(name = "db_save", comment = "数据源信息保存")
public JBean dbSave(MetaDb plat) {
MetaKit.save(plat);
public JBean dbSave(DbAccount plat) {
// MetaKit.save(plat);
if (!Utils.isEmpty(plat.getDbid()) || plat.getDbid() != 0) {
if (Utils.isEmpty(plat.getPwd())) {
DbAccount account = MetaKit.getDbPlat(plat.getDbid());
plat.setPwd(account.getPwd());
}
metaSource.update(plat);
} else {
metaSource.insert(plat);
}
return JBean.OK;
}

View File

@@ -8,7 +8,7 @@ import net.tccn.base.dbq.jdbc.api.DbAccount;
import net.tccn.base.dbq.jdbc.api.DbKit;
import net.tccn.base.dbq.table.Column;
import net.tccn.base.dbq.table.Table;
import net.tccn.meta.MetaTable;
import net.tccn.meta.MTable;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
@@ -23,13 +23,13 @@ import java.util.stream.Stream;
public class _DbService extends BaseService {
@RestMapping(name = "catalog_list", comment = "获取数据源的database")
public JBean catalogList(DbAccount dbAccount, String dbPlatId) {
public JBean catalogList(DbAccount dbAccount, int dbid) {
JBean jBean = new JBean();
DbKit dbKit = null;
if (dbAccount != null) {
dbKit = new DbKit(dbAccount, "");
} else {
dbKit = MetaKit.getDbKit(dbPlatId, "");
dbKit = MetaKit.getDbKit(dbid, "");
}
List<Map> list = dbKit.queryList("SHOW DATABASES;", Map.class);
@@ -40,29 +40,29 @@ public class _DbService extends BaseService {
}
@RestMapping(name = "table_list", comment = "数据库表列表")
public List<Table> tableList(String dbPlatId, String catalog, String[] tables) {
DbKit dbKit = MetaKit.getDbKit(dbPlatId, "");
public List<Table> tableList(int dbid, String catalog, String[] tables) {
DbKit dbKit = MetaKit.getDbKit(dbid, "");
String sql = tplKit.getTpl("db.table_list", Kv.of("catalog", catalog).set("tables", tables));
return dbKit.queryList(sql, Table.class);
}
@RestMapping(ignore = true)
public List<Table> tableInfoList(String dbPlatId, String catalog, String[] tables) {
public List<Table> tableInfoList(int dbid, String catalog, String[] tables) {
List<Table> list = new ArrayList<>(tables.length);
for (String table : tables) {
list.add(tableInfo(dbPlatId, catalog, table));
list.add(tableInfo(dbid, catalog, table));
}
return list;
}
@RestMapping(name = "table_info", comment = "数据库表详情")
public JBean MetatableInfo(String dbPlatId, String catalog, String tableName) {
public JBean MetatableInfo(int dbid, String catalog, String tableName) {
JBean jBean = new JBean();
try {
Table table = tableInfo(dbPlatId, catalog, tableName);
Table table = tableInfo(dbid, catalog, tableName);
jBean.setBody(MetaTable.toAs(table));
jBean.setBody(MTable.toAs(table));
} catch (Exception e) {
jBean.set(-1, "查询表信息失败");
new IllegalArgumentException("查询表信息失败", e);
@@ -71,8 +71,8 @@ public class _DbService extends BaseService {
}
@RestMapping(ignore = true, comment = "查询表信息")
public Table tableInfo(String dbPlatId, String catalog, String tableName) {
DbKit dbKit = MetaKit.getDbKit(dbPlatId, catalog);
public Table tableInfo(int dbid, String catalog, String tableName) {
DbKit dbKit = MetaKit.getDbKit(dbid, catalog);
String sql = tplKit.getTpl("db.table_list", Kv.of("table", tableName));
String columnSql = String.format("SHOW FULL COLUMNS FROM %s.`%s`", catalog, tableName);
@@ -92,12 +92,121 @@ public class _DbService extends BaseService {
}
@RestMapping(name = "table_create", comment = "新建表[mysql]")
public JBean tableCreate(String dbPlatId, String catalog, String sql) {
public JBean tableCreate(int dbid, String catalog, String sql) {
JBean jBean = new JBean();
DbKit dbKit = MetaKit.getDbKit(dbPlatId, catalog);
DbKit dbKit = MetaKit.getDbKit(dbid, catalog);
dbKit.createTable(sql);
return jBean;
}
// 比对表结构
/*@RestMapping(name = "table_compare", comment = "对比表结构")
public Kv tableCompare(String dbPlatA, String dbPlatB, String catalog) {
String sql = String.format("SELECT table_name 'tableName', column_name 'columnName', column_comment 'columnComment',column_type 'columnType',column_default 'columnDefault', is_nullable 'isNullable'" +
" FROM INFORMATION_SCHEMA.COLUMNS" +
" WHERE table_schema = '%s'", catalog);
List<Column> listA = MetaKit.getDbKit(dbPlatA, catalog).queryList(sql, Column.class);
List<Column> listB = MetaKit.getDbKit(dbPlatB, catalog).queryList(sql, Column.class);
Map<String, List<Column>> ddlA = Utils.group(listA, Column::getTableName);
Map<String, List<Column>> ddlB = Utils.group(listB, Column::getTableName);
Set<String> same = new HashSet<>(); // table_name;
List<Kv<String, Object>> differ = new ArrayList<>(); // 不相同的表,以及对应 A、B库的字段信息如[{"tableName": "", A: [{}], B: [{}], dif: [{}] }]
Kv<String, List<Table>> without = Kv.of(); // A,B不在对方库的表{A: [{}], B: [{}]}
ddlA.forEach((tableName, columns) -> {
// A 有B 无
if (!ddlB.containsKey(tableName)) {
List<Table> tables = without.getOrDefault("A", new ArrayList<>());
tables.add(new Table(tableName, columns));
without.set("A", tables);
}
// TODO 相同 、差异比较
List<Column> columns2 = ddlB.get(tableName);
if (columns2 == null) {
return;
}
List<Kv<String, Object>> dif = new ArrayList<>();
for (Column column : columns) {
Column column2 = columns2.stream().filter(c -> c.getColumnName().equals(column.getColumnName())).findFirst().orElse(null);
if (column2 == null) {
dif.add(Kv.of("column", column.getColumnName()).set("diff", "column not exist in B"));
} else {
if (!column.getColumnName().equals(column2.getColumnName())) {
dif.add(Kv.of("column", column.getColumnName()).set( "diff", "column name not same"));
}
if (!column.getColumnComment().equals(column2.getColumnComment())) {
dif.add(Kv.of("column", column.getColumnName()).set( "diff", "column comment not same"));
}
if (!column.getColumnType().equals(column2.getColumnType())) {
dif.add(Kv.of("column", column.getColumnName()).set( "diff", "column type not same"));
}
if (!column.getColumnDefault().equals(column2.getColumnDefault())) {
dif.add(Kv.of("column", column.getColumnName()).set( "diff", "column default not same"));
}
if (!column.getIsNullable().equals(column2.getIsNullable())) {
dif.add(Kv.of("column", column.getColumnName()).set( "diff", "column nullable not same"));
}
}
}
// columns2 中有 columns 中没有
for (Column column2 : columns2) {
if (!columns.stream().anyMatch(c -> c.getColumnName().equals(column2.getColumnName()))) {
dif.add(Kv.of("column", column2.getColumnName()).set( "diff", "column not exist in A"));
}
}
if (dif.size() > 0) {
differ.add(Kv.of("tableName", tableName).set( "A", columns).set( "B", columns2).set( "dif", dif));
}
});
// B 有A 无
ddlB.forEach((tableName, columns) -> {
if (ddlA.containsKey(tableName)) {
return;
}
List<Table> tables = without.getOrDefault("B", new ArrayList<>());
tables.add(new Table(tableName, columns));
without.set("B", tables);
});
Kv retKv = Kv.of(); // 返回结果
retKv.set("same", same);
retKv.set("differ", differ);
retKv.set("without", without);
return retKv;
}
@Getter
@Setter
static class Table {
String tableName;
List<Column> columns;
public Table(String tableName, List<Column> columns) {
this.tableName = tableName;
this.columns = columns;
}
}
@Getter
@Setter
static class Column {
@ConvertColumn(ignore = true)
private String tableName;
private String columnName;
private String columnComment;
private String columnType;
private String columnDefault;
private String isNullable;
}*/
}

View File

@@ -6,7 +6,7 @@ import net.tccn.base.Kv;
import net.tccn.base.MetaKit;
import net.tccn.base.dbq.table.Table;
import net.tccn.file._FileService;
import net.tccn.meta.MetaTable;
import net.tccn.meta.MTable;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
@@ -35,8 +35,8 @@ public class _TableService extends BaseService {
// excel
String filePath,
//mysql {数据库连接账号、数据源id、数据库database数组}
String dbPlatId, String catalog,
@RestParam(name = "platToken") String token) {
int dbid, String catalog,
@RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
@@ -44,21 +44,21 @@ public class _TableService extends BaseService {
jBean = fileService.data(filePath, token);
} else if ("mysql".equals(cate)) {
List<Table> list = dbService.tableList(dbPlatId, catalog, null);
List<Table> list = dbService.tableList(dbid, catalog, null);
String[] tableArr = list.stream().map(Table::getName).toArray(String[]::new);
List<String> hv = MetaKit.tableExist(tableArr, token);
List<MetaTable> sheets = new ArrayList<>();
List<MTable> sheets = new ArrayList<>();
list.forEach(x -> {
MetaTable bean = MetaTable.toAs(x);
MTable bean = MTable.toAs(x);
bean.setHv(hv.contains(x.getName()) ? 1 : 0);
sheets.add(bean);
});
//对数据分组后返回
Kv<String, MetaTable> data = Kv.of();
sheets.forEach(x -> data.set(x.getName(), x));
Kv<String, MTable> data = Kv.of();
sheets.forEach(x -> data.set(x.getTablename(), x));
jBean.setBody(data);
}
@@ -67,63 +67,65 @@ public class _TableService extends BaseService {
}
@RestMapping(name = "sheet_info", comment = "sheet详情")
public JBean sheetInfo(String cate, @RestParam(name = "platToken") String token,
public JBean sheetInfo(String cate, @RestParam(name = "plattoken") String token,
// excel
String filePath, String sheetName,
// mysql
String dbPlatId, String catalog, String tableName) {
int dbid, String catalog, String tableName) {
if ("excel".equals(cate)) {
return fileService.sheetData(filePath, sheetName, token);
} else if ("mysql".equals(cate)) {
return new JBean().setBody(dbService.tableInfo(dbPlatId, catalog, tableName));
return new JBean().setBody(dbService.tableInfo(dbid, catalog, tableName));
}
return null;
}
@RestMapping(name = "table_save", comment = "保存数据源实体到元数据实体表")
public JBean tableSave(String cate, @RestParam(name = "platToken") String token,
public JBean tableSave(String cate, @RestParam(name = "plattoken") String token,
String filePath, String[] sheetNames,
String dbPlatId, String catalog, String[] tableArr) {
int dbid, String catalog, String[] tableArr) {
if ("excel".equals(cate)) {
return fileService.saveSheet(sheetNames, filePath, token);
} else if ("mysql".equals(cate)) {
List<String> hv = MetaKit.tableExist(tableArr, token);
List<Table> tables = dbService.tableInfoList(dbPlatId, catalog, tableArr);
List<Table> tables = dbService.tableInfoList(dbid, catalog, tableArr);
MetaTable[] metaTables = tables.stream()
MTable[] metaTables = tables.stream()
.filter(t -> !hv.contains(t.getName())) // 去除同名
.map(t -> {
MetaTable metaTable = MetaTable.toAs(t);
MTable metaTable = MTable.toAs(t);
metaTable.setCatalog(catalog);
metaTable.setDbPlatId(dbPlatId);
metaTable.setAlias(MetaKit.nextAlias());// 表别名
metaTable.setSysPlatId(platId(token));
metaTable.setDbid(dbid);
metaTable.setAlias(metaKit.nextAlias());// 表别名
metaTable.setPlatid(platId(token));
return metaTable;
}).toArray(MetaTable[]::new);
MetaKit.save(metaTables);
}).toArray(MTable[]::new);
for (MTable table : metaTables) {
metaKit.save(table);
}
// 已经有的表 更新
MetaTable[] metaTables2 = tables.stream()
MTable[] metaTables2 = tables.stream()
.filter(t -> hv.contains(t.getName())) // 去除同名
.map(t -> {
MetaTable table = MetaKit.getMetaTable(t.getName(), token);
MTable table = MetaKit.getMetaTable(t.getName(), token);
MetaTable metaTable = MetaTable.toAs(t);
MTable metaTable = MTable.toAs(t);
table.setCatalog(catalog);
table.setDbPlatId(dbPlatId);
table.setDbid(dbid);
table.setAlias(table.getAlias());// 表别名
table.setSysPlatId(platId(token));
table.setPlatid(platId(token));
table.setItems(metaTable.getItems());
table.setComment(metaTable.getComment());
return table;
}).toArray(MetaTable[]::new);
MetaKit.save(metaTables2);
}).toArray(MTable[]::new);
for (MTable table : metaTables2) {
metaKit.save(table);
}
}
return JBean.OK;
}

View File

@@ -1,3 +1,4 @@
/*
package net.tccn.qtask;
import lombok.Getter;
@@ -6,9 +7,11 @@ import net.tccn.base.arango.Doc;
import javax.persistence.Table;
*/
/**
* Created by liangxianyou at 2019/4/20 20:04.
*/
*//*
@Getter
@Setter
@Table(name = "DbTask", catalog = "db_meta")
@@ -18,13 +21,14 @@ public class DbTask extends Doc<DbTask> {
private String name; // 任务标识码
private String title; // 任务名称
//private String cate; // 任务类型
private String dbPlatId; // 数据平台id
private int dbid; // 数据平台id
private String catalog; //
private String content; // 任务内容
private String remark; // 任务备注
private String para; // 任务参数
private String sysPlatId; // 平台id
private String platid; // 平台id
// ---------------------
}
*/

View File

@@ -1,33 +1,25 @@
package net.tccn.qtask;
import net.tccn.base.BaseService;
import net.tccn.base.JBean;
import net.tccn.base.Kv;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
import java.util.Map;
import org.redkale.service.RetResult;
/**
* @author: liangxianyou at 2018/11/13 18:14.
*/
@RestService(automapping = true, comment = "qtask查询服务")
@RestService(name = "qtask", automapping = true, comment = "qtask查询服务")
public class QtaskService extends BaseService {
// 调用示例: http://qtask_service_addr_xxxxxx/qtask/call?name=abxx&platToken=3421432&para={h:1}
// 调用示例: http://qtask_service_addr_xxxxxx/qtask/call?name=abxx&plattoken=3421432&para={h:1}
@RestMapping(name = "call", auth = false)
public JBean call(String name, Map<String, String> para, @RestParam(name = "platToken") String token) {
JBean jBean = new JBean();
Kv kv = Kv.of();
if (para != null) {
para.forEach((k, v) -> kv.put(k, v));
public RetResult<Object> call(String name, Kv<String, String> para, @RestParam(name = "plattoken") String plattoken) {
if (para == null) {
para = Kv.of();
}
jBean.setBody(TaskKit.taskRun(name, token, kv));
return jBean;
return RetResult.success(TaskKit.taskRun(name, plattoken, para));
}
}

View File

@@ -5,9 +5,10 @@ import lombok.Setter;
import net.tccn.base.Kv;
import net.tccn.base.dbq.jdbc.api.DbAccount;
/**
* |- dbp: 调用谁, 参数,
* |- 谁:谁(干什么) => dbPlatId + content (在程序的世界每个个体,往往都有其明确的职责)
* |- 谁:谁(干什么) => dbid + content (在程序的世界每个个体,往往都有其明确的职责)
* |-
* 任务对象
*/
@@ -16,7 +17,7 @@ import net.tccn.base.dbq.jdbc.api.DbAccount;
public class Task {
private String name; // 任务标识,同一系统唯一
private String dbPlatId; // 数据源id
private int dbid; // 数据源id
private String catalog; // 数据库 database
private String content; // 任务内容

View File

@@ -1,11 +1,10 @@
package net.tccn.qtask;
import dev.zhub.mk.qtask.QTask;
import net.tccn.base.Kv;
import net.tccn.base.MetaKit;
import org.redkale.convert.json.JsonConvert;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -13,61 +12,40 @@ import java.util.Optional;
* Created by liangxianyou at 2019/4/20 19:59.
*/
public class TaskKit {
static final JsonConvert convert = JsonConvert.root();
private static List<DbTask> taskEntities;
private static List<QTask> qTasks;
static {
init();
public static void init(List<QTask> tasks) {
qTasks = tasks;
}
public static void init() {
taskEntities = MetaKit.getTaskEntities();
}
public static Task buildTask(String name, String platToken, Kv para) {
DbTask taskEntity = getTaskEntity(name, platToken);
public static Task buildTask(String name, String plattoken, Kv para) {
QTask taskEntity = getTaskEntity(name, plattoken);
return buildTask(taskEntity, para);
}
public static Task buildTask(DbTask taskEntity, Kv para) {
Task task = new Task();
task.setName(taskEntity.getName());
task.setTitle(taskEntity.getTitle());
task.setContent(taskEntity.getContent());
task.setDbPlatId(taskEntity.getDbPlatId());
task.setCatalog(taskEntity.getCatalog());
Kv _para = Kv.of().putAll(para);
if (taskEntity.getPara() != null) {
try {
Map<String, String> map = convert.convertFrom(JsonConvert.TYPE_MAP_STRING_STRING, taskEntity.getPara());
map.forEach((k,v) -> _para.put(k, v));
} catch (Exception e) {
new IllegalArgumentException(String.format("fromJson error:[%s]",taskEntity.getPara()), e);
}
}
task.setPara(_para);
task.setDbAccount(MetaKit.getDbPlat(taskEntity.getDbPlatId()));
public static Task buildTask(dev.zhub.mk.qtask.QTask qTask, Kv para) {
Task task = qTask.createTask(para);
task.setDbAccount(MetaKit.getDbPlat(qTask.getDbid()));
return task;
}
public static DbTask getTaskEntity(String name, String platToken) {
public static QTask getTaskEntity(String name, String platid) {
Objects.requireNonNull(name);
Objects.requireNonNull(platToken);
Objects.requireNonNull(platid);
Optional<DbTask> any = taskEntities.stream()
.filter(x -> name.equals(x.getName()) && MetaKit.getPlatId(platToken).equals(x.getSysPlatId()))
Optional<QTask> any = qTasks.stream()
.filter(x -> name.equals(x.getName()) && MetaKit.getPlatId(platid).equals(x.getPlatid()))
.findAny();
return any.get();
}
public static Object taskRun(String name, String platToken, Kv para) {
Task task = buildTask(name, platToken, para);
public static Object taskRun(String name, String plattoken, Kv para) {
Task task = buildTask(name, plattoken, para);
return QRuner.query(task);
}
public static Object taskRun(DbTask entity) {
Task task = buildTask(entity, Kv.of());
public static Object taskRun(QTask qTask) {
Task task = buildTask(qTask, Kv.of());
return QRuner.query(task);
}
}

View File

@@ -1,31 +1,86 @@
package net.tccn.qtask;
import dev.zhub.mk.qtask.QTask;
import net.tccn.base.BaseService;
import net.tccn.base.JBean;
import net.tccn.base.MetaKit;
import net.tccn.base.PageBean;
import net.tccn.base.Utils;
import org.redkale.net.http.RestBody;
import org.redkale.net.http.RestHeader;
import org.redkale.net.http.RestParam;
import org.redkale.net.http.RestService;
import org.redkale.service.RetResult;
import org.redkale.source.ColumnValue;
import org.redkale.source.FilterNode;
import org.redkale.source.Flipper;
import org.redkale.util.Comment;
import org.redkale.util.Sheet;
@RestService(automapping = true)
public class _QtaskService extends BaseService {
@Comment("qtask列表")
public JBean list(DbTask task, Flipper flipper, @RestParam(name = "platToken") String token) {
if (task == null) {
public RetResult<Sheet<QTask>> list(Flipper flipper, @RestHeader(name = "plattoken") String token) {
flipper.sort("qtaskid DESC");
/*if (task == null) {
task = new DbTask();
}
task.setSysPlatId(platId(token));
PageBean<DbTask> page = DbTask.dao.findPage(task, flipper);
task.setplatid(platId(token));
return JBean.by(0, "", page);
PageBean<DbTask> page = DbTask.dao.findPage(task, flipper);*/
FilterNode node = FilterNode.create("platid", platId(token)).and("status", 10);
Sheet<QTask> sheet = metaSource.querySheet(QTask.class, flipper, node);
return RetResult.success(sheet);
}
@Comment("qtask保存")
public JBean save(DbTask task, @RestParam(name = "platToken") String token) {
public RetResult create(@RestHeader(name = "plattoken") String token,
@RestBody QTask task) {
if (Utils.isEmpty(task.getName())) {
return retError("任务KEY 不能为空");
}
if (Utils.isEmpty(task.getTitle())) {
return retError("任务名称 不能为空");
}
FilterNode node = FilterNode.create("name", task.getName()).and("platid", platId(token));
if (metaSource.exists(QTask.class, node)) {
return retError("任务KEY 不能重复");
}
task.setPlatid(platId(token));
metaSource.insert(task);
// 刷新缓存
metaKit.reloadxAsync(QTask.class);
return render();
}
public RetResult update(@RestHeader(name = "plattoken") String token,
@RestBody QTask task) {
metaSource.update(task);
// 刷新缓存
metaKit.reloadxAsync(QTask.class);
return render();
}
public RetResult delete(@RestHeader(name = "plattoken") String token,
@RestBody QTask task) {
metaSource.updateColumn(QTask.class, task.getQtaskid(), ColumnValue.create("status", 80));
// 刷新缓存
metaKit.reloadxAsync(QTask.class);
return render();
}
/*@Comment("qtask保存")
public JBean save(DbTask task, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
do {
@@ -36,7 +91,7 @@ public class _QtaskService extends BaseService {
// 同平台name 唯一校验
DbTask bean = new DbTask();
bean.setSysPlatId(platId(token));
bean.setplatid(platId(token));
bean.setName(task.getName());
DbTask entity = DbTask.dao.findFirst(bean);
@@ -48,7 +103,7 @@ public class _QtaskService extends BaseService {
if (task.getKey() != null) {
task.update();
} else {
task.setSysPlatId(platId(token));
task.setplatid(platId(token));
task.save();
}
MetaKit.reload(task);
@@ -57,10 +112,10 @@ public class _QtaskService extends BaseService {
return jBean;
}
}*/
@Comment("debug调试接口")
public JBean debug(DbTask task, @RestParam(name = "platToken") String token) {
public JBean debug(QTask task, @RestParam(name = "plattoken") String token) {
JBean jBean = new JBean();
Object res = TaskKit.taskRun(task);

View File

@@ -3,12 +3,16 @@ package net.tccn.qtask.impl;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.template.Engine;
import com.jfinal.template.Template;
import net.tccn.base.Kv;
import net.tccn.base.MetaKit;
import net.tccn.base.Utils;
import net.tccn.base.dbq.jdbc.api.DbKit;
import net.tccn.qtask.QTask;
import net.tccn.qtask.Task;
import java.util.Map;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class QTaskMysql extends QTaskAbs implements QTask {
@@ -23,7 +27,7 @@ public class QTaskMysql extends QTaskAbs implements QTask {
public QTaskMysql(Task task) {
super(task);
this.dbKit = MetaKit.getDbKit(task.getDbPlatId(), task.getCatalog());
this.dbKit = MetaKit.getDbKit(task.getDbid(), task.getCatalog());
}
@Override
@@ -31,6 +35,15 @@ public class QTaskMysql extends QTaskAbs implements QTask {
Template tpl = engine.getTemplateByString(task.getContent());
String sql = tpl.renderToString(getTask().getPara()).replaceAll("[\\s]+", " ");
// 聚合统计返回统计结果 TODO 待完善
if (sql.startsWith("UPDATE ") || sql.startsWith("update ")) {
return dbKit.exetuteUpdate(sql);
}
String countSql = Utils.parserCountSql(sql);
if (countSql == null || (sql.startsWith("SELECT COUNT") || sql.startsWith("select count") || sql.startsWith("SELECT count") || sql.startsWith("select COUNT"))) {
return dbKit.find(sql, Kv.class);
}
/*
// todo: 从sql分析支持多种sql处理类别
if (sql.startsWith("select count")) {
@@ -58,6 +71,22 @@ public class QTaskMysql extends QTaskAbs implements QTask {
dbKit.exetute(sql);
}*/
return dbKit.queryList(sql, Map.class);
// sql 解析-检查:未设置分页设置默认分页
sql = Utils.parserSql(sql);
Kv kv = Kv.of();
CompletableFuture<Long> countFuture = dbKit.findColumnAsync(countSql, long.class);
CompletableFuture<List<Kv>> listFuture = dbKit.queryListAsync(sql, Kv.class);
try {
kv.set("count", countFuture.get());
kv.set("list", listFuture.get());
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return kv;
}
}

View File

@@ -0,0 +1,11 @@
package net.tccn.user;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class LoginBean {
private String username;
private String pwd;
}

View File

@@ -3,37 +3,40 @@ package net.tccn.user;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.JBean;
import net.tccn.base.arango.Doc;
import org.redkale.persistence.Cacheable;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity;
import org.redkale.persistence.Id;
import org.redkale.util.Utility;
import javax.persistence.Table;
/**
* @author: liangxianyou at 2018/11/22 17:37.
*/
@Getter
@Setter
@Table(name = "MetaUser", catalog = "db_meta")
public class MetaUser extends Doc<MetaUser> {
public static MetaUser dao = dao(MetaUser.class);
@Entity
@Cacheable(value = true, interval = 60 * 60 * 1000, direct = true)
public class MUser {
@Id
@Column(comment = "[用户ID]")
private Integer userid;
@Column(length = 64, comment = "[用户名]")
private String username;
//@ConvertColumn(ignore = true,type = ConvertType.JSON)
@Column(length = 64, comment = "[加密后的密码]")
private String pwd;
private Long createTime;
private Long loginTime;
private Integer status;
@Column(length = 64, comment = "[会话ID]")
private String sessionid;
public MetaUser() {
}
@Column(comment = "[状态] 1启用0未启用")
private short status;
public MetaUser(String sessionid) {
this.sessionid = sessionid;
}
//-------------------------------
@Column(updatable = false, comment = "[创建时间]")
private long createtime;
public static String md5IfNeed(String password){
@Column(comment = "[最后登录时间]")
private long logintime;
public static String md5IfNeed(String password) {
if (password == null || password.length() == 0) {
return "";
}
@@ -54,5 +57,4 @@ public class MetaUser extends Doc<MetaUser> {
jBean.setBody(this);
return jBean;
}
}

View File

@@ -2,10 +2,10 @@ package net.tccn.user;
import net.tccn.base.BaseService;
import net.tccn.base.JBean;
import net.tccn.base.MetaKit;
import org.redkale.net.http.RestMapping;
import org.redkale.net.http.RestService;
import org.redkale.net.http.RestSessionid;
import org.redkale.source.FilterNode;
/**
* @author: liangxianyou at 2018/11/22 17:16.
@@ -17,39 +17,44 @@ public class UserService extends BaseService {
public JBean login(@RestSessionid String sessionid,
String username,
String pwd) {
MetaUser bean = new MetaUser();
MUser bean = new MUser();
bean.setUsername(username);
MetaUser user = MetaKit.findFirst(bean);
//MUser user = MetaKit.findFirst(bean);
MUser user = metaSource.find(MUser.class, FilterNode.create("username", username));
if (user == null) {
return JBean.by(-1, "登陆失败:账号无效");
}
JBean jBean = user.checkLogin(pwd);
if (jBean.getCode() == 0) {
cacheSource.set(30 * 60 * 2,sessionid, MetaUser.class, user);
cacheSource.set(30 * 60 * 2, sessionid, MUser.class, user);
user.setSessionid(sessionid);
user.setLoginTime(System.currentTimeMillis());
MetaKit.save(user);
user.setLogintime(System.currentTimeMillis());
// MetaKit.save(user);
metaSource.updateColumn(user, "sessionid", "logintime");
}
return jBean;
}
@RestMapping(name = "current")
public MetaUser current(@RestSessionid String sessionid) {
return getT("user_" + sessionid, MetaUser.class, () -> MetaKit.findFirst(new MetaUser(sessionid)));
public MUser current(@RestSessionid String sessionid) {
// T
//return getT("user_" + sessionid, MUser.class, () -> MetaKit.findFirst(new MetaUser(sessionid)));
MUser user = metaSource.find(MUser.class, FilterNode.create("sessionid", sessionid));
return user;
}
@RestMapping(name = "logout", comment = "退出登陆")
public JBean logout(@RestSessionid String sessionid) {
MetaUser user = MetaKit.findFirst(new MetaUser(sessionid));
MUser user = metaSource.find(MUser.class, FilterNode.create("sessionid", sessionid));
if (user != null) {
user.setSessionid("");
MetaKit.save(user);
metaSource.updateColumn(user, "sessionid");
}
cacheSource.removeAsync("user_" + sessionid);
// cacheSource.removeAsync("user_" + sessionid);
return JBean.OK;
}

View File

@@ -5,6 +5,13 @@
UPDATE "#(key)" WITH { link:null } IN Characters
#end
#sql("mable.lastAlias")
SELECT alias
FROM mtable
ORDER BY LENGTH(alias) DESC, alias DESC
LIMIT 1;
#end
#sql("metaTable.lastAlias")
for d in MetaTable
sort length(d.alias) desc, d.alias desc

View File

@@ -1,28 +1,15 @@
import net.tccn.base.*;
import net.tccn.base.dbq.fbean.FBean;
import net.tccn.base.dbq.jdbc.api.DbAccount;
import net.tccn.base.dbq.jdbc.api.DbKit;
import net.tccn.base.dbq.parser.ParseMysql;
import net.tccn.dict.Dict;
import net.tccn.dict.MDict;
import net.tccn.dict.DictKit;
import net.tccn.meta.MetaService;
import net.tccn.meta.MetaTable;
import net.tccn.qtask.DbTask;
import net.tccn.qtask.TaskKit;
import net.tccn.user.MetaUser;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test;
import org.redkale.convert.json.JsonConvert;
import org.redkale.source.CacheMemorySource;
import org.redkale.util.TypeToken;
import org.redkale.util.Utility;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
@@ -41,7 +28,7 @@ public class RunTest<T> {
/*public static Task A = new Task("mysql", "select * from user where userid=#(userid)", "查询用户列表", Kv.of("userid", 1));
public static Task B = new Task("method", "User.say", "user调用", Kv.of("name", "张三").set("age", 13));
public static Task C = new Task("http", "http://127.0.0.1/meta/db_plat_list?platToken=3421432", "查询数据平台列表", Kv.of("abx", "abx111"));
public static Task C = new Task("http", "http://127.0.0.1/meta/db_plat_list?plattoken=3421432", "查询数据平台列表", Kv.of("abx", "abx111"));
public static Task d = new Task("es", "http://192.168.91.5:9200/_sql?", "查询数据平台列表", Kv.of("sql", "select * from basic_iotdevice_all limit 10"));
public static Task e = new Task("http", "http://192.168.91.5:9200/_sql?sql=select%20*%20from%20basic_iotdevice_all%20limit%2010", "查询数据平台列表", Kv.of());
*/
@@ -62,7 +49,7 @@ public class RunTest<T> {
//@Test
public void parseFBeanTest() {
String str = "{'platToken':'ipsm_v4','name':'historyTrack'," +
String str = "{'plattoken':'ipsm_v4','name':'historyTrack'," +
"'filters':[{'col':'ap.comName','value':'贵阳市第十九中学','type':'LIKE'},{'col':'','value':'name=213113','type':'SQL'}," +
"{'col':'age','values':[1,2],'type':'RANGE'}]," +
@@ -76,7 +63,7 @@ public class RunTest<T> {
System.out.println("list:" + parse[1]);
}
@Test
/*@Test
public void jdbcTest() {
//DbAccount jdbcAccount = new DbAccount("jdbc:mysql://192.168.202.11:3306/gxbii_dev", "root", "eversec123098");
DbAccount dbAccount = new DbAccount();
@@ -105,10 +92,10 @@ public class RunTest<T> {
//find count
/*long total = dbKit.queryColumn("select count(1) from basic_device", long.class);
*//*long total = dbKit.queryColumn("select count(1) from basic_device", long.class);
System.out.println(total);
System.out.println(int.class);*/
}
System.out.println(int.class);*//*
}*/
//@Test
public void toAsTest() {
@@ -175,7 +162,7 @@ public class RunTest<T> {
}
//@Test
public void userCreate() {
/*public void userCreate() {
MetaUser user = new MetaUser();
user.setUsername("admin");
user.setCreateTime(System.currentTimeMillis());
@@ -183,12 +170,12 @@ public class RunTest<T> {
user.setStatus(1);
user.save();
}
}*/
//@Test
public void t() {
/*public void t() {
System.out.println(MetaKit.nextAlias());
}
}*/
//@Test
public void kvTest() {
@@ -218,27 +205,38 @@ public class RunTest<T> {
Object o = Kv.toAs(k, v);
switch (v.getSimpleName()) {
case "int":
System.out.println((int)o);break;
System.out.println((int) o);
break;
case "Integer":
System.out.println((Integer)o);break;
System.out.println(o);
break;
case "long":
System.out.println((long)o);break;
System.out.println((long) o);
break;
case "Long":
System.out.println((Long)o);break;
System.out.println(o);
break;
case "short":
System.out.println((short)o);break;
System.out.println((short) o);
break;
case "Short":
System.out.println((Short)o);break;
System.out.println(o);
break;
case "byte":
System.out.println((byte)o);break;
System.out.println((byte) o);
break;
case "float":
System.out.println((float)o);break;
System.out.println((float) o);
break;
case "Float":
System.out.println((Float)o);break;
System.out.println(o);
break;
case "Byte":
System.out.println((Byte)o);break;
System.out.println(o);
break;
case "String":
System.out.println((String)o);break;
System.out.println((String) o);
break;
}
}
}
@@ -254,12 +252,12 @@ public class RunTest<T> {
}
@Test
/*@Test
public void T() {
List<MetaTable> metaTables = MetaKit.getMetaTables();
System.out.println(metaTables.size());
}
}*/
TplKit tplKit = TplKit.use();
@@ -294,16 +292,16 @@ public class RunTest<T> {
}
//@Test
public void taskRunTest() {
DbTask entity = DbTask.dao.findByKey("23074420");
/*public void taskRunTest() {
QTask entity = DbTask.dao.findByKey("23074420");
if (entity != null) {
System.out.printf("------------------------%n%s%n------------------------%n", convert.convertTo(TaskKit.taskRun(entity)));
}
}
}*/
//@Test
public void dataToFileTest() {
/*public void dataToFileTest() {
List<MetaService> metaServices = MetaService.dao.find();
@@ -313,17 +311,17 @@ public class RunTest<T> {
file.getParentFile().mkdirs();
FileKit.strToFile(convert.convertTo(metaKit), file);
}
}*/
//@Test
public void readJson() {
/*public void readJson() {
File file = new File("tmp/MetaService.json");
try {
Type type = new TypeToken<List<MetaService>>() {
Type type = new TypeToken<List<MService>>() {
}.getType();
List<MetaService> list = convert.convertFrom(type, new FileInputStream(file));
List<MService> list = convert.convertFrom(type, new FileInputStream(file));
System.out.println(list);
@@ -331,22 +329,22 @@ public class RunTest<T> {
e.printStackTrace();
}
Class clazz = MetaService.class;
Class clazz = MService.class;
//File file = new File(String.format("tmp/%s.json", clazz.getSimpleName()));
/*
*//*
写入数据到 文件
MetaKit.cacheSave(MetaTable.class);
MetaKit.cacheSave(MetaLink.class);
MetaKit.cacheSave(MetaService.class);
MetaKit.cacheSave(DbAccount.class);
MetaKit.cacheSave(SysPlat.class);*/
MetaKit.cacheSave(SysPlat.class);*//*
}
}*/
//@Test
public void cacheMemorySourceTest() {
/*public void cacheMemorySourceTest() {
CacheMemorySource source = new CacheMemorySource("");
//MetaKit.dcate = "db";
//MetaKit.init();
@@ -367,9 +365,9 @@ public class RunTest<T> {
System.out.println(metaTable);
}
}*/
public List<Map> dbKitTest() {
/*public List<Map> dbKitTest() {
DbAccount dbAccount = new DbAccount();
dbAccount.setCate("mysql");
dbAccount.setUrl("jdbc:mysql://192.168.202.11:3306/gxbii_dev");
@@ -389,11 +387,11 @@ public class RunTest<T> {
System.out.println(list);
return list;
}
}*/
// 通用导出组件测试
//@Test
public void exportTest() {
/*public void exportTest() {
List<Map> list = dbKitTest();
Kv kv = Kv.of("platID", "平台id")
@@ -408,7 +406,7 @@ public class RunTest<T> {
e.printStackTrace();
}
}
}*/
//@Test
public void switchTest() {
@@ -581,13 +579,13 @@ public class RunTest<T> {
System.out.println(ipv4Count("0.0.0.2", "0.0.0.0"));
}
Predicate<Dict> isProvice = (s) -> String.valueOf(s.getValue()).trim().endsWith("0000");
Predicate<Dict> isCity = (s) -> !isProvice.test(s) && String.valueOf(s.getValue()).trim().endsWith("00");
BiPredicate<Dict, Dict> belongProvice = (p, x) -> String.valueOf(x.getValue()).trim().startsWith(String.valueOf(p.getValue()).trim().substring(0, 2));
Predicate<MDict> isProvice = (s) -> String.valueOf(s.getValue()).trim().endsWith("0000");
Predicate<MDict> isCity = (s) -> !isProvice.test(s) && String.valueOf(s.getValue()).trim().endsWith("00");
BiPredicate<MDict, MDict> belongProvice = (p, x) -> String.valueOf(x.getValue()).trim().startsWith(String.valueOf(p.getValue()).trim().substring(0, 2));
@Test
//@Test
public void dictTest() {
MetaKit.init();
// MetaKit.init();
System.out.println("-------- 1 -------");
DictKit dictKit = DictKit.use("ipsm_v4");
System.out.println(dictKit.getDictLabel("useSubclass", "3"));