新增:1、qtask-debug结果渲染为表格

2、mdict 存贮到MySQL, meta 业务预览支持字典渲染验证
     3、其他交互优化
This commit is contained in:
2024-04-05 00:29:43 +08:00
parent 3bbf78f51c
commit 36a30ba2b3
14 changed files with 300 additions and 98 deletions

View File

@@ -160,7 +160,7 @@
{url:"/content/create.html", name:"内容管理", icon:"icon-edit-sign"}, {url:"/content/create.html", name:"内容管理", icon:"icon-edit-sign"},
{url:"/plat/dev.html", name:"dev", icon:"icon-beaker"}, {url:"/plat/dev.html", name:"dev", icon:"icon-beaker"},
] ]
}, },*/
{name: "Zhub", url: "/zhub", nodes: [ {name: "Zhub", url: "/zhub", nodes: [
{url:"/zhub/monitor.html", name:"Monitor", icon:"icon-server"}, {url:"/zhub/monitor.html", name:"Monitor", icon:"icon-server"},
{url:"/zhub/topic.html", name:"Topics", icon:"icon-server"}, {url:"/zhub/topic.html", name:"Topics", icon:"icon-server"},
@@ -168,7 +168,7 @@
{url:"/zhub/timer.html", name:"Timer", icon:"icon-server"}, {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/wxapp.html", name:"公众号管理", icon:"icon-server"},
{url:"/weixin/user.html", name:"用户管理", icon:"icon-server"}, {url:"/weixin/user.html", name:"用户管理", icon:"icon-server"},
{url:"/weixin/templateMessage.html", name:"模板消息", icon:"icon-server"}, {url:"/weixin/templateMessage.html", name:"模板消息", icon:"icon-server"},
@@ -217,6 +217,9 @@
loadMain(item) { loadMain(item) {
this.menus = item.nodes || [item]; this.menus = item.nodes || [item];
this.pageId = item.name; this.pageId = item.name;
// 加载新模块下的第一个
this.loadPage(this.menus[0]);
}, },
refresh() { refresh() {
refresh().then(res => { refresh().then(res => {

View File

@@ -3,12 +3,25 @@
<h3 class="pull-left">业务预览</h3> <h3 class="pull-left">业务预览</h3>
<div class="col-xs-4 pull-right"> <div class="col-xs-4 pull-right">
<div class="input-group"> <div class="input-group">
<span class="input-group-btn"> <!--<span class="input-group-btn">
<button class="btn btn-default" type="button">添加过滤条件</button> <button class="btn btn-default" type="button">添加过滤条件</button>
</span> </span>
<select class="form-control" v-model="addFilter" style="width: 130px;"> <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> <option v-for="f in cfg.filters" :value="f.name" v-show="!f.checked">{{f.label}}</option>
</select> </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"> <span class="input-group-btn">
<button @click="findList()" class="btn btn-primary" type="button"> 查询</button> <button @click="findList()" class="btn btn-primary" type="button"> 查询</button>
@@ -46,32 +59,46 @@
<div class="col-xs-2"> <div class="col-xs-2">
<div style="padding-left: 10px;/*background-color: #ccc;*/width: 100%"> 业务列表(Meta-Service)</div> <div style="padding-left: 10px;/*background-color: #ccc;*/width: 100%"> 业务列表(Meta-Service)</div>
<ul class="nav nav-tabs nav-stacked dlist" style="height: 100%"> <ul class="nav nav-tabs nav-stacked dlist" style="height: 100%">
<li :class="[{'active':service==item.alias}]" v-for="item in services" > <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> <a @click="service=item.name" :title="`${item.name}`" v-text="`${item.comment}`" href="javascript:;"></a>
</li> </li>
</ul> </ul>
</div> </div>
<!-- 预览功能 --> <!-- 预览功能 -->
<div class="col-xs-10"> <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"> <!--<div class="input-group col-xs-4" v-for="(filter,index) in cfg.filters" v-if="filter.checked">
<span class="input-group-addon" style="max-width: 130px;">{{filter.label}}</span> <span class="input-group-addon">{{filter.label}}</span>
<select class="form-control" v-model="filter['type']" style="width: 95px;"> <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;">{{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> <option v-for="(t, i) in filter.filterType" :value="t.name" v-text="t.remark"></option>
</select> </select>
<span class="input-group-addon fix-border fix-padding"></span> <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']"> <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"> <select v-if="filter.inType == 'DICT'" class="form-control" v-model="filter['value']">
<!-- option v-for="(t, index) in filter.filterType" :value="t.name" v-text="t.remark"></option --> <!-- option v-for="(t, index) in filter.filterType" :value="t.name" v-text="t.remark"></option -->
<option value=""> 字典值一</option> <option value=""> 字典值一</option>
<option value=""> 字典值二</option> <option value=""> 字典值二</option>
</select> </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> <a href="javascript:;" @click="filter.checked = false;"><i class="icon icon-trash"></i></a>
</span> </span>
</div> </div>
@@ -238,7 +265,7 @@
return {1:"男",2:"女"}[v] || "未知性别" return {1:"男",2:"女"}[v] || "未知性别"
} }
let {getServiceList, getCfg, getDataList, exportData, dataDel, dataSave} = meta let {getServiceList, getDataList, exportData, dataDel, dataSave} = meta
let {showOk} = red let {showOk} = red
let vm = new Vue({ let vm = new Vue({
el:".data-list", el:".data-list",
@@ -259,12 +286,13 @@
limit: {pn: 1, ps: 20, total: 0}, limit: {pn: 1, ps: 20, total: 0},
order: {col: "", desc: 1}, order: {col: "", desc: 1},
pk: "", pk: "",
detailData: {} detailData: {},
dictData: {}, // 存放字典数据
}, },
watch: { watch: {
addFilter(v) { addFilter(v) {
this.cfg.filters.forEach(function (f) { this.cfg.filters.forEach(function (f) {
if (f.name == v) { if (f.name === v) {
f["checked"] = true; f["checked"] = true;
vm.addFilter = ""; vm.addFilter = "";
} }
@@ -272,8 +300,7 @@
}, },
service() { service() {
this.loadCfg(function () { this.loadCfg(function () {
this.limit = {pn: 1, ps: 20, total: 0}; vm.limit = {pn: 1, ps: 20, total: 0};
this.order = {col:"", desc:1};
vm.findList(); vm.findList();
}); });
}, },
@@ -305,7 +332,7 @@
}); });
}, },
loadCfg(back) { loadCfg(back) {
getCfg({name: this.service}).then(res => { meta.getCfg({name: this.service}).then(res => {
// res['type'] = res.filters[0]['name'] // res['type'] = res.filters[0]['name']
for (i in res["filters"]) { for (i in res["filters"]) {
@@ -328,6 +355,11 @@
}) })
} }
} }
if (fbean['orders'] && fbean['orders'].length > 0) {
this.order = fbean['orders'][0]
} else {
this.order = {col: "", desc: 0};
}
if (back) { if (back) {
back(); back();
@@ -337,8 +369,25 @@
dealFieldFmt(bean, colFmt) { //处理字典数据 及 自定义函数处理数据 dealFieldFmt(bean, colFmt) { //处理字典数据 及 自定义函数处理数据
let v = bean[colFmt["col"]] 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
}
for (let i in dictArr) {
if (dictArr[i].value + "" === v + "") {
return dictArr[i].label
}
}
return v
} else if (colFmt.inType == "INPUT_DAY") { } else if (colFmt.inType == "INPUT_DAY") {
return red.timeFmt(new Date(v), 'yyyy-MM-dd') return red.timeFmt(new Date(v), 'yyyy-MM-dd')
} else if (colFmt.inType == "INPUT_TIME") { } else if (colFmt.inType == "INPUT_TIME") {
@@ -395,8 +444,12 @@
return str; return str;
}, },
sortEvent(col) { sortEvent(col) {
if (vm.order.col == col) { if (vm.order.col === col) {
vm.order.desc = -vm.order.desc vm.order.desc = -vm.order.desc
// 第一次 1、第二次 -1、第三次点击的时候回到1这个时候取消排序
if (vm.order.desc === 1) {
vm.order.col = ''
}
} else { } else {
vm.order.col = col; vm.order.col = col;
vm.order.desc = 1; vm.order.desc = 1;
@@ -487,6 +540,9 @@
}, },
mounted() { mounted() {
this.serviceList(); this.serviceList();
dict.list({}).then(res => {
this.dictData = res
})
} }
}); });
</script> </script>

View File

@@ -10,10 +10,10 @@
.dropdown-menu-table .table td { .dropdown-menu-table .table td {
padding: 0; padding: 0;
} }
.dropdown-menu-table .table a { /*.dropdown-menu-table .table a {
padding: 8px; padding: 8px;
display: block; display: block;
} }*/
/*.dropdown-menu-table .table a:hover, /*.dropdown-menu-table .table a:hover,
.dropdown-menu-table .table a:active, .dropdown-menu-table .table a:active,
.dropdown-menu-table .table a:focus { .dropdown-menu-table .table a:focus {
@@ -160,15 +160,14 @@
<div class="col-xs-3"> <div class="col-xs-3">
<div class="base-info"> 业务列表</div> <div class="base-info"> 业务列表</div>
<table class="table"> <table class="table table-bordered tlist">
<tr> <tr>
<th>业务KEY</th> <th>业务KEY</th>
<th>业务名称</th> <th>业务名称</th>
<th>操作</th> <th>操作</th>
</tr> </tr>
<tr v-for="item in services" @click="service=item.name;serviceLabel=item.comment;"> <tr v-for="item in services" @click="service=item.name;serviceLabel=item.comment;" :class="[{'active': item.name==service}]">
<td> <td>
<i class="icon icon-ok" v-if="item.name==service" style="color: #7f74c4"></i>
{{item.name}} {{item.name}}
</td> </td>
<td>{{item.comment}}</td> <td>{{item.comment}}</td>
@@ -227,7 +226,7 @@
<td v-show="status=='detail'"><input type="checkbox" v-model="detailArr" :value="sheet + '$' + item.name"></td> <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-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.label"></td>
<!--<td v-text="item.type"></td> <!--<td v-text="item.type"></td>
<td v-text="item.inType"></td> <td v-text="item.inType"></td>

View File

@@ -94,7 +94,7 @@
<div class="base-info"> 字段信息</div> <div class="base-info"> 字段信息</div>
<table :class="[{'table':status!=2},'table-bordered']"> <table :class="[{'table':status!=2},'table-bordered']">
<tr style="background-color: #f1f1f1"> <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"><input type="checkbox"></td>
<th v-show="status==1"></th> <th v-show="status==1"></th>
<th>列名</th> <th>列名</th>
@@ -109,7 +109,7 @@
</tr> </tr>
<tr v-for="(item, index) in meta.items" class="item"> <tr v-for="(item, index) in meta.items" class="item">
<td v-show="status==1" class="icon icon-move"></td> <td v-show="status==1" class="icon icon-move"></td>
<td v-show="status!=2" v-text="item.name" style="background-color: rgb(235, 235, 228);"></td> <td v-show="status!=2" v-text="item.name"></td>
<td v-show="status!=2" v-text="item.label"></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.type"></td>
<!-- <!--

View File

@@ -39,7 +39,7 @@
<div class="col-md-5" style=""> <div class="col-md-5" style="">
<ul id="treeDemo" class="ztree" style="display: none"></ul> <ul id="treeDemo" class="ztree" style="display: none"></ul>
<table class="table table-bordered table-hover" style="width: 100%; "> <table class="table table-bordered tlist" style="width: 100%; ">
<thead> <thead>
<tr> <tr>
<th v-for="field in cfg.cols" v-text="field.label"></th> <th v-for="field in cfg.cols" v-text="field.label"></th>
@@ -47,7 +47,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="row in list.rows" @click="openDia(row)"> <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 v-for="field in cfg.cols" v-title="row[field.col]" v-text="row[field.col]"></td>
<td> <td>
<a @click="openDia(row)" href="javascript:;">编辑</a> | <a @click="openDia(row)" href="javascript:;">编辑</a> |
@@ -106,19 +106,19 @@
<td> <td>
<input v-model="row.title" class="form-control"> <input v-model="row.title" class="form-control">
</td> </td>
<th style="width: 120px">任务KEY</th>
<td>
<input v-model="row.name" class="form-control">
</td>
</tr>
<tr>
<th>数据平台</th> <th>数据平台</th>
<td> <td>
<select v-model="row.dbid" class="form-control"> <select v-model="row.dbid" class="form-control">
<option v-for="item in dbPlats" :value="item.dbid" v-text="item.dbname"></option> <option v-for="item in dbPlats" :value="item.dbid" v-text="item.dbname"></option>
</select> </select>
</td> </td>
<th>CataLog</th> </tr>
<tr>
<th>任务KEY</th>
<td>
<input v-model="row.name" class="form-control">
</td>
<th style="width: 120px">CataLog</th>
<td> <td>
<select v-model="row.catalog" class="form-control"> <select v-model="row.catalog" class="form-control">
<option v-for="item in catalogs()" :value="item" v-text="item"></option> <option v-for="item in catalogs()" :value="item" v-text="item"></option>
@@ -171,8 +171,43 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<th>调试结果</th> <td colspan="4"></td>
<td colspan="3" class="tpl-debug"><pre class="pre-scrollable">{{debugRet}}</pre></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> </tr>
</table> </table>
<div v-show="editStatus!=1" style="text-align: center"> <div v-show="editStatus!=1" style="text-align: center">
@@ -272,7 +307,7 @@
let {dbList} = plat let {dbList} = plat
function beforeDrag(treeId, treeNodes) { function beforeDrag(treeId, treeNodes) {
for (var i=0,l=treeNodes.length; i<l; i++) { for (let i=0,l=treeNodes.length; i<l; i++) {
if (treeNodes[i].drag === false) { if (treeNodes[i].drag === false) {
return false; return false;
} }
@@ -306,6 +341,8 @@
sysPlats: [{name: "工控系统"}], sysPlats: [{name: "工控系统"}],
editStatus: 0, editStatus: 0,
debugRet: "", debugRet: "",
debugData: "",
debugView: "TABLE", // 0:TABLE, 1:SQL, 3:JSON
// ZTree // ZTree
setting : { setting : {
@@ -338,6 +375,7 @@
}) })
} }
this.debugRet = "" this.debugRet = ""
this.debugData = ""
$(".tpl-content>textarea").attr("rows", this.countLines(row.content)) $(".tpl-content>textarea").attr("rows", this.countLines(row.content))
$(".tpl-remark>textarea").attr("rows", this.countLines(row.remark, 2, 5)) $(".tpl-remark>textarea").attr("rows", this.countLines(row.remark, 2, 5))
} }
@@ -420,9 +458,9 @@
}, },
debug: function () { debug: function () {
qtask.qtaskDebug({task: this.row}).then(res => { qtask.qtaskDebug({task: this.row}).then(res => {
this.debugRet = "";
this.debugRet = res; this.debugRet = res;
red.showOk("查询成功") red.showOk("查询成功")
this.parseDebugRet(res)
}) })
}, },
countLines: function (text='', min=3, max=15) { countLines: function (text='', min=3, max=15) {
@@ -452,6 +490,51 @@
} }
this.row.para = JSON.stringify(_para) 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 () { mounted: function () {

View File

@@ -268,7 +268,7 @@ ul.pager {
} }
body,table,th,td,.table-bordered,textarea,.form-control,button,pre,hr,.panel,input,checkbox, body,table,tr,/*th,td,*/.table-bordered,textarea,.form-control,button,pre,hr,.panel,input,checkbox,
.btn-default,.input-group-btn,.input-group, .btn-default,.input-group-btn,.input-group,
/*.nav-tabs>li.active>a,.nav-tabs>li:focus,*/ /*.nav-tabs>li.active>a,.nav-tabs>li:focus,*/
.previous>a,.next>a, .previous>a,.next>a,
@@ -276,7 +276,8 @@ body,table,th,td,.table-bordered,textarea,.form-control,button,pre,hr,.panel,inp
.input-group-addon, .input-group-addon,
.modal-content,.modal-header,.modal-body,.modal-footer, .modal-content,.modal-header,.modal-body,.modal-footer,
.base-info,.plat-switch, .base-info,.plat-switch,
.tlist>li.active>a,.tlist>li>a, /*.tlist>li.active>a,*/
.tlist>li>a,
.alert-info{ .alert-info{
background-color: #22272e !important; background-color: #22272e !important;
color: #c3c5c7 !important; color: #c3c5c7 !important;
@@ -330,6 +331,51 @@ body,table,th,td,.table-bordered,textarea,.form-control,button,pre,hr,.panel,inp
table { table {
width: 100%; 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 #a5cff8!important;
background-color: #4c5960;
}
} }
.plat-switch { .plat-switch {

View File

@@ -37,7 +37,7 @@ public class QTask extends BaseEntity {
private String name = ""; private String name = "";
@Comment("[所属平台ID]") @Comment("[所属平台ID]")
@Column(updatable = false) @Column(updatable = false, comment = "")
private Integer platid; private Integer platid;
@Comment("[业务名称]") @Comment("[业务名称]")

View File

@@ -5,7 +5,8 @@ import lombok.Getter;
import net.tccn.base.dbq.jdbc.api.DbAccount; import net.tccn.base.dbq.jdbc.api.DbAccount;
import net.tccn.base.dbq.jdbc.api.DbKit; import net.tccn.base.dbq.jdbc.api.DbKit;
import net.tccn.base.dbq.table.Field; 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.meta.*;
import net.tccn.plat.MPlat; import net.tccn.plat.MPlat;
import net.tccn.qtask.TaskKit; import net.tccn.qtask.TaskKit;
@@ -47,7 +48,7 @@ public class MetaKit extends AbstractService {
@Getter @Getter
private static List<QTask> qTasks; private static List<QTask> qTasks;
@Getter @Getter
private static List<Dict> dicts; private static List<MDict> dicts;
@Resource(name = "property.dataCate") @Resource(name = "property.dataCate")
protected String dcate = "db"; protected String dcate = "db";
@@ -68,7 +69,10 @@ public class MetaKit extends AbstractService {
else if (clazz == MTable.class) mTables = metaSource.queryList(MTable.class); else if (clazz == MTable.class) mTables = metaSource.queryList(MTable.class);
else if (clazz == MService.class) metaServices = metaSource.queryList(MService.class); else if (clazz == MService.class) metaServices = metaSource.queryList(MService.class);
else if (clazz == MLink.class) metaLinks = metaSource.queryList(MLink.class); else if (clazz == MLink.class) metaLinks = metaSource.queryList(MLink.class);
else if (clazz == Dict.class) dicts = metaSource.queryList(Dict.class); else if (clazz == MDict.class) {
dicts = metaSource.queryList(MDict.class);
DictKit.cleanCache();
}
/*if (clazz == MUser.class) { /*if (clazz == MUser.class) {
users = metaSource.queryList(MUser.class); users = metaSource.queryList(MUser.class);
}*/ }*/
@@ -83,7 +87,7 @@ public class MetaKit extends AbstractService {
reloadxAsync(MService.class); reloadxAsync(MService.class);
reloadxAsync(MTable.class); reloadxAsync(MTable.class);
reloadxAsync(MLink.class); reloadxAsync(MLink.class);
// reloadxAsync(Dict.class); reloadxAsync(MDict.class);
/*metaTables.forEach(x -> { /*metaTables.forEach(x -> {
@@ -278,11 +282,11 @@ public class MetaKit extends AbstractService {
* *
* @param plattoken * @param plattoken
*/ */
public static Map<String, List<Dict>> getDictData(String plattoken) { public static Map<String, List<MDict>> getDictData(String plattoken) {
/*Integer platId = MetaKit.getPlatId(plattoken); int platid = MetaKit.getPlatId(plattoken);
Map<String, List<Dict>> dicts = MetaKit.dicts.stream().filter(x -> x.getPlatid() == (int) platId).collect(Collectors.groupingBy(Dict::getType)); Map<String, List<MDict>> dicts = MetaKit.dicts.stream().filter(x -> x.getPlatid() == platid).collect(Collectors.groupingBy(MDict::getType));
return dicts;*/ return dicts;
return new HashMap<>(); // return new HashMap<>();
} }
// ----------------------------------- // -----------------------------------

View File

@@ -1,25 +0,0 @@
package net.tccn.dict;
import lombok.Getter;
import lombok.Setter;
import net.tccn.base.BaseEntity;
import javax.persistence.Table;
/**
* @author: liangxianyou
*/
@Getter
@Setter
@Table(name = "Dict")
public class Dict extends BaseEntity {
private int dictid;
private String type; // 字典类型
private String value; // 字典值
private String label; // 中文名
private String pValue; // 父级字典值
private String code; //
private Integer platid; // 系统平台id
}

View File

@@ -13,7 +13,7 @@ import java.util.*;
public final class DictKit { public final class DictKit {
private static Map<String, DictKit> kits = new HashMap<>(); private static Map<String, DictKit> kits = new HashMap<>();
private String plattoken; private String plattoken;
private Map<String, List<Dict>> dicts; private Map<String, List<MDict>> dicts;
private DictKit() { private DictKit() {
} }
@@ -29,8 +29,8 @@ public final class DictKit {
return dictKit; return dictKit;
} }
public synchronized void reload() { public static synchronized void cleanCache() {
this.dicts = MetaKit.getDictData(plattoken); kits.clear();
} }
// 初始化字典,不同模式下,数据来源不同 // 初始化字典,不同模式下,数据来源不同
@@ -123,20 +123,20 @@ public final class DictKit {
* @param code * @param code
* @return * @return
*/ */
public List<Dict> getDicts(String code) { public List<MDict> getDicts(String code) {
Objects.requireNonNull(code, "code 不能为空"); Objects.requireNonNull(code, "code 不能为空");
return dicts.getOrDefault(code, new ArrayList<>()); return dicts.getOrDefault(code, new ArrayList<>());
} }
public Map<String, List<Dict>> getDicts() { public Map<String, List<MDict>> getDicts() {
return dicts; return dicts;
} }
public String getDictLabel(String code, String value) { public String getDictLabel(String code, String value) {
Objects.requireNonNull(code, "code 不能为空"); Objects.requireNonNull(code, "code 不能为空");
Objects.requireNonNull(value, "value 不能为空"); Objects.requireNonNull(value, "value 不能为空");
List<Dict> dicts = getDicts(code); List<MDict> dicts = getDicts(code);
Optional<Dict> any = dicts.stream().filter(x -> value.equals(x.getValue())).findAny(); Optional<MDict> any = dicts.stream().filter(x -> value.equals(x.getValue())).findAny();
return any.isPresent() ? any.get().getLabel() : ""; return any.isPresent() ? any.get().getLabel() : "";
} }
@@ -144,8 +144,8 @@ public final class DictKit {
Objects.requireNonNull(code, "code 不能为空"); Objects.requireNonNull(code, "code 不能为空");
Objects.requireNonNull(label, "label 不能为空"); Objects.requireNonNull(label, "label 不能为空");
List<Dict> dicts = getDicts(code); List<MDict> dicts = getDicts(code);
Optional<Dict> any = dicts.stream().filter(x -> label.equals(x.getLabel())).findAny(); Optional<MDict> any = dicts.stream().filter(x -> label.equals(x.getLabel())).findAny();
return any.isPresent() ? any.get().getValue() : ""; return any.isPresent() ? any.get().getValue() : "";
} }

View File

@@ -23,7 +23,7 @@ public class DictService extends BaseService {
DictKit dictKit = DictKit.use(token); DictKit dictKit = DictKit.use(token);
if (!isEmpty(type)) { if (!isEmpty(type)) {
List<Dict> dicts = dictKit.getDicts(type); List<MDict> dicts = dictKit.getDicts(type);
jBean.setBody(dicts); jBean.setBody(dicts);
} else { } else {
Map dicts = dictKit.getDicts(); 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

@@ -4,7 +4,6 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.tccn.base.BaseEntity; import net.tccn.base.BaseEntity;
import org.redkale.annotation.Comment; import org.redkale.annotation.Comment;
import org.redkale.persistence.Column;
import org.redkale.persistence.Entity; import org.redkale.persistence.Entity;
import org.redkale.persistence.Id; import org.redkale.persistence.Id;
@@ -25,7 +24,7 @@ public class MPlat extends BaseEntity {
@Comment("[备注信息]") @Comment("[备注信息]")
private String remark; private String remark;
@Comment("[创建时间]") /*@Comment("[创建时间]")
@Column(updatable = false) @Column(updatable = false)
private Long createtime; private Long createtime;*/
} }

View File

@@ -1,7 +1,7 @@
import net.tccn.base.*; import net.tccn.base.*;
import net.tccn.base.dbq.fbean.FBean; import net.tccn.base.dbq.fbean.FBean;
import net.tccn.base.dbq.parser.ParseMysql; 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.dict.DictKit;
import org.junit.Test; import org.junit.Test;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
@@ -579,9 +579,9 @@ public class RunTest<T> {
System.out.println(ipv4Count("0.0.0.2", "0.0.0.0")); System.out.println(ipv4Count("0.0.0.2", "0.0.0.0"));
} }
Predicate<Dict> isProvice = (s) -> String.valueOf(s.getValue()).trim().endsWith("0000"); Predicate<MDict> isProvice = (s) -> String.valueOf(s.getValue()).trim().endsWith("0000");
Predicate<Dict> isCity = (s) -> !isProvice.test(s) && String.valueOf(s.getValue()).trim().endsWith("00"); Predicate<MDict> 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)); 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() { public void dictTest() {