Compare commits

...

14 Commits

10 changed files with 125 additions and 130 deletions

View File

@ -241,8 +241,15 @@ export default {
req: async function( id){ req: async function( id){
return await http.post(`${config.API_URL}/system/user/${id}/reset_password/`); return await http.post(`${config.API_URL}/system/user/${id}/reset_password/`);
} }
},
routers: {
url: `${config.API_URL}/system/user/route/`,
name: "菜单列表",
req: async function(params){
return await http.get(this.url, params);
} }
}, },
},
post: { post: {
list: { list: {
url: `${config.API_URL}/system/post/`, url: `${config.API_URL}/system/post/`,

View File

@ -3,6 +3,7 @@
</template> </template>
<script> <script>
import { markRaw } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import T from './echarts-theme-T.js'; import T from './echarts-theme-T.js';
echarts.registerTheme('T', T); echarts.registerTheme('T', T);
@ -27,7 +28,15 @@
option: { option: {
deep:true, deep:true,
handler (v) { handler (v) {
unwarp(this.myChart).setOption(v); let that = this;
if(that.myChart!==null){
that.myChart.setOption(v);
}else{
let myChart = markRaw(echarts.init(that.$refs.scEcharts, 'T'));
myChart.setOption(v);
that.myChart = myChart;
}
// unwarp(this.myChart).setOption(v);
} }
} }
}, },
@ -54,7 +63,7 @@
}, },
methods: { methods: {
draw(){ draw(){
var myChart = echarts.init(this.$refs.scEcharts, 'T'); var myChart = markRaw(echarts.init(this.$refs.scEcharts, 'T'));
myChart.setOption(this.myOptions); myChart.setOption(this.myOptions);
this.myChart = myChart; this.myChart = myChart;
window.addEventListener('resize', () => myChart.resize()); window.addEventListener('resize', () => myChart.resize());

View File

@ -33,6 +33,9 @@ const DEFAULT_CONFIG = {
//请求是否开启缓存 //请求是否开启缓存
REQUEST_CACHE: false, REQUEST_CACHE: false,
//静态菜单static | 动态菜单dynamic
MENU_CATE:'dynamic',
//布局 默认default | 通栏header | 经典menu | 功能坞dock //布局 默认default | 通栏header | 经典menu | 功能坞dock
//dock将关闭标签和面包屑栏 //dock将关闭标签和面包屑栏
LAYOUT: 'header', LAYOUT: 'header',
@ -50,7 +53,8 @@ const DEFAULT_CONFIG = {
LANG: 'zh-cn', LANG: 'zh-cn',
//主题颜色 //主题颜色
COLOR: '#536DFE', // COLOR: '#536DFE',//gx、gz、tkx
COLOR: '#0052d9',//bx
//是否加密localStorage, 为空不加密可填写AES(模式ECB,移位Pkcs7)加密 //是否加密localStorage, 为空不加密可填写AES(模式ECB,移位Pkcs7)加密
LS_ENCRYPTION: '', LS_ENCRYPTION: '',

View File

@ -66,21 +66,34 @@ router.beforeEach(async (to, from, next) => {
} }
//加载动态/静态路由 //加载动态/静态路由
if (!isGetRouter) { if (!isGetRouter) {
let userMenu = [];
if(tool.data.get('BASE_INFO').base.base_menucate=='dynamic'){
userMenu = tool.data.get("MENU") || [];
}else{
let permissions = tool.data.get("PERMISSIONS") || [];//账号页面权限 let permissions = tool.data.get("PERMISSIONS") || [];//账号页面权限
let userMenu = userRoutes;//静态路由 // console.log("permissions",permissions);
userMenu = userRoutes;//静态路由
userMenu = treeFilter(userRoutes, node => { userMenu = treeFilter(userRoutes, node => {
return node.meta.perms ? node.meta.perms.filter(item => permissions.indexOf(item) > -1).length > 0 : true return node.meta.perms ? node.meta.perms.filter(item => permissions.indexOf(item) > -1).length > 0 : true
}); });
}
try {
var menuRouter = filterAsyncRouter(userMenu); var menuRouter = filterAsyncRouter(userMenu);
menuRouter = flatAsyncRoutes(menuRouter); menuRouter = flatAsyncRoutes(menuRouter);
menuRouter.forEach(item => { menuRouter.forEach(item => {
router.addRoute("layout", item) router.addRoute("layout", item)
}); });
routes_404_r = router.addRoute(routes_404); routes_404_r = router.addRoute(routes_404);
if (to.matched.length == 0) {
router.push(to.fullPath);
}
isGetRouter = true; isGetRouter = true;
next({ ...to, replace: true }); // 重新触发导航
return;
}catch (e) {
isGetRouter = false;
console.error('路由加载失败:', e);
next('/login');
return;
}
} }
beforeEach(to, from) beforeEach(to, from)
next(); next();
@ -101,14 +114,17 @@ router.onError((error) => {
//入侵追加自定义方法、对象 //入侵追加自定义方法、对象
router.sc_getMenu = () => { router.sc_getMenu = () => {
// var apiMenu = tool.data.get("MENU") || [] if(tool.data.get('BASE_INFO').base.base_menucate=='dynamic'){
return tool.data.get("MENU") || []
}
else{
let permissions = tool.data.get("PERMISSIONS") || []; let permissions = tool.data.get("PERMISSIONS") || [];
let userMenu = userRoutes; let userMenu = treeFilter(userRoutes, node => {
userMenu = treeFilter(userRoutes, node => {
return node.meta.perms ? node.meta.perms.filter(item => permissions.indexOf(item) > -1).length > 0 : true return node.meta.perms ? node.meta.perms.filter(item => permissions.indexOf(item) > -1).length > 0 : true
}); });
let menus = checkRoute(userMenu, permissions) userMenu = checkRoute(userMenu, permissions)
return menus return userMenu
}
} }
//转换 //转换
@ -124,8 +140,8 @@ function filterAsyncRouter(routerMap) {
//MAP转路由对象 //MAP转路由对象
var route = { var route = {
path: item.path, path: item.path,
name: item.name, name: item.name?item.name:'',
meta: item.meta, meta: item.meta?item.meta:{},
redirect: item.redirect, redirect: item.redirect,
children: item.children ? filterAsyncRouter(item.children) : null, children: item.children ? filterAsyncRouter(item.children) : null,
component: loadComponent(item.component) component: loadComponent(item.component)

View File

@ -118,9 +118,20 @@ export default {
if (base_dashboard == null || base_dashboard == undefined || base_dashboard == '') { if (base_dashboard == null || base_dashboard == undefined || base_dashboard == '') {
base_dashboard = '/dashboard' base_dashboard = '/dashboard'
} }
this.$router.replace({ if(this.$TOOL.data.get('BASE_INFO').base.base_menucate=='dynamic'){
try{
var res = await that.$API.system.user.routers.req({})
this.$TOOL.data.set("MENU",res)
console.log(res)
} catch (err) {
}
}
that.$router.replace({
path: base_dashboard, path: base_dashboard,
}); });
} catch (err) { } catch (err) {
that.islogin = false; that.islogin = false;
} }

View File

@ -20,8 +20,19 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="路由名" prop="route_name" width="100"></el-table-column> <el-table-column label="路由名" prop="route_name" width="100"></el-table-column>
<el-table-column label="图标" prop="icon" width="80"></el-table-column> <el-table-column label="图标" prop="icon" width="150"></el-table-column>
<el-table-column label="组件" prop="component" width="150" :show-overflow-tooltip="true"></el-table-column> <el-table-column label="路由地址" prop="path" width="200" :show-overflow-tooltip="true"></el-table-column>
<el-table-column label="组件" prop="component" width="200" :show-overflow-tooltip="true"></el-table-column>
<el-table-column label="是否隐藏" width="80">
<template #default="scope">
<span v-show="scope.row.is_hidden"></span>
</template>
</el-table-column>
<el-table-column label="是否全屏" width="80">
<template #default="scope">
<span v-show="scope.row.is_fullpage"></span>
</template>
</el-table-column>
<el-table-column label="权限标识" prop="codes" min-width="100" :show-overflow-tooltip="true"> <el-table-column label="权限标识" prop="codes" min-width="100" :show-overflow-tooltip="true">
<template #default="scope"> <template #default="scope">
<el-tag v-for="i in scope.row.codes" v-bind:key="i">{{ i }}</el-tag> <el-tag v-for="i in scope.row.codes" v-bind:key="i">{{ i }}</el-tag>
@ -67,7 +78,7 @@
<el-form-item label="组件地址" prop="component"> <el-form-item label="组件地址" prop="component">
<el-input v-model="addForm.component" clearable></el-input> <el-input v-model="addForm.component" clearable></el-input>
</el-form-item> </el-form-item>
</span>
<el-form-item label="是否隐藏" prop="is_hidden"> <el-form-item label="是否隐藏" prop="is_hidden">
<el-switch v-model="addForm.is_hidden"></el-switch> <el-switch v-model="addForm.is_hidden"></el-switch>
</el-form-item> </el-form-item>
@ -75,6 +86,7 @@
<el-switch v-model="addForm.is_fullpage"></el-switch> <el-switch v-model="addForm.is_fullpage"></el-switch>
</el-form-item> </el-form-item>
</span> </span>
</span>
<el-form-item label="权限标识"> <el-form-item label="权限标识">
<el-select v-model="addForm.codes" multiple filterable allow-create default-first-option <el-select v-model="addForm.codes" multiple filterable allow-create default-first-option
:reserve-keyword="false" placeholder="权限标识(回车添加多个)" style="width: 100%"> :reserve-keyword="false" placeholder="权限标识(回车添加多个)" style="width: 100%">
@ -179,13 +191,13 @@ export default {
}, },
// //
delMenu(id) { delMenu(row) {
this.$confirm(`确定删除吗?`, "提示", { this.$confirm(`确定删除吗?`, "提示", {
type: "warning", type: "warning",
confirmButtonText: "删除", confirmButtonText: "删除",
confirmButtonClass: "el-button--danger", confirmButtonClass: "el-button--danger",
}).then(() => { }).then(() => {
this.$API.system.permission.delete.req(id).then((res) => { this.$API.system.permission.delete.req(row.id).then((res) => {
this.$refs.table.refresh(); this.$refs.table.refresh();
}); });
}); });

View File

@ -60,6 +60,7 @@
> >
<el-popconfirm <el-popconfirm
title="确定删除吗?" title="确定删除吗?"
v-if="!scope.row.children"
@confirm="delDept(scope.row, scope.$index)" @confirm="delDept(scope.row, scope.$index)"
> >
<template #reference> <template #reference>
@ -68,7 +69,6 @@
type="danger" type="danger"
size="small" size="small"
v-auth="'dept.delete'" v-auth="'dept.delete'"
v-if="!scope.row.children"
>删除</el-button >删除</el-button
> >
</template> </template>

View File

@ -24,7 +24,7 @@
</el-tree> </el-tree>
</el-main> </el-main>
<el-footer style="height:51px;"> <el-footer style="height:51px;">
<el-button type="primary" size="mini" icon="el-icon-plus" style="width: 100%;" @click="addDicType" v-auth="'dict.create'">字典分类</el-button> <el-button type="primary" size="small" icon="el-icon-plus" style="width: 100%;" @click="addDicType" v-auth="'dict.create'">字典分类</el-button>
</el-footer> </el-footer>
</el-container> </el-container>
</el-aside> </el-aside>
@ -36,7 +36,7 @@
</div> </div>
</el-header> </el-header>
<el-main class="nopadding"> <el-main class="nopadding">
<scTable ref="table" :apiObj="listApi" row-key="id" :params="listApiParams" @selection-change="selectionChange" stripe :paginationLayout="'prev, pager, next'"> <scTable ref="table" :apiObj="listApi" row-key="id" :params="listApiParams" stripe :paginationLayout="'prev, pager, next'">
<!-- <el-table-column type="selection" width="50"></el-table-column> --> <!-- <el-table-column type="selection" width="50"></el-table-column> -->
<el-table-column label="序号" type="index" width="50"></el-table-column> <el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="名称" prop="name" width="360"></el-table-column> <el-table-column label="名称" prop="name" width="360"></el-table-column>

View File

@ -16,22 +16,22 @@
</ul> </ul>
<div class="bottom"> <div class="bottom">
<div class="state"> <div class="state">
<el-tag v-if="item.enabled" size="mini">启用</el-tag> <el-tag v-if="item.enabled" size="small">启用</el-tag>
<el-tag v-if="!item.enabled" size="mini" type="danger">停用</el-tag> <el-tag v-if="!item.enabled" size="small" type="danger">停用</el-tag>
</div> </div>
<div class="handler"> <div class="handler">
<el-popconfirm title="确定立即执行吗?" @confirm="run(item)"> <el-popconfirm title="确定立即执行吗?" @confirm="run(item)">
<template #reference> <template #reference>
<el-button type="primary" icon="el-icon-caret-right" size="mini" circle></el-button> <el-button type="primary" icon="el-icon-caret-right" size="small" circle></el-button>
</template> </template>
</el-popconfirm> </el-popconfirm>
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<el-button type="primary" icon="el-icon-more" size="mini" circle plain></el-button> <el-button type="primary" icon="el-icon-more" size="small" circle plain></el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="editTask(item)" v-auth="'ptask.update'">编辑</el-dropdown-item> <!-- <el-dropdown-item @click="editTask(item)" v-auth="'ptask.update'">编辑</el-dropdown-item> -->
<el-dropdown-item @click="logs(item)">日志</el-dropdown-item> <el-dropdown-item @click="logs(item)">日志</el-dropdown-item>
<el-dropdown-item @click="delTask(item)" divided v-auth="'ptask.delete'">删除</el-dropdown-item> <!-- <el-dropdown-item @click="delTask(item)" divided v-auth="'ptask.delete'">删除</el-dropdown-item> -->
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
@ -40,7 +40,7 @@
</el-card> </el-card>
</el-col> </el-col>
<el-col :xl="6" :lg="6" :md="8" :sm="12" :xs="24"> <el-col :xl="6" :lg="6" :md="8" :sm="12" :xs="24">
<el-card class="task task-add" shadow="none" @click="addTask" v-auth="'ptask.create'"> <el-card class="task task-add" @click="addTask" v-auth="'ptask.create'">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>添加计划任务</p> <p>添加计划任务</p>
</el-card> </el-card>
@ -77,8 +77,8 @@
</template> </template>
</el-dialog> </el-dialog>
<el-drawer title="计划任务日志" v-model="logsVisible" :size="600" direction="rtl" destroy-on-close> <el-drawer title="计划任务日志" v-model="logsVisible" :size="800" direction="rtl" destroy-on-close>
<logs></logs> <logs :ptask="ptask"></logs>
</el-drawer> </el-drawer>
</template> </template>
@ -118,6 +118,7 @@
visible: false, visible: false,
isSaving: false, isSaving: false,
logsVisible: false, logsVisible: false,
ptask: ""
} }
}, },
mounted() { mounted() {
@ -180,7 +181,8 @@
// //
}) })
}, },
logs(){ logs(item){
this.ptask = item;
this.logsVisible = true this.logsVisible = true
}, },
run(task){ run(task){

View File

@ -1,96 +1,30 @@
<template> <template>
<el-container> <el-container>
<el-main style="padding:0 20px;"> <el-main class="nopadding">
<scTable ref="table" :data="data" stripe> <scTable ref="table" :apiObj="apiObj" :params="params">
<el-table-column label="执行时间" prop="time" width="200"></el-table-column> <el-table-column label="任务ID" prop="task_id" width="300"></el-table-column>
<el-table-column label="执行结果" prop="state" width="100"> <el-table-column label="执行时间" prop="date_created" width="160"></el-table-column>
<template #default="scope"> <el-table-column label="执行状态" prop="status">
<span v-if="scope.row.state==200" style="color: #67C23A;"><i class="el-icon-success"></i> 成功</span>
<span v-else style="color: #F56C6C;"><i class="el-icon-error"></i> 异常</span>
</template>
</el-table-column>
<el-table-column label="执行日志" prop="logs" width="100" fixed="right">
<template #default="scope">
<el-button size="mini" @click="show(scope.row)" link>日志</el-button>
</template>
</el-table-column> </el-table-column>
</scTable> </scTable>
</el-main> </el-main>
</el-container> </el-container>
<el-drawer title="日志" v-model="logsVisible" :size="500" direction="rtl" destroy-on-close>
<el-main style="padding:0 20px 20px 20px;">
<pre style="font-size: 12px;color: #999;padding:20px;background: #333;font-family: consolas;line-height: 1.5;overflow: auto;">{{demoLog}}</pre>
</el-main>
</el-drawer>
</template> </template>
<script> <script>
export default { export default {
props: {
ptask: {type: Object, default: () => {}}
},
data() { data() {
return { return {
logsVisible: false, apiObj: this.$API.system.task.result,
demoLog: `2021-07-07 12:35:00 [com.xxl.job.core.thread.JobThread#run]-[124]-[Thread-308] params: {task_name: this.ptask.task, periodic_task_name: this.ptask.name},
----------- xxl-job job execute start -----------
----------- Param:
2021-07-07 12:35:00 [com.heronshn.reservation.jobhandler.AqshMasterDataSendHandler#execute]-[31]-[Thread-308] aqshMasterDataSendHandler start
2021-07-07 12:35:00 [com.heronshn.reservation.data.service.impl.AqshVehicleServiceImpl#send]-[42]-[Thread-308] send 45
2021-07-07 12:35:00 [com.heronshn.reservation.data.service.impl.AqshVehicleServiceImpl#send]-[45]-[Thread-308] webapi http://127.0.0.1:48080
2021-07-07 12:35:00 [com.heronshn.reservation.jobhandler.AqshMasterDataSendHandler#execute]-[33]-[Thread-308] aqshMasterDataSendHandler vehicle end
2021-07-07 12:35:00 [com.heronshn.reservation.jobhandler.AqshMasterDataSendHandler#execute]-[35]-[Thread-308] aqshMasterDataSendHandler stop
2021-07-07 12:35:00 [com.xxl.job.core.thread.JobThread#run]-[158]-[Thread-308]
----------- xxl-job job execute end(finish) -----------
----------- ReturnT:ReturnT [code=200, msg=null, content=null]
2021-07-07 12:35:00 [com.xxl.job.core.thread.TriggerCallbackThread#callbackLog]-[176]-[Thread-10]
----------- xxl-job job callback finish.
[Load Log Finish]`,
data: [
{
time: "2021-07-07 00:00:00",
state: "500",
logs: ""
},
{
time: "2021-07-06 00:00:00",
state: "200",
logs: ""
},
{
time: "2021-07-05 00:00:00",
state: "200",
logs: ""
},
{
time: "2021-07-04 00:00:00",
state: "200",
logs: ""
},
{
time: "2021-07-03 00:00:00",
state: "200",
logs: ""
},
{
time: "2021-07-02 00:00:00",
state: "200",
logs: ""
},
{
time: "2021-07-01 00:00:00",
state: "200",
logs: ""
}
]
} }
}, },
mounted() { mounted() {
}, },
methods: { methods: {
show(){
this.logsVisible = true;
}
} }
} }
</script> </script>