This commit is contained in:
lxy
2020-05-10 23:18:59 +08:00
parent 707e9ee680
commit 68eea7b27d
42 changed files with 5969 additions and 361 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<application port="5001" xmlns="application.xsd">
<application port="5001">
<resources>
<listener value="net.tccn.base.MetaListenter"/>
<properties load="config.txt"></properties>

View File

@@ -12,10 +12,10 @@ rpc.url=
kafak.servers=
#--------------- arango --------------
arango.host=120.24.230.60
arango.host=127.0.0.1
arango.port=8529
arango.user=root
arango.passwd=abc123
arango.password=123456
arango.database=db_dev
#--------------- arango --------------
@@ -24,3 +24,7 @@ tplPath=/tpl
# file|db
dataCate=db
dataPath=${APP_HOME}/conf/data/
#--------------- 文件上传 --------------
upfile.dir=/var/www/upload/meta/
upfile.view=http://img.1216.top/meta/

32
pom.xml
View File

@@ -7,7 +7,7 @@
<groupId>net.tccn</groupId>
<artifactId>meta-kit</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<packaging>war</packaging>
<modules>
<!--<module>qtask</module>-->
</modules>
@@ -18,21 +18,33 @@
<dependency>
<groupId>org.redkale</groupId>
<artifactId>redkale</artifactId>
<version>2.0.0.beta2</version>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.redkalex</groupId>
<artifactId>redkale-plugins</artifactId>
<version>LATEST</version>
</dependency>
<!-- mysql连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
<version>LATEST</version>
</dependency>
<!-- arangodb支持 -->
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>arangodb-java-driver-async</artifactId>
<version>5.0.4</version>
<version>LATEST</version>
<exclusions>
<exclusion>
<groupId>junit:junit:3.8.1</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -45,13 +57,13 @@
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<version>LATEST</version>
<scope>provided</scope>
</dependency>
@@ -67,9 +79,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>8</source>
<target>8</target>
<source>14</source>
<target>14</target>
</configuration>
</plugin>
@@ -77,6 +90,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy-dependencies</id>
@@ -95,7 +109,7 @@
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<version>2.1.2</version>
<executions>
<execution>
<id>copy-resources</id>

9
root/api/tmp.js Normal file
View File

@@ -0,0 +1,9 @@
const tmp = {
saveData({bean}) {
return red.postX('http://oss-v09x.woaihaoyouxi.com/article/batch_import', {bean:JSON.stringify(bean)})
},
search({keyword}) {
return red.postX('http://oss-v09x.woaihaoyouxi.com/game/search', {keyword})
}
}

176
root/content/create.html Normal file
View File

@@ -0,0 +1,176 @@
<row class="content-create">
<div class="modal-body" style="text-align: left">
<form class="form-horizontal">
<div class="form-group">
<label for="queryId" class="col-sm-1 required">内容类型</label>
<div class="col-md-2 col-sm-11">
<select class="form-control" v-model="row.type">
<option value="1">微动态</option>
<option value="2">游戏说</option>
</select>
</div>
</div>
<div class="form-group" v-show="row.type == 2">
<label for="queryId" class="col-sm-1 required">游戏说标题</label>
<div class="col-md-6 col-sm-5">
<input v-model="row.name" class="form-control" id="queryId" placeholder="请输入 游戏说标题">
</div>
</div>
<div class="form-group" v-show="row.type == 2">
<label for="queryId" class="col-sm-1 required">关联的游戏ID</label>
<div class="col-md-6 col-sm-5">
<input v-model="row.gameids" class="form-control" id="gameids" placeholder="请输入 关联的游戏ID">
</div>
</div>
<div class="form-group" v-show="row.type == 2">
<label for="editor" class="col-md-1">游戏说内容</label>
<div class="col-md-11">
<div id="editor">
</div>
</div>
</div>
<div class="form-group" v-show="row.type == 1">
<label for="editor" class="col-md-1">微动态内容</label>
<div class="col-md-11">
<textarea v-model="row.content" class="form-control layui-code" rows="10" id="content" placeholder="请输入 微动态内容" > </textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-11">
<div id='myUploader' class="uploader"><!--data-ride="uploader"-->
<div class="uploader-message text-center">
<div class="content"></div>
<button type="button" class="close">×</button>
</div>
<div class="uploader-files file-list file-list-grid"></div>
<div>
<hr class="divider">
<div class="uploader-status pull-right text-muted"></div>
<button type="button" class="btn btn-link uploader-btn-browse" v-show="row.type == 1"><i class="icon icon-plus"></i> 选择微动态图片</button>
<button type="button" class="btn btn-link uploader-btn-browse" v-show="row.type == 2"><i class="icon icon-plus"></i> 选择封面</button>
<button type="button" class="btn btn-link uploader-btn-start"><i class="icon icon-cloud-upload"></i> 上传图片 </button>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button @click="saveTable()" type="button" class="btn btn-primary">确定</button>
</div>
</row>
<link href="/res/zui/lib/uploader/zui.uploader.min.css" rel="stylesheet">
<script src="/res/zui/lib/uploader/zui.uploader.min.js"></script>
<script src="/res/wangEditor/wangEditor.min.js"></script>
<script>
let {saveData} = tmp
let vm = new Vue({
el: ".content-create",
data: {
row: {
type:2,
files: [],
cover: ""
},
vediter : {}
},
watch: {
},
methods: {
saveTable() {
let html = this.vediter.txt.html()
if(vm.row['type'] == 2) {
this.row['content'] = html
}
saveData({bean: this.row}).then(res => {
if (res.retcode == 0) {
red.showOk("保存成功");
setTimeout(function () {
location.reload();
}, 600)
} else {
red.showError(res.retinfo);
}
})
},
buildEditer(key){
let E = window.wangEditor
let editor = new E('#editor')
editor.customConfig.uploadImgServer = '/upload/editor?cate=editor'
let cache_key = key+"_" + $("input[name='contentid']").val()
let html = localStorage.getItem(cache_key)
editor.customConfig.onblur = function (html) {
localStorage.setItem(cache_key, html)
}
editor.create()
//if (html) editor.txt.html(html)//缓存的内容
return editor
}
},
mounted: function () {
this.vediter = this.buildEditer("11");
$('#myUploader').uploader({
url: '/upload/x',
responseHandler: function (res, f) {
let file = JSON.parse(res.response)["body"][0];
let filepath = file["filePath"]
console.log(file)
if (vm.row['type'] == 2) {
vm.row['cover'] = filepath
} else {
vm.row.files.push(filepath)
}
},
lang: 'zh_cn'
/*filters: {
mime_types: [
{title: 'Excel文件', extensions: ''},
],
prevent_duplicates: true
}*/
});
}
});
/*function buildEditer(key){
let E = window.wangEditor
let editor = new E('#editor')
editor.customConfig.uploadImgServer = '/upload/img'
let cache_key = key+"_" + $("input[name='contentid']").val()
let html = localStorage.getItem(cache_key)
editor.customConfig.onblur = function (html) {
localStorage.setItem(cache_key, html)
}
editor.create()
if (html) editor.txt.html(html)//缓存的内容
return editor
}*/
</script>
</body>
</html>

163
root/content/funs.html Normal file
View File

@@ -0,0 +1,163 @@
<row class="funs">
<div class="col-md-12">
<h3 >平台功能</h3>
</div>
<div class="col-md-12" style="padding-top: 10px;overflow:auto;">
<table class="table table-bordered table-hover" style="width: 100%">
<!--<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
<th>操作</th>
</tr>
</thead>-->
<tbody>
<tr>
<td>用户</td>
</tr>
<tr>
<td>文章</td>
</tr>
<tr>
<td>游戏</td>
</tr>
<tr>
<td>全文检索</td>
</tr>
<tr>
<td>IM</td>
</tr>
<tr>
<td>通知</td>
</tr>
<!--<tr v-for="row in list.rows">
<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="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>-->
</tbody>
</table>
<div v-show="!row || list.rows == 0" style="text-align: center">
<img src="../res/img/none.png">
<p>暂无数据</p>
</div>
</div>
<!-- modal-tpl -->
<!--<div class="col-md-12">
&lt;!&ndash; 对话框触发按钮 &ndash;&gt;
&lt;!&ndash; 对话框HTML &ndash;&gt;
<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">QTask编辑</h4>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 required">任务名称</label>
<div class="col-md-6 col-sm-10">
<input v-model="row.title" class="form-control" placeholder="请输入 业务名称">
</div>
</div>
<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="请输入 任务标识码">
</div>
</div>
<div class="form-group" style="margin-bottom: 0">
<label class="col-md-2 required">执行内容</label>
<div class="col-md-10">
<textarea v-model="row.content" class="form-control layui-code" rows="5" placeholder="请输入 SQL (支持jfinal-enjoy模板语法)" > </textarea>
</div>
</div>
<div class="form-group">
<label for="para" class="col-sm-2">默认查询参数</label>
<div class="col-sm-10">
<input v-model="row.para" class="form-control" id="para" placeholder="请输入 默认查询参数格式: {k:v}">
</div>
</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">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
</select>
</div>
<div class="col-md-4">
<select v-model="row.catalog" class="form-control">
<option></option>
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
</select>
</div>
</div>
<div class="form-group">
<label for="para" class="col-sm-2">备注(注释)</label>
<div class="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()" type="button" class="btn btn-primary">确定</button>
</div>
</div>
</div>
</div>
&lt;!&ndash; 小对话框 &ndash;&gt;
&lt;!&ndash;<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#mySmModal">小对话框</button>&ndash;&gt;
<div class="modal fade" id="mySmModal">
<div class="modal-dialog modal-sm">
<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-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button @click="save()" type="button" class="btn btn-primary">确定</button>
</div>
</div>
</div>
</div>-->
</row>
<script>
let {search} = tmp
let vm = new Vue({
el: ".funs",
data: {
cfg:{},
keyword: "",
list: {rows:[], total: 0},
row: {},
},
watch: {
},
methods: {
search() {
if (!this.keyword) {
red.showError("输入有效关键字查询")
}
search({keyword: this.keyword}).then(rs => {
this.list = {rows: rs, total: rs.length}
})
}
},
mounted: function () {
// this.loadList();
}
});
</script>

162
root/content/list.html Normal file
View File

@@ -0,0 +1,162 @@
<row class="content-list">
<div class="col-md-12">
<h3 v-text="cfg.title"></h3>
</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="search({})" class="btn btn-primary" type="button"> 查询</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%">
<thead>
<tr>
<th v-for="field in cfg.cols" v-text="field.label"></th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="row in list.rows">
<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="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>
</tbody>
</table>
<div v-show="!row || list.rows == 0" style="text-align: center">
<img src="../res/img/none.png">
<p>暂无数据</p>
</div>
</div>
<!-- modal-tpl -->
<!--<div class="col-md-12">
&lt;!&ndash; 对话框触发按钮 &ndash;&gt;
&lt;!&ndash; 对话框HTML &ndash;&gt;
<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">QTask编辑</h4>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 required">任务名称</label>
<div class="col-md-6 col-sm-10">
<input v-model="row.title" class="form-control" placeholder="请输入 业务名称">
</div>
</div>
<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="请输入 任务标识码">
</div>
</div>
<div class="form-group" style="margin-bottom: 0">
<label class="col-md-2 required">执行内容</label>
<div class="col-md-10">
<textarea v-model="row.content" class="form-control layui-code" rows="5" placeholder="请输入 SQL (支持jfinal-enjoy模板语法)" > </textarea>
</div>
</div>
<div class="form-group">
<label for="para" class="col-sm-2">默认查询参数</label>
<div class="col-sm-10">
<input v-model="row.para" class="form-control" id="para" placeholder="请输入 默认查询参数格式: {k:v}">
</div>
</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">
<option></option>
<option v-for="item in dbPlats" :value="item.key" v-text="item.name"></option>
</select>
</div>
<div class="col-md-4">
<select v-model="row.catalog" class="form-control">
<option></option>
<option v-for="item in catalogs()" :value="item" v-text="item"></option>
</select>
</div>
</div>
<div class="form-group">
<label for="para" class="col-sm-2">备注(注释)</label>
<div class="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()" type="button" class="btn btn-primary">确定</button>
</div>
</div>
</div>
</div>
&lt;!&ndash; 小对话框 &ndash;&gt;
&lt;!&ndash;<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#mySmModal">小对话框</button>&ndash;&gt;
<div class="modal fade" id="mySmModal">
<div class="modal-dialog modal-sm">
<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-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button @click="save()" type="button" class="btn btn-primary">确定</button>
</div>
</div>
</div>
</div>-->
</row>
<script src="http://www.1216.top/res/layui/layui.js"></script>
<script>
let {search} = tmp
let vm = new Vue({
el: ".qtask-list",
data: {
keyword: "",
list: {rows:[], total: 0},
row: {},
},
watch: {
},
methods: {
search() {
if (!this.keyword) {
red.showError("输入有效关键字查询")
}
search({keyword: this.keyword}).then(rs => {
this.list = {rows: rs, total: rs.length}
})
}
},
mounted: function () {
// this.loadList();
}
});
</script>

View File

@@ -82,13 +82,14 @@
<script src="/api/db.js"></script>
<script src="/api/table.js"></script>
<script src="/api/dict.js"></script>
<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 type="module">
import { logout } from './api/user.js'
let { refresh } = meta
let { platList } = plat
var vm = new Vue({
let vm = new Vue({
el: ".container-fluid",
data: {
sysPlat: red.getData('sysPlat'),
@@ -97,12 +98,15 @@
/*{name: "DDL", url: "/qtask/ddl.html"},*/
{name: "元服务", url: "/meta", nodes: [
/*{url:"/metadata/metatable/list.html", name:"TableList"},*/
{url:"/metadata/metatable/metaTable.html", name:"实体管理", icon: "icon-table"},
{url:"/metadata/metatable/metaTable.html", name:"实体管理", icon: "icon-cubes"},
/*{url:"/metadata/metatable/import.html", name:"导入实体"},*/
{url:"/metadata/metaLink.html", name:"实体关系"},
{url:"/metadata/metaService.html", name:"业务管理", icon:"icon-usecase"},
{url:"/metadata/dataList.html", name:"业务预览", icon:"icon-bug"},
{url:"/metadata/dict.html", name:"字典管理", icon:"icon-usecase"},
{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:"/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"},*/
]
},
{
@@ -111,11 +115,11 @@
{url:"/qtask/debug.html", name:"QTask-Debug", icon:"icon-bug"},
]
},
{
/*{
name: "其他服务", url: "/plat/db.html", nodes: [
{url:"/plat/db.html", name:"文件服务", icon: "icon-database"},
]
},
},*/
{
name: "业务平台", url: "/qtask", nodes: [
{url:"/plat/index.html", name:"业务平台", icon:"icon-server"},
@@ -172,7 +176,14 @@
this.pageId = item.name;
},
refresh() {
refresh().then(res => red.showOk())
refresh().then(res => {
platList().then(res => { // 刷新平台列表缓存
let rows = res.rows
this.sysPlats = rows;
red.setData("sysPlats", rows);
})
red.showOk()
})
},
logout() {
logout()
@@ -184,7 +195,7 @@
this.pageId = red.getData("pageId", this.page['mame'])
//绑定事件
$('.menu .nav').on('click', 'li:not(.nav-parent) > a', function() {
var $this = $(this);
let $this = $(this);
$('.menu .nav .active').removeClass('active');
$this.closest('li').addClass('active');
$this.closest('.nav-parent').addClass('active');
@@ -195,7 +206,7 @@
//监听浏览器窗口大小变化
function autoLeftHeight() {
var h = document.documentElement.clientHeight || document.body.clientHeight;
let h = document.documentElement.clientHeight || document.body.clientHeight;
$("#left").attr("style", "height:" + (h - 50) + "px");
$("#main").attr("style", "height:" + (h - 90) + "px; overflow: auto;");
$(".sheet-cell").attr("style", "height:" + (h - 265) + "px;margin-bottom:20px;");

View File

@@ -27,7 +27,7 @@
<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.name} [${item.comment}]`" href="javascript:;"></a>
<a @click="service=item.name" :title="`${item.name}`" v-text="`${item.comment}`" href="javascript:;"></a>
</li>
</ul>
</div>
@@ -55,9 +55,9 @@
<!-- 过滤条件 -->
<div class="col-lg-4 col-md-6" v-for="(filter,index) in cfg.filters" v-if="filter.checked">
<div class="input-group item">
<span class="input-group-addon" style="width: 130px;">{{filter.label}}</span>
<select class="form-control" v-model="filter['type']" style="width: 100px">
<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;">
<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>
@@ -236,7 +236,7 @@
let {getServiceList, getCfg, getDataList, exportData, dataDel, dataSave} = meta
let {showOk} = red
var vm = new Vue({
let vm = new Vue({
el:".data-list",
data: {
cfg: {
@@ -252,7 +252,7 @@
addFilter: "",
para: {},
list: {rows: [], total: 0},
limit: {pn: 1, ps: 10, total: 0},
limit: {pn: 1, ps: 20, total: 0},
order: {col: "id", desc: 1},
pk: "",
detailData: {}
@@ -268,7 +268,7 @@
},
service() {
this.loadCfg();
this.limit = {pn: 1, ps: 10, total: 0};
this.limit = {pn: 1, ps: 20, total: 0};
this.order = {col:"", desc:1};
this.findList();
},
@@ -301,7 +301,7 @@
},
loadCfg() {
getCfg({name: this.service}).then(res => {
res['type'] = res.filters[0]['name']
// res['type'] = res.filters[0]['name']
for (i in res["filters"]) {
res["filters"][i]['type'] = res["filters"][i]['filterType'][0]['name']
@@ -311,59 +311,28 @@
},
dealFieldFmt(bean, colFmt) { //处理字典数据 及 自定义函数处理数据
let v = ""
let v = bean[colFmt["col"]]
if (colFmt.inType == "DICT") {
// 取字典值返回
v = bean[colFmt["col"]]
}
else if (colFmt.inType == "INPUT_DAY") {
v = bean[colFmt["col"]]
}
else if (colFmt.inType == "INPUT_TIME") {
v = bean[colFmt["col"]]
// 时间戳格式化
return red.timeFmt(new Date(v))
}
else if (colFmt.inType == "INPUT_FUNC") {
v = bean[colFmt["col"]]
}
else if (colFmt.inType == "FILE" && v) {
return '<a href="{0}" target="_blank">查看</a>'.format(v)
}
else {
v = bean[colFmt["col"]]
}
if (colFmt.inType && colFmt.inType != "INPUT") {
v += " -> "+colFmt.inType
}
return v
/*if (colFmt["fmt"]) {
let fmt = colFmt["fmt"]
let cate = ""
if (fmt.indexOf("|") > 0) {
cate = fmt.split("|")[0]
fmt = fmt.split("|")[1]
}
if (cate == "Dict") {
//console.log(`Dict:${fmt}-${bean[colFmt["col"]]}`)
}
else {
//console.log(`func:${fmt}-${bean[colFmt["col"]]}`)
let evl = `${fmt}(${JSON.stringify(bean)},'${bean[colFmt["col"]]}')`
//console.log("evl", evl)
return (new Function("","return "+ evl))()
}
return bean[colFmt["col"]];
} else {
//console.log(`k-v:${colFmt["col"]}-${bean[colFmt["col"]]}`)
return bean[colFmt["col"]]
}*/
},
dealField(bean, field) {
let str = "";
@@ -438,12 +407,12 @@
let orders = [];
//截取真实字段名,(考虑如果多表关联情况,是否需要加入真实字段名)
if (vm.order.col) {
var end = vm.order.col.indexOf("\|");
let end = vm.order.col.indexOf("\|");
if (end < 0) {
end = vm.order.col.indexOf("=")
}
var col = vm.order.col;
let col = vm.order.col;
if (end > 0) {
col = vm.order.col.substring(0, end);
}
@@ -497,4 +466,4 @@
this.serviceList();
}
});
</script>
</script>

View File

@@ -527,7 +527,7 @@
EQUAL:"等于", NOTEQUAL:"不等于", IN: "包含", NOTIN:"不包含", LIKE: "模糊查询", RANGE: "范围"
},
findTypes: ["INPUT", "DICT", "CHECKBOX", "RADIO", "DAY", "TIME"],
inTypes: ["INPUT", "DICT", "INPUT_DAY", "INPUT_TIME", "FUNC", "QTASK", "HIDDEN"],
inTypes: ["INPUT", "DICT", "INPUT_DAY", "INPUT_TIME", "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"],
@@ -1102,4 +1102,4 @@
}
});
</script>
</script>

View File

@@ -60,45 +60,50 @@
</ul>
</div>
<!-- 实体表信息 -->
<div class="col-md-10" 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">
<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>
</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.label"></td>
<td v-show="status!=2" v-text="item.type"></td>
<!--
<td v-show="status!=2" v-text="item.inType"></td>
<td v-show="status!=2" v-text="item.inExt"></td>
-->
<td v-show="status!=2">
<i v-if="item.pk" class="icon icon-check"></i>
</td>
<div class="col-md-10">
<!-- 实体属性列表 -->
<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">
<td v-show="status==3 || status==4 || status==5 || status==6"><input type="checkbox"></td>
<th v-show="status==1"></th>
<th>字段</th>
<th>中文名</th>
<th>数据类型</th>
<!--
<th>输入类型</th>
<th>附加属性</th>
-->
<th>非空</th>
<th>主键</th>
</tr>
<tr v-for="(item, index) in meta.items" class="item">
<td v-show="status==1" class="icon icon-move"></td>
<td v-show="status!=2" v-text="item.name" style="background-color: rgb(235, 235, 228);"></td>
<td v-show="status!=2" v-text="item.label"></td>
<td v-show="status!=2" v-text="item.type"></td>
<!--
<td v-show="status!=2" v-text="item.inType"></td>
<td v-show="status!=2" v-text="item.inExt"></td>
-->
<td v-show="status!=2">
<i v-if="item.notNull" class="icon icon-check"></i>
</td>
<td v-show="status!=2">
<i v-if="item.pk" class="icon icon-check"></i>
</td>
<td v-show="status==2">
<input type="hidden" name="item" :value="JSON.stringify(item)">
<input v-model="item" type="hidden">
<input :value="item.name" disabled class="form-control">
<input v-model="item.name" type="hidden">
<input name="name" type="hidden" :value="item.name">
</td>
<td v-show="status==2"><input v-model="item.label" class="form-control"></td>
<td v-show="status==2"><input v-model="item.type" class="form-control"></td>
<!--
<td v-show="status==2">
<input type="hidden" name="item" :value="JSON.stringify(item)">
<input v-model="item" type="hidden">
<input :value="item.name" disabled class="form-control">
<input v-model="item.name" type="hidden">
<input name="name" type="hidden" :value="item.name">
</td>
<td v-show="status==2"><input v-model="item.label" class="form-control"></td>
<td v-show="status==2"><input v-model="item.type" class="form-control"></td>
<!--
<td v-show="status==2">
<select v-model="item.inType" class="form-control" style="width: 130px">
<option></option>
@@ -107,16 +112,19 @@
</td>
<td v-show="status==2"><input v-model="item.inExt" class="form-control"></td>
-->
<td v-show="status==2" style="text-align: center">
<label>
<input v-model="item.pk" type="checkbox">
</label>
</td>
</tr>
</table>
</div>
<div class="col-md-10">
<td v-show="status==2" style="text-align: center">
<label>
<input v-model="item.notNull" type="checkbox">
</label>
</td>
<td v-show="status==2" style="text-align: center">
<label>
<input v-model="item.pk" type="checkbox">
</label>
</td>
</tr>
</table>
</div>
<!-- baseInfo -->
<div class="panel" v-show="status==7 ">
@@ -166,6 +174,12 @@
<p style="padding: 5px">整理中,【实体关系】放到此处维护</p>
</div>
<textarea class="form-control layui-code" v-model="upsql" rows="10" id="content" placeholder="/* 没有提交要执行的查询 */" />
</div>
<div class="col-md-10">
</div>
</row>
@@ -175,10 +189,10 @@
let {showOk} = red
let {dbList} = plat
var vm = new Vue({
let vm = new Vue({
el: ".meta-list",
data: {
inTypes: ["INPUT", "SELECT_EXT", "INPUT_DT", "FMT_FUN"],
inTypes: ["INPUT", "SELECT_EXT", "INPUT_DT", "FMT_FUN", "FILE"],
dataTypes: ["bigint(20)", "varchar(255)", "varchar(64)", "varchar(32)", "varchar(16)", "int(11)", "int(3)", "int(2)", "datetime"],
filterCate: ["EQUAL", "NOTEQUAL", "LIKE", "IN"],
tables: [],//所有的业务类型,【测试用】
@@ -199,6 +213,8 @@
dbPlats:[],
row: {key: "", platId: "", dbPlatId:"", catalog: "", name:"", comment:"", alias: ""},
filter: {db: "", catalog: "", name: ""},//tableList 过滤条件
upsql: "", // 需要执行的 sql语句
},
watch: {
metaTable(v) {
@@ -207,6 +223,7 @@
},
status: function (v) {
this.setMove(v)
this.upsql = ''
},
alias: function () {
this.loadDetail();
@@ -217,7 +234,7 @@
let itemOv = this.oldItems || [];
if (itemOv.length == 0) return;
let attr = ["label", "name", "pk", "type", "inType","inExt"];
let attr = ["label", "name", "pk", "type", "inType","inExt", 'notNull'];
let itemEdit = [];
a:for (let i = 0; i < itemOv.length; i++) {
for (let j = 0; j < attr.length; j++) {
@@ -243,6 +260,33 @@
//vm.table = v[0]["name"];
}
},
// 基础信息变更 sql
row: {
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.comment != row.comment) {
vm.upsql += 'ALTER TABLE `{0}`.`{1}` COMMENT=\'{2}\';\n'.format(vm.metaTable.catalog, vm.metaTable.name, row.comment)
}
},
deep: true
},
// 属性表更 sql
itemEdit: {
handler: function (items) {
// vm.upsql = 'ALTER TABLE `{0}`.`{1}'.format()
/*`
CHANGE `rankcate` `rankcate` VARCHAR(64) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL COMMENT '[排行类型]',
CHANGE `remark` `remark1` VARCHAR(128) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL COMMENT '[说明]';*/
},
deep: true
},
meta: function (v) {
this.row = {key:v.key, dbPlatId: v.dbPlatId, catalog: v.catalog, name:v.name, comment:v.comment, alias: v.alias};
let oldItems = v['items'] || []
@@ -253,6 +297,7 @@
methods: {
loadDetail() {
tableInfo({alias: this.alias}).then(res => {
this.metaTable = res
let row = res;
vm.meta = row;
let oldItems = [];
@@ -422,14 +467,22 @@
},
showInfo() {
$('#f-info').modal({moveable: true})
}
},
buildSql() {
}
},
mounted: function (){
dbList().then(res => {
this.dbPlats = res.rows;
})
this.tableList();
/*setTimeout(function () {
layui.use('code', function(){ //加载code模块
layui.code({title:"",about: false, height: "500"}); //引用code方法
});
}, 300)*/
}
});
</script>

View File

@@ -67,7 +67,7 @@
let {qtaskList, qtaskDebug} = qtask
let {dbList} = plat
var vm = new Vue({
let vm = new Vue({
el: ".qtask-debug",
data: {
row: {},

View File

@@ -44,10 +44,10 @@ body {
}
#left.col-md-1 {
padding: 0 2px;
width: 10.63333333%;
width: 10.64%;
}
#mainDiv .col-md-11 {
width: 89.36666667%;
width: 89.36%;
/*background-color: #fff;*/
}
#left .nav {
@@ -102,7 +102,7 @@ table td,th{
white-space:nowrap;
overflow:hidden;
text-overflow: ellipsis;
max-width: 200px;
max-width: 173px;
}
th{
background-color: #f1f1f1;

View File

@@ -40,12 +40,12 @@ var red = {
},
getPlatToken: function() {
let plat = red.getData("sysPlat");
if (!plat) {
/*if (!plat) {
red.showMsg({type:'error', placement: 'center', msg: '登陆过期,请前往登陆'});
setTimeout(function () {
location.href = "/user/login.html";
}, 2000);
}
}*/
return plat["token"];
},
getJSON: function (url, params = {}, callback) {
@@ -211,4 +211,4 @@ var red = {
String.prototype.replaceAll=function(s,t){
return red.replaceAll(this, s, t);
}
}

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
root/res/wangEditor/wangEditor.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -107,9 +107,9 @@
<script src="../res/libs/vue.min.js"></script>
<script type="module">
import { login } from '../api/user.js'
let { platList } = plat;
let { platList } = plat
var vm = new Vue({
let vm = new Vue({
el: ".login",
data: {
row:{},

View File

@@ -4,12 +4,9 @@ import org.redkale.convert.json.JsonConvert;
import org.redkale.net.http.RestMapping;
import org.redkale.service.Service;
import org.redkale.source.CacheSource;
import org.redkale.util.AnyValue;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.function.Supplier;
import java.util.logging.Logger;
@@ -39,28 +36,6 @@ public class BaseService implements Service {
private static boolean tplInit = false;
@Override
public void init(AnyValue config) {
try {
File file = new File(APP_HOME.toPath() + "/conf/config.txt");
if (file.exists()) {
prop.load(new FileInputStream(file));
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (!tplInit) {
tplInit = true;
//tplKit.addTpl(new File(FileKit.rootPath(), tplPath));
}
} catch (Exception e) {
e.printStackTrace();
}
}
@RestMapping(ignore = true)
public <T> T getT(String key, Class<T> clazz, Supplier<T> supplier) {
Object obj = cacheSource.getAndRefresh(key, 1000 * 60 * 3, clazz);
@@ -75,21 +50,12 @@ public class BaseService implements Service {
return t;
}
@RestMapping(ignore = true)
public String getProperty(String k, String defaultValue){
return prop.getProperty(k, defaultValue).replace("${APP_HOME}", APP_HOME.getPath());
}
@RestMapping(ignore = true)
public String getProperty(String k){
return prop.getProperty(k);
}
@RestMapping(ignore = true)
public String platId(String token) {
return MetaKit.getPlatId(token);
}
public boolean isEmpty(Object obj) {
return X.isEmpty(obj);
return Utils.isEmpty(obj);
}
}

View File

@@ -1,23 +1,21 @@
package net.tccn.base;
import com.arangodb.ArangoDBException;
import net.tccn.base.arango.ArangoSource;
import net.tccn.user.User;
import net.tccn.user.UserService;
import org.redkale.net.http.HttpRequest;
import org.redkale.net.http.HttpResponse;
import org.redkale.net.http.HttpServlet;
import org.redkale.net.http.HttpUserType;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author: liangxianyou at 2018/11/8 17:05.
*/
@HttpUserType(User.class)
public class BaseServlet extends HttpServlet {
@Resource(name = "SERVER_ROOT")
@@ -26,6 +24,7 @@ public class BaseServlet extends HttpServlet {
private UserService userService;
public Logger logger = Logger.getLogger(this.getClass().getSimpleName());
public static final boolean winos = System.getProperty("os.name").contains("Window");
@Override
protected void preExecute(HttpRequest request, HttpResponse response) throws IOException {
@@ -41,6 +40,11 @@ public class BaseServlet extends HttpServlet {
User user = userService.current(sessionid);
request.setCurrentUser(user);
}
String uri = request.getRequestURI();
if (uri.endsWith(".html")){
response.finish(new File(webroot + uri));
return;
}
super.preExecute(request, response);
}
@@ -67,9 +71,6 @@ public class BaseServlet extends HttpServlet {
try {
// logger.log(Level.INFO, String.format("%s : %s", new Date(), request.getRequestURI()));
super.execute(request, response);
} catch (ArangoDBException e) {
logger.log(Level.INFO, "arangodb init!", e);
ArangoSource.use();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
response.finish(JBean.by(-1, e.getMessage()));
@@ -81,19 +82,4 @@ public class BaseServlet extends HttpServlet {
response.finish(JBean.by(-1, e.getMessage()));
}
}
public Kv getParams(HttpRequest request, String... key) {
Kv kv = Kv.of();
for (String k : key) {
if (k.contains("=")) { //如果没有值使用默认值
kv.put(k.split("=")[0], request.getParameter(k.split("=")[0], k.split("=")[1]));
continue;
} else if (k.contains("<")) { //强制使用"<"右侧的值
kv.put(k.split("<")[0], k.split("<")[1]);
continue;
}
kv.put(k, request.getParameter(k));
}
return kv;
}
}

View File

@@ -304,7 +304,7 @@ public class ExcelKit {
}
if (cell.getCellType() == CellType.NUMERIC) {
map.put(fields[j], (long) cell.getNumericCellValue() + "");
map.put(fields[j], cell.getNumericCellValue() + "");
} else {
map.put(fields[j], cell.getStringCellValue());
}
@@ -346,7 +346,7 @@ public class ExcelKit {
}
if (cell.getCellType() == CellType.NUMERIC) {
map.put(field, (long) cell.getNumericCellValue() + "");
map.put(field, cell.getNumericCellValue() + "");
} else {
map.put(field, cell.getStringCellValue());
}

View File

@@ -258,6 +258,14 @@ public class IpKit {
}
return arr;
};
/*private static Function<String, List<Integer>> _toIntSlice = (str) -> {
String[] strArr = str.trim().split("");
List<Integer> arr = new ArrayList<>(strArr.length);
for (int i = 0; i < strArr.length; i++) {
arr.add(Integer.parseInt(strArr[i]));
}
return arr;
};*/
/**
* 任意两个大小正整数相减
@@ -349,4 +357,35 @@ public class IpKit {
}
return _ip;
}
// 任意两个小数相加 x: 0.1213, y: 0.981
/*private static String _add(String x, String y) {
List<Integer> xArr = _toIntSlice.apply(x.substring(2));
List<Integer> yArr = _toIntSlice.apply(y.substring(2));
String v = "";
int len = xArr.size() > yArr.size() ? xArr.size() : yArr.size();
int carry = 0;
for (int i = 0; i < len; i++) {
int a = xArr.size() > (len - i - 1) ? xArr.get(len - i - 1) : 0;
int b = yArr.size() > (len - i - 1) ? yArr.get(len - i - 1) : 0;
int _v = a + b + carry;
carry = _v / 10;
v = _v % 10 + v;
}
v = carry + v;
StringBuffer buf = new StringBuffer(v).insert(v.length() - len, ".");
return buf.toString();
}
// 任意两个数相加
public static String addx(String x, String y) {
String str = _add(x, y);
System.out.printf("%s + %s = %s \n", x, y, str);
return str;
}*/
}

View File

@@ -15,27 +15,27 @@ import java.util.stream.Stream;
/**
* Created by liangxianyou@eversec.cn at 2018/3/12 14:17.
*/
public class Kv<K,V> extends LinkedHashMap<K,V> {
public static Kv of(){
public class Kv<K, V> extends LinkedHashMap<K, V> {
public static Kv of() {
return new Kv();
}
public static Kv of(Object k, Object v){
return new Kv().set(k,v);
public static Kv of(Object k, Object v) {
return new Kv().set(k, v);
}
public Kv<K, V> set(K k, V v){
public Kv<K, V> set(K k, V v) {
put(k, v);
return this;
}
public Kv<K,V> putAll(Kv<K,V> kv) {
kv.forEach((k,v) -> put(k, v));
public Kv<K, V> putAll(Kv<K, V> kv) {
kv.forEach((k, v) -> put(k, v));
return this;
}
// 将obj 属性映射到Kv 中
public static Kv toKv(Object m, String ... fields) {
public static Kv toKv(Object m, String... fields) {
Kv kv = Kv.of();
Stream.of(fields).forEach(field -> {
String filedT = field;
@@ -45,10 +45,10 @@ public class Kv<K,V> extends LinkedHashMap<K,V> {
if (field.contains("=")) {
String[] arr = field.split("=");
filedT = arr[0];
filedS= arr[1];
filedS = arr[1];
}
Method method = m.getClass().getDeclaredMethod("get" + X.toUpperCaseFirst(filedS));
Method method = m.getClass().getDeclaredMethod("get" + Utils.toUpperCaseFirst(filedS));
if (method != null) {
kv.set(filedT, method.invoke(m));
}
@@ -108,87 +108,57 @@ public class Kv<K,V> extends LinkedHashMap<K,V> {
return null;
} else if (v.getClass() == clazz) {
return (T) v;
} else if (clazz == String.class) {
} else if (clazz == String.class) {
return (T) String.valueOf(v);
}
Object v1 = null;
Object v1 = v;
try {
if (v.getClass() == Long.class) {//多种数值类型的处理: Long => x
switch (clazz.getSimpleName()) {
case "int":
case "Integer": v1 = (int)(long) v; break;
case "short":
case "Short": v1 = (short)(long) v; break;
case "float":
case "Float": v1 = (float)(long) v; break;
case "byte":
case "Byte": v1 = (byte)(long) v; break;
default: v1 = v;
case "int", "Integer" -> v1 = (int) (long) v;
case "short", "Short" -> v1 = (short) (long) v;
case "float", "Float" -> v1 = (float) (long) v;
case "byte", "Byte" -> v1 = (byte) (long) v;
}
} else if (v.getClass() == Double.class) {
if (isNumber.test(clazz)) {
switch (clazz.getSimpleName()) {
case "long":
case "Long": v1 = (long)(double) v; break;
case "int":
case "Integer": v1 = (int)(double) v; break;
case "short":
case "Short": v1 = (short)(double) v; break;
case "float":
case "Float": v1 = (float)(double) v; break;
case "byte":
case "Byte": v1 = (byte)(double) v; break;
default: v1 = v;
case "long", "Long" -> v1 = (long) (double) v;
case "int", "Integer" -> v1 = (int) (double) v;
case "short", "Short" -> v1 = (short) (double) v;
case "float", "Float" -> v1 = (float) (double) v;
case "byte", "Byte" -> v1 = (byte) (double) v;
}
} else if (clazz == String.class){
} else if (clazz == String.class) {
v1 = String.valueOf(v);
}
} else if (v.getClass() == String.class) {
switch (clazz.getSimpleName()) {
case "Date":
v1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) v); break;
case "short":
case "Short": v1 = (short)Double.parseDouble((String) v); break;
case "float":
case "Float": v1 = (float)Double.parseDouble((String) v); break;
case "int":
case "Integer": v1 = (int)Double.parseDouble((String) v); break;
case "long":
case "Long": v1 = (long)Double.parseDouble((String) v); break;
case "double":
case "Double": v1 = Double.parseDouble((String) v); break;
case "byte":
case "Byte": v1 = Byte.parseByte((String) v); break;
default: v1 = v;
case "Date" -> v1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) v);
case "short", "Short" -> v1 = (short) Double.parseDouble((String) v);
case "float", "Float" -> v1 = (float) Double.parseDouble((String) v);
case "int", "Integer" -> v1 = (int) Double.parseDouble((String) v);
case "long", "Long" -> v1 = (long) Double.parseDouble((String) v);
case "double", "Double" -> v1 = Double.parseDouble((String) v);
case "byte", "Byte" -> v1 = Byte.parseByte((String) v);
}
} else if (v.getClass() == Integer.class) {
switch (clazz.getSimpleName()) {
case "long":
case "Long": v1 = (long) (int) v; break;
case "short":
case "Short": v1 = (short) (int) v; break;
case "float":
case "Float": v1 = (float) (int) v; break;
case "byte":
case "Byte": v1 = (byte)(int) v; break;
default: v1 = v;
case "long", "Long" -> v1 = (long) (int) v;
case "short", "Short" -> v1 = (short) (int) v;
case "float", "Float" -> v1 = (float) (int) v;
case "byte", "Byte" -> v1 = (byte) (int) v;
}
} else if (v.getClass() == Float.class) {
switch (clazz.getSimpleName()) {
case "long":
case "Long": v1 = (long) (float) v; break;
case "int":
case "Integer": v1 = (int) (float)v; break;
case "short":
case "Short": v1 = (short) (float) v; break;
case "byte":
case "Byte": v1 = (byte)(float) v; break;
default: v1 = v;
case "long", "Long" -> v1 = (long) (float) v;
case "int", "Integer" -> v1 = (int) (float) v;
case "short", "Short" -> v1 = (short) (float) v;
case "byte", "Byte" -> v1 = (byte) (float) v;
}
}
else {
} else {
v1 = v;
}
} catch (ParseException e) {
@@ -198,7 +168,7 @@ public class Kv<K,V> extends LinkedHashMap<K,V> {
}
public static <T> T toBean(Map map, Class<T> clazz) {
//按照方法名 + 类型寻找
//按照方法名 + 类型寻找,
//按照方法名 寻找
//+
Object obj = null;
@@ -208,10 +178,9 @@ public class Kv<K,V> extends LinkedHashMap<K,V> {
new IllegalArgumentException("创建对象实列失败", e); // 检查clazz是否有无参构造
}
for (String k : (Set<String>)map.keySet()) {
for (String k : (Set<String>) map.keySet()) {
Object v = map.get(k);
if (v == null) continue;
//寻找method
try {
String methodName = "set" + upFirst.apply(k);
Class tClazz = null;
@@ -243,7 +212,7 @@ public class Kv<K,V> extends LinkedHashMap<K,V> {
method.invoke(obj, toAs(v, tClazz));
}
//没有方法找属性注解
//没有方法,找属性注解
if (method == null) {
Field field = null;
Field[] fields = clazz.getDeclaredFields();
@@ -270,5 +239,4 @@ public class Kv<K,V> extends LinkedHashMap<K,V> {
}
}

View File

@@ -483,7 +483,7 @@ public final class MetaKit {
Set<String> allAlias;
if (!all) {
allAlias = X.concat(
allAlias = Utils.concat(
metaService.getFilters().stream().map(f -> {
String col = (String) f.getName();
String alias = col.split("[.]")[0];

View File

@@ -20,11 +20,13 @@ public class MetaListenter implements ApplicationListener {
@Resource(name = "property.dataPath")
private String dataPath;
public static ResourceFactory resourceFactory;
@Override
public void preStart(Application application) {
CompletableFuture.runAsync(()-> {
ResourceFactory rf = application.getResourceFactory();
resourceFactory = rf;
rf.inject(this);
MetaKit.dcate = dcate;

View File

@@ -1,31 +0,0 @@
package net.tccn.base;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
* @author: liangxianyou
*/
public final class PropKit {
private static Properties properties = new Properties();
static {
try {
// 读取导入配置文件
properties.load(new FileReader(new File("conf/config.txt")));
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getProperty(String key) {
return properties.getProperty(key);
}
public static String getProperty(String key, String value) {
String oldValue = getProperty(key);
properties.setProperty(key, value);
return oldValue;
}
}

View File

@@ -8,7 +8,7 @@ import java.util.stream.Stream;
/**
* Created by liangxianyou at 2019/3/19 18:01.
*/
public class X {
public class Utils {
/**
* 将集合数组合并到一个Set<T> 集合中

View File

@@ -7,9 +7,10 @@ import com.arangodb.Function;
import com.arangodb.entity.DocumentCreateEntity;
import com.arangodb.entity.DocumentDeleteEntity;
import com.arangodb.entity.MultiDocumentEntity;
import net.tccn.base.PropKit;
import net.tccn.base.X;
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;
@@ -26,40 +27,35 @@ import static java.util.Arrays.asList;
*/
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> sources = new HashMap();
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() {
return use("main");
}
public static ArangoSource use(String unit) {
if (unit == null || unit.isEmpty() || "main".equals(unit)) {
unit = "";
} else {
unit = "." + unit;
}
ArangoSource source = sources.get(unit);
if (source == null) {
String host = PropKit.getProperty("arango.host" + unit);
int port = Integer.parseInt(PropKit.getProperty("arango.port" + unit, "8529"));
String user = PropKit.getProperty("arango.user" + unit);
String password = PropKit.getProperty("arango.passwd" + unit);
source = new ArangoSource(new ArangoDB.Builder().host(host, port).user(user).password(password).build());
}
return source;
}
public ArangoDB arangoDB() {
return arangoDb;
ArangoSource arangoSource = new ArangoSource();
return arangoSource;
}
public ArangoDatabase db(String db) {
@@ -137,7 +133,7 @@ public class ArangoSource {
private Function<Doc, StringBuilder> orderBuilder = (t) -> {
StringBuilder buf = new StringBuilder();
Map<String, Integer> order = t.getOrder();
if (X.isEmpty(order)) {
if (Utils.isEmpty(order)) {
return buf.append(" sort d._key desc");
}
buf.append(" sort ");
@@ -151,7 +147,7 @@ public class ArangoSource {
private Function<Doc, StringBuilder> returnBuilder = (t) -> {
StringBuilder buf = new StringBuilder();
if (X.isEmpty(t.get_Shows())) {
if (Utils.isEmpty(t.get_Shows())) {
return buf.append(" return d");
}

View File

@@ -231,7 +231,6 @@ public abstract class Doc<T extends Doc> {
} catch (ArangoDBException e) {
System.out.println(aql);
e.printStackTrace();
ArangoSource.use();
}
return db.query(aql, clazz).asListRemaining();
}
@@ -241,7 +240,6 @@ public abstract class Doc<T extends Doc> {
} catch (ArangoDBException e) {
System.out.println(aql);
e.printStackTrace();
ArangoSource.use();
}
return db.query(aql, clazz).first();
}

View File

@@ -1,7 +1,7 @@
package net.tccn.base.dbq.fbean;
import net.tccn.base.Kv;
import net.tccn.base.X;
import net.tccn.base.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -31,7 +31,7 @@ public enum FilterType {
//不同的条件构建过滤语句
public static String buildSql(Filter filter) {
if (X.isEmpty(filter.getValue()) && X.isEmpty(filter.getValues())) {
if (Utils.isEmpty(filter.getValue()) && Utils.isEmpty(filter.getValues())) {
return "";
}
FilterType filterType = getFilterType(filter.getType());

View File

@@ -1,10 +1,13 @@
package net.tccn.base.dbq.fbean;
import lombok.Data;
import java.util.List;
/**
* Created by liangxianyou at 2018/12/14 15:36.
*/
@Data
public class Order {
private String col;
private int desc;//1 or -1

View File

@@ -1,6 +1,6 @@
package net.tccn.base.dbq.jdbc.api;
import net.tccn.base.X;
import net.tccn.base.Utils;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -31,7 +31,7 @@ public class DbKit implements DbSource{
this.catalog = catalog;
try {
DbSource dbSource = X.getDbSource(DbSource.class, dbAccount.getCate());
DbSource dbSource = Utils.getDbSource(DbSource.class, dbAccount.getCate());
dbSource.setDbAccount(dbAccount);
dbSource.setCatalog(catalog);

View File

@@ -60,10 +60,9 @@ public class DbSourceMysql implements DbSource {
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
List list = new ArrayList();
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
while (rs.next()) {
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
Map row = new HashMap();
for (int i = 1; i <= count; i++) {
String columnTypeName = metaData.getColumnTypeName(i);
@@ -87,6 +86,7 @@ public class DbSourceMysql implements DbSource {
return list;
} catch (SQLException e) {
System.out.println("sql :"+ sql);
e.printStackTrace();
return null;
} finally {

View File

@@ -6,7 +6,6 @@ import net.tccn.meta.MetaLink;
import net.tccn.meta.MetaService;
import net.tccn.meta.MetaTable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@@ -64,20 +63,20 @@ public class ParseMysql implements Parser {
if (sameDbFun.test(tables) || true) {
// where 1=1 and xx=xx
StringBuffer bufWhere = new StringBuffer();
if (!X.isEmpty(filters)) {
if (!Utils.isEmpty(filters)) {
bufWhere.append(Filter.filter(filters, DbType.MYSQL));
}
//select a.x, b.y, c.z
StringBuffer bufSelect = new StringBuffer();
bufSelect.append("select ");
if ("export".equals(fBean.getType()) && !X.isEmpty(exports)) {
if ("export".equals(fBean.getType()) && !Utils.isEmpty(exports)) {
exports.forEach(x -> {
bufSelect.append(x.get("col")).append(" as ").append("'").append(x.get("col")).append("',");
});
bufSelect.deleteCharAt(bufSelect.length() - 1);
}
else if ("list".equals(fBean.getType()) && !X.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("',");
});
@@ -88,13 +87,13 @@ public class ParseMysql implements Parser {
//from
StringBuilder bufFrom = new StringBuilder();
bufFrom.append(" from ").append(metaTable.getCatalog()).append(".`").append(metaTable.getName()).append("` ").append(metaTable.getAlias());
bufFrom.append(" from ").append(metaTable.getCatalog()).append(".`").append(metaTable.getName()).append("` `").append(metaTable.getAlias()).append("`");
//left join
if (!X.isEmpty(links)) {
if (!Utils.isEmpty(links)) {
links.forEach(x -> {
MetaTable 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.getName()).append(" `").append(rightTable.getAlias()).append("` on ");
int tag = bufFrom.length();
x.getLink().forEach((k, v) -> {
if (bufFrom.length() > tag) {
@@ -108,7 +107,7 @@ public class ParseMysql implements Parser {
StringBuffer bufOth = new StringBuffer();
//order by
if (!X.isEmpty(orders)) {
if (!Utils.isEmpty(orders)) {
bufOth.append(" ").append(Order.order(orders, DbType.MYSQL));
}
//limit
@@ -168,18 +167,18 @@ public class ParseMysql implements Parser {
List<String> keys = data.keySet()
.stream()
.filter(x ->
x.startsWith(alias + ".") || !X.isEmpty(data.get(alias + "." + x))
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());
} else if (keys.size() == 0) {
throw new CfgException("保存数据失败提交数据不能改空");
throw new CfgException("保存数据失败,提交数据不能改空");
}
//单主键
String pv = data.get(alias + "." + pks[0]);
if (X.isEmpty(pv)) { //新增
if (Utils.isEmpty(pv)) { //新增
String sqlTpl = "INSERT INTO `%s` (%s) VALUES %s;"; // para: table、 ks、 vs
StringBuffer ks = new StringBuffer();// `k1`,`k2`,`k3`, ...
StringBuffer vs = new StringBuffer();// `v1`,`v2`,`v3`, ...

View File

@@ -14,6 +14,7 @@ public class Field {
private String inType;
private String inExt;
private Boolean pk; // 是否主键
private Boolean notNull; // 是否主键
public Field() {}

View File

@@ -5,6 +5,7 @@ import net.tccn.base.JBean;
import net.tccn.base.Kv;
import org.redkale.net.http.*;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -16,27 +17,44 @@ import java.util.List;
@WebServlet(value = {"/upload/*"}, comment = "测试servlet")
public class FileServlet extends BaseServlet {
@Resource(name = "property.upfile.dir")
private String dir = "";
@Resource(name = "property.upfile.view")
private String view = "";
private String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS";
@HttpMapping(url = "/upload/", comment = "文件上传,访问地址:/upload/x")
public void uploadExcel(HttpRequest request, HttpResponse response) {
JBean jBean = new JBean();
List list = new ArrayList();
String cate = request.getParameter("cate");
List data = new ArrayList();
try {
for (MultiPart part : request.multiParts()) {
String filePath = "u/table/" + part.getFilename();
File destFile = new File(webroot, filePath);
destFile.getParentFile().mkdirs();
String name = part.getFilename();
String suffix = name.substring(name.lastIndexOf("."));
String path = String.format(format, System.currentTimeMillis()) + suffix;
File destFile = new File((winos ? webroot + "/tem/" : dir) + path);
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
part.save(destFile);
list.add(
Kv.of("name", part.getFilename())
.set("filePath", filePath)
.set("viewPath", filePath)
);
String viewPath = (winos ? "/tem/" : view) + path;
if ("editor".equalsIgnoreCase(cate)) {
data.add(viewPath);
} else {
data.add(Kv.of("name", part.getFilename()).set("filePath", viewPath).set("viewPath", viewPath));
}
}
} catch (IOException e) {
e.printStackTrace();
}
response.finish(jBean.set(0, "", list));
if ("editor".equalsIgnoreCase(cate)) {
response.finish(Kv.of("errno", 0).set("data", data));
} else {
response.finish(JBean.by(0, "", data));
}
}
}

View File

@@ -206,6 +206,7 @@ public class MetadataService extends BaseService { //arango
public JBean dbPlatUpdate(MetaTable metaTable, @RestParam(name = "platToken") String token) {
MetaTable _metaTable = MetaKit.getMetaTableByKey(metaTable.getKey());
_metaTable.setName(metaTable.getName());
_metaTable.setComment(metaTable.getComment());
_metaTable.setCatalog(metaTable.getCatalog());
_metaTable.setDbPlatId(metaTable.getDbPlatId());

View File

@@ -57,7 +57,7 @@ public class DataService extends BaseService {
PageBean page = DbExecutors.findPage(fBean);
Kv heads = MetaKit.cfgExport(fBean.getName(), token);
if (X.isEmpty(fileName)) {
if (Utils.isEmpty(fileName)) {
fileName = String.format("export_excel_%s", System.currentTimeMillis());
}

View File

@@ -0,0 +1,10 @@
package net.tccn.tmp;
import java.util.List;
import java.util.Map;
public class QStat {
private String sql;
private List<Map<String, String>> header;
}