mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-07-05 10:08:15 +08:00
@ -9,40 +9,40 @@
|
||||
"prettier": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"ace-builds": "^1.36.0",
|
||||
"aieditor": "^1.0.14",
|
||||
"axios": "^1.7.5",
|
||||
"clipboard": "^2.0.11",
|
||||
"core-js": "^3.38.1",
|
||||
"cropperjs": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.1",
|
||||
"element-plus": "^2.8.1",
|
||||
"json-bigint": "^1.0.0",
|
||||
"json5-to-table": "^0.1.8",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-emoji": "^3.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinyin-match": "^1.2.5",
|
||||
"qrcodejs2": "^0.0.2",
|
||||
"sortablejs": "^1.15.2",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"vue": "^3.4.38",
|
||||
"vue-i18n": "^9.14.0",
|
||||
"vue-router": "^4.4.3",
|
||||
"vue3-ace-editor": "^2.2.4",
|
||||
"vue3-json-viewer": "^2.2.2",
|
||||
"vuedraggable": "^4.0.3",
|
||||
"vuex": "^4.1.0"
|
||||
"@element-plus/icons-vue": "2.3.1",
|
||||
"ace-builds": "1.36.2",
|
||||
"aieditor": "1.1.7",
|
||||
"axios": "1.7.7",
|
||||
"clipboard": "2.0.11",
|
||||
"core-js": "3.38.1",
|
||||
"cropperjs": "1.6.2",
|
||||
"crypto-js": "4.2.0",
|
||||
"echarts": "5.5.1",
|
||||
"element-plus": "2.8.5",
|
||||
"json-bigint": "1.0.0",
|
||||
"json5-to-table": "0.1.8",
|
||||
"markdown-it": "14.1.0",
|
||||
"markdown-it-emoji": "3.0.0",
|
||||
"nprogress": "0.2.0",
|
||||
"pinyin-match": "1.2.6",
|
||||
"qrcodejs2": "0.0.2",
|
||||
"sortablejs": "1.15.3",
|
||||
"vkbeautify": "0.99.3",
|
||||
"vue": "3.5.12",
|
||||
"vue-i18n": "10.0.4",
|
||||
"vue-router": "4.4.5",
|
||||
"vue3-ace-editor": "2.2.4",
|
||||
"vue3-json-viewer": "2.2.2",
|
||||
"vuedraggable": "4.0.3",
|
||||
"vuex": "4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.1.2",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-organize-attributes": "^1.0.0",
|
||||
"sass": "^1.77.8",
|
||||
"terser": "^5.31.6",
|
||||
"vite": "^5.4.2"
|
||||
"@vitejs/plugin-vue": "5.1.4",
|
||||
"prettier": "3.3.3",
|
||||
"prettier-plugin-organize-attributes": "1.0.0",
|
||||
"sass": "1.79.5",
|
||||
"terser": "5.34.1",
|
||||
"vite": "5.4.8"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
@ -5,6 +5,17 @@
|
||||
import config from '@/config'
|
||||
import http from '@/utils/request'
|
||||
export default {
|
||||
/**
|
||||
* 退出程序
|
||||
*/
|
||||
exit: {
|
||||
url: `${config.API_URL}/api/probe/exit`,
|
||||
name: `退出程序`,
|
||||
get: async function (data = {}, config = {}) {
|
||||
return await http.get(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 健康检查
|
||||
*/
|
||||
@ -26,4 +37,26 @@ export default {
|
||||
return await http.get(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 实例下线
|
||||
*/
|
||||
offline: {
|
||||
url: `${config.API_URL}/api/probe/offline`,
|
||||
name: `实例下线`,
|
||||
get: async function (data = {}, config = {}) {
|
||||
return await http.get(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 停止日志计数器
|
||||
*/
|
||||
stopLogCounter: {
|
||||
url: `${config.API_URL}/api/probe/stop.log.counter`,
|
||||
name: `停止日志计数器`,
|
||||
get: async function (data = {}, config = {}) {
|
||||
return await http.get(this.url, data, config)
|
||||
},
|
||||
},
|
||||
}
|
@ -180,4 +180,15 @@ export default {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 启用/禁用字典内容
|
||||
*/
|
||||
setEnabled: {
|
||||
url: `${config.API_URL}/api/sys/dic/set.enabled`,
|
||||
name: `启用/禁用字典内容`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
}
|
@ -5,6 +5,17 @@
|
||||
import config from '@/config'
|
||||
import http from '@/utils/request'
|
||||
export default {
|
||||
/**
|
||||
* Aes解密
|
||||
*/
|
||||
aesDecode: {
|
||||
url: `${config.API_URL}/api/sys/tools/aes.decode`,
|
||||
name: `Aes解密`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 执行SQL语句
|
||||
*/
|
||||
@ -59,15 +70,4 @@ export default {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 系统停机
|
||||
*/
|
||||
shutdown: {
|
||||
url: `${config.API_URL}/api/sys/tools/shutdown`,
|
||||
name: `系统停机`,
|
||||
get: async function (data = {}, config = {}) {
|
||||
return await http.get(this.url, data, config)
|
||||
},
|
||||
},
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
<el-table-column v-bind="$attrs">
|
||||
<template #default="{ row }">
|
||||
<p>{{ row.id }}</p>
|
||||
<p v-if="showTime" class="time">{{ row.createdTime }}</p>
|
||||
<p v-if="showTime" class="color-secondary">{{ row.createdTime }}</p>
|
||||
<slot :data="row"></slot>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -26,8 +26,4 @@ export default {
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.time {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
</style>
|
||||
<style scoped></style>
|
@ -6,13 +6,21 @@
|
||||
<el-popconfirm
|
||||
v-if="item.confirm"
|
||||
:title="this.$t(`确定 {title}?`, { title: item.title })"
|
||||
@confirm="item.click(row, vue)"
|
||||
@confirm="click(item, row, vue)"
|
||||
width="20rem">
|
||||
<template #reference>
|
||||
<el-button :icon="item.icon" :title="item.title" :type="item.type" @click.native.stop size="small"></el-button>
|
||||
<el-button
|
||||
v-loading="loading"
|
||||
:icon="item.icon"
|
||||
:title="item.title"
|
||||
:type="item.type"
|
||||
@click.native.stop
|
||||
size="small"></el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-button v-else :icon="item.icon" :title="item.title" @click="item.click(row, vue)" size="small">{{ item.title }} </el-button>
|
||||
<el-button v-else v-loading="loading" :icon="item.icon" :title="item.title" @click="click(item, row, vue)" size="small"
|
||||
>{{ item.title }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-button-group>
|
||||
</template>
|
||||
@ -32,13 +40,21 @@ export default {
|
||||
prop: { type: String },
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
created() {},
|
||||
components: {},
|
||||
computed: {},
|
||||
methods: {},
|
||||
methods: {
|
||||
async click(item, row, vue) {
|
||||
this.loading = true
|
||||
await item.click(row, vue)
|
||||
this.loading = false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<template v-for="(item, i) in options" :key="i">
|
||||
<div v-if="this.$TOOL.getNestedProperty(data, this.prop)?.toLowerCase() === item.value?.toLowerCase()">
|
||||
<div v-if="this.$TOOL.getNestedProperty(data, this.prop)?.toString().toLowerCase() === item.value?.toString().toLowerCase()">
|
||||
<sc-status-indicator
|
||||
:pulse="item.pulse"
|
||||
:style="item.type ? '' : `background: #${Math.abs(this.$TOOL.crypto.hashCode(item.value)).toString(16).substring(0, 6)}`"
|
||||
|
@ -25,7 +25,8 @@
|
||||
@filter-change="filterChange"
|
||||
@row-contextmenu="rowContextmenu"
|
||||
@sort-change="sortChange"
|
||||
ref="scTable">
|
||||
ref="scTable"
|
||||
tooltip-effect="light">
|
||||
<slot></slot>
|
||||
<template v-for="(item, index) in userColumn" :key="index">
|
||||
<el-table-column
|
||||
@ -181,12 +182,8 @@
|
||||
:command="`${menu}^|^NotAny^|^${tool.getNestedProperty(current.row, menu) ?? ''}`"
|
||||
:title="$t('非其一')"></sc-contextmenu-item>
|
||||
</sc-contextmenu-item>
|
||||
<sc-contextmenu-item
|
||||
v-if="contextOpers.includes('view')"
|
||||
:title="$t('查看')"
|
||||
command="view"
|
||||
divided
|
||||
icon="el-icon-view"></sc-contextmenu-item>
|
||||
<sc-contextmenu-item :title="$t('复制')" command="copy" divided icon="el-icon-copy-document"></sc-contextmenu-item>
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('view')" :title="$t('查看')" command="view" icon="el-icon-view"></sc-contextmenu-item>
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('edit')" :title="$t('编辑')" command="edit" icon="el-icon-edit"></sc-contextmenu-item>
|
||||
<sc-contextmenu-item v-if="contextOpers.includes('del')" :title="$t('删除')" command="del" icon="el-icon-delete"></sc-contextmenu-item>
|
||||
<sc-contextmenu-item
|
||||
@ -222,7 +219,7 @@ export default {
|
||||
props: {
|
||||
vue: { type: Object },
|
||||
contextMenus: { type: Array },
|
||||
contextOpers: { type: Array, default: ['view', 'edit', 'del'] },
|
||||
contextOpers: { type: Array, default: ['copy', 'view', 'edit', 'del'] },
|
||||
contextAdvs: { type: Array, default: [] },
|
||||
tableName: { type: String, default: '' },
|
||||
beforePost: {
|
||||
@ -352,12 +349,30 @@ export default {
|
||||
methods: {
|
||||
async contextMenuCommand(command) {
|
||||
if (typeof command === 'object') {
|
||||
return command.action()
|
||||
return command.action(this.vue, this.current.row)
|
||||
}
|
||||
if (command === 'refresh') {
|
||||
this.vue.reload()
|
||||
return
|
||||
}
|
||||
if (command === 'copy') {
|
||||
let data = this.current.row[this.current.column.property]
|
||||
|
||||
const textarea = document.createElement('textarea')
|
||||
textarea.readOnly = 'readonly'
|
||||
textarea.style.position = 'absolute'
|
||||
textarea.style.left = '-9999px'
|
||||
textarea.value = data
|
||||
document.body.appendChild(textarea)
|
||||
textarea.select()
|
||||
textarea.setSelectionRange(0, textarea.value.length)
|
||||
const result = document.execCommand('Copy')
|
||||
if (result) {
|
||||
this.$message.success(this.$t('复制成功'))
|
||||
}
|
||||
document.body.removeChild(textarea)
|
||||
return
|
||||
}
|
||||
if (command === 'view') {
|
||||
this.vue.dialog.save = { mode: 'view', row: { id: this.current.row.id } }
|
||||
return
|
||||
|
@ -5,5 +5,5 @@ export default {
|
||||
//标题
|
||||
//APP_NAME: "NetAdmin",
|
||||
//接口地址,如遇跨域需使用nginx代理
|
||||
//API_URL: "https://www.fastmock.site/mock/5039c4361c39a7e3252c5b55971f1bd3/api"
|
||||
API_URL: import.meta.env.VITE_API_URL,
|
||||
}
|
@ -77,6 +77,9 @@ export default {
|
||||
user: null,
|
||||
numbers: null,
|
||||
chars: null,
|
||||
hasPermission: function (p) {
|
||||
return this.permissions.includes('*/*/*') || this.permissions.some((a) => a === p)
|
||||
},
|
||||
}
|
||||
|
||||
app.use(JsonViewer)
|
||||
|
@ -12,7 +12,7 @@
|
||||
<el-card v-for="job in jobs" :class="`user-bar-jobs-item ${job.lastStatusCode === 'oK' ? '' : 'alert'}`" :key="job.id" shadow="hover">
|
||||
<div class="user-bar-jobs-item-body">
|
||||
<div class="jobIcon">
|
||||
{{ job.lastStatusCode.toUpperCase() }}
|
||||
{{ job.lastStatusCode?.toUpperCase() }}
|
||||
</div>
|
||||
<div class="jobMain">
|
||||
<div class="title">
|
||||
|
@ -7,7 +7,7 @@
|
||||
<img class="logo" src="@/assets/img/logo.png" />
|
||||
<div>
|
||||
<p>{{ $CONFIG.APP_NAME }}</p>
|
||||
<p class="version">{{ version }}</p>
|
||||
<p class="version color-secondary">{{ version }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<ul v-if="!ismobile" class="nav">
|
||||
@ -334,6 +334,5 @@ export default {
|
||||
.version {
|
||||
font-size: var(--el-font-size-small);
|
||||
font-weight: var(--el-font-weight-primary);
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
</style>
|
@ -480,8 +480,8 @@ export default {
|
||||
应用配置: 'Application configuration',
|
||||
导出文件: 'Export file',
|
||||
刷新: 'Refresh',
|
||||
'访问分布(Today)': 'Access distribution (Today)',
|
||||
'访问趋势(Today)': 'Access trend (Today)',
|
||||
'流量分布(Today)': 'Traffic distribution (Today)',
|
||||
'流量趋势(Today)': 'Traffic trend (Today)',
|
||||
'作业分布(Today)': 'Job distribution (Today)',
|
||||
'作业趋势(Today)': 'Job trend (Today)',
|
||||
后退一时: 'Back an hour',
|
||||
|
@ -477,8 +477,8 @@ export default {
|
||||
应用配置: '应用配置',
|
||||
导出文件: '导出文件',
|
||||
刷新: '刷新',
|
||||
'访问分布(Today)': '访问分布(Today)',
|
||||
'访问趋势(Today)': '访问趋势(Today)',
|
||||
'流量分布(Today)': '流量分布(Today)',
|
||||
'流量趋势(Today)': '流量趋势(Today)',
|
||||
'作业分布(Today)': '作业分布(Today)',
|
||||
'作业趋势(Today)': '作业趋势(Today)',
|
||||
后退一时: '后退一时',
|
||||
|
@ -532,7 +532,9 @@ textarea {
|
||||
.justify-content-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-content-right {
|
||||
justify-content: right;
|
||||
}
|
||||
.font-monospace {
|
||||
font-family: 'Lucida Console', 'Microsoft YaHei', monospace;
|
||||
}
|
||||
@ -587,4 +589,14 @@ textarea {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.color-secondary {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.color-primary {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.color-regular {
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
@ -306,4 +306,9 @@
|
||||
|
||||
.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
|
||||
--el-table-row-hover-bg-color: #fffaf0;
|
||||
}
|
||||
|
||||
.el-popper {
|
||||
max-width: 90%;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-card :header="$t('访问趋势(Today)')" shadow="never" style="height: 25rem">
|
||||
<el-card :header="$t('流量趋势(Today)')" shadow="never" style="height: 25rem">
|
||||
<chart-bar
|
||||
:api="[
|
||||
{
|
||||
@ -29,9 +29,9 @@ export default {
|
||||
return tool
|
||||
},
|
||||
},
|
||||
title: '访问趋势(Today)',
|
||||
title: '流量趋势(Today)',
|
||||
icon: 'el-icon-data-line',
|
||||
description: '访问趋势(Today)',
|
||||
description: '流量趋势(Today)',
|
||||
components: {
|
||||
ChartBar,
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-card :header="$t('访问分布(Today)')" shadow="never" style="height: 25rem">
|
||||
<el-card :header="$t('流量分布(Today)')" shadow="never" style="height: 25rem">
|
||||
<chart-pie
|
||||
:api="[
|
||||
{
|
||||
@ -29,9 +29,9 @@ export default {
|
||||
return tool
|
||||
},
|
||||
},
|
||||
title: '访问分布(Today)',
|
||||
title: '流量分布(Today)',
|
||||
icon: 'el-icon-data-line',
|
||||
description: '访问分布(Today)',
|
||||
description: '流量分布(Today)',
|
||||
components: {
|
||||
ChartPie,
|
||||
},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -19,7 +28,15 @@
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search :controls="[]" :vue="this" @reset="onReset" @search="onSearch" ref="search" />
|
||||
<na-search
|
||||
:controls="[]"
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
|
||||
@ -42,8 +59,18 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-menus="['id', 'userRegisterConfirm', 'enabled', 'createdTime']"
|
||||
:context-menus="[
|
||||
'id',
|
||||
'userRegisterConfirm',
|
||||
'userRegisterDept.name',
|
||||
'userRegisterRole.name',
|
||||
'enabled',
|
||||
'createdTime',
|
||||
'phoneReuseTimes',
|
||||
'emailReuseTimes',
|
||||
]"
|
||||
:export-api="$API.sys_config.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_config.pagedQuery"
|
||||
:vue="this"
|
||||
@ -81,8 +108,7 @@
|
||||
type: 'danger',
|
||||
})
|
||||
"
|
||||
:vue="this"
|
||||
width="150" />
|
||||
:vue="this" />
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
@ -116,6 +142,7 @@ export default {
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -136,6 +163,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_config.count.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
async setEnabled(enabled) {
|
||||
let loading
|
||||
try {
|
||||
@ -193,12 +224,12 @@ export default {
|
||||
this.$refs.selectFilter.selected['enabled'] = [true]
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
|
||||
@ -211,9 +242,10 @@ export default {
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -222,12 +254,15 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.search.form.dy.enabled = true
|
||||
this.$refs.search.keeps.push({
|
||||
field: 'enabled',
|
||||
value: true,
|
||||
type: 'dy',
|
||||
})
|
||||
this.onReset()
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['keywords'],
|
||||
watch: {},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -31,6 +40,9 @@
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
@ -57,6 +69,7 @@
|
||||
:context-menus="['id', 'name', 'sort', 'enabled', 'createdTime', 'summary']"
|
||||
:default-sort="{ prop: 'sort', order: 'descending' }"
|
||||
:export-api="$API.sys_dept.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_dept.query"
|
||||
:vue="this"
|
||||
@ -76,7 +89,7 @@
|
||||
<na-col-id :label="$t('部门编号')" prop="id" sortable="custom" width="170" />
|
||||
<el-table-column :label="$t('部门名称')" prop="name" sortable="custom" />
|
||||
<el-table-column :label="$t('排序')" align="right" prop="sort" sortable="custom" />
|
||||
<el-table-column :label="$t('备注')" prop="summary" />
|
||||
<el-table-column label="备注" prop="summary" sortable="custom" />
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
|
||||
@ -127,6 +140,7 @@ export default {
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -147,6 +161,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_dept.count.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
async setEnabled(enabled) {
|
||||
let loading
|
||||
try {
|
||||
@ -204,12 +222,12 @@ export default {
|
||||
this.$refs.selectFilter.selected['enabled'] = [true]
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
|
||||
@ -222,9 +240,10 @@ export default {
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -233,12 +252,15 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.search.form.dy.enabled = true
|
||||
this.$refs.search.keeps.push({
|
||||
field: 'enabled',
|
||||
value: true,
|
||||
type: 'dy',
|
||||
})
|
||||
this.onReset()
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['keywords'],
|
||||
watch: {},
|
||||
|
@ -1,5 +1,22 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('启用状态'),
|
||||
key: 'enabled',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
{ label: $t('启用'), value: true },
|
||||
{ label: $t('禁用'), value: false },
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -12,7 +29,11 @@
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
@ -21,12 +42,29 @@
|
||||
icon="el-icon-plus"
|
||||
type="primary"></el-button>
|
||||
<na-button-bulk-del :api="$API.sys_dic.bulkDeleteContent" :vue="this" />
|
||||
<el-dropdown v-show="this.selection.length > 0">
|
||||
<el-button type="primary">
|
||||
{{ $t('批量操作') }}
|
||||
<el-icon>
|
||||
<el-icon-arrow-down />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="setEnabled(true)">{{ $t('启用') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click="setEnabled(false)">{{ $t('禁用') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click="this.dialog.savebatch = { mode: 'batchedit', data: { catalogId: this.catalogId } }">{{
|
||||
$t('设置项值')
|
||||
}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:before-post="(data) => data.dynamicFilter.filters.length > 0"
|
||||
:context-menus="['key', 'value', 'createdTime']"
|
||||
:context-menus="['key', 'value', 'enabled', 'createdTime']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:export-api="$API.sys_dic.exportContent"
|
||||
:params="query"
|
||||
@ -44,7 +82,13 @@
|
||||
<el-table-column type="selection" width="50" />
|
||||
<el-table-column :label="$t('项名')" prop="key" sortable="custom" />
|
||||
<el-table-column :label="$t('项值')" prop="value" sortable="custom" />
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" />
|
||||
<el-table-column :label="$t('描述')" prop="summary" sortable="custom" />
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170" />
|
||||
<na-col-operation
|
||||
:buttons="
|
||||
naColOperation.buttons.concat({
|
||||
@ -67,6 +111,13 @@
|
||||
@mounted="$refs.saveDialog.open(dialog.save)"
|
||||
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
|
||||
ref="saveDialog"></save-dialog>
|
||||
|
||||
<savebatch-dialog
|
||||
v-if="dialog.savebatch"
|
||||
@closed="dialog.savebatch = null"
|
||||
@mounted="$refs.savebatchDialog.open(dialog.savebatch)"
|
||||
@success="(data, mode) => batchsuccess(data, mode)"
|
||||
ref="savebatchDialog"></savebatch-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -75,9 +126,11 @@ import table from '@/config/table'
|
||||
import naColOperation from '@/config/naColOperation'
|
||||
|
||||
const saveDialog = defineAsyncComponent(() => import('./save.vue'))
|
||||
const savebatchDialog = defineAsyncComponent(() => import('./savebatch.vue'))
|
||||
export default {
|
||||
components: {
|
||||
saveDialog,
|
||||
savebatchDialog,
|
||||
},
|
||||
computed: {
|
||||
naColOperation() {
|
||||
@ -104,6 +157,59 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async batchsuccess(data, mode) {
|
||||
if (mode === 'batchedit') {
|
||||
let loading
|
||||
try {
|
||||
await this.$confirm(`确定修改选中的 ${this.selection.length} 项吗?`, '提示', {
|
||||
type: 'warning',
|
||||
})
|
||||
loading = this.$loading()
|
||||
const res = await Promise.all(this.selection.map((x) => this.$API.sys_dic.editContent.post(Object.assign(x, { value: data }))))
|
||||
this.$message.success(
|
||||
`操作成功 ${res.map((x) => (x.code === 'succeed' ? 1 : 0)).reduce((a, b) => a + b, 0)}/${this.selection.length} 条`,
|
||||
)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
loading?.close()
|
||||
}
|
||||
},
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
})
|
||||
this.$refs.search.search()
|
||||
},
|
||||
//表格内开关事件
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
await this.$API.sys_dic.setEnabled.post(row)
|
||||
this.$message.success(`操作成功`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
async setEnabled(enabled) {
|
||||
let loading
|
||||
try {
|
||||
await this.$confirm(`确定${enabled ? '启用' : '禁用'}选中的 ${this.selection.length} 项吗?`, '提示', {
|
||||
type: 'warning',
|
||||
})
|
||||
loading = this.$loading()
|
||||
const res = await Promise.all(this.selection.map((x) => this.$API.sys_dic.setEnabled.post(Object.assign(x, { enabled: enabled }))))
|
||||
this.$message.success(`操作成功 ${res.map((x) => x.data ?? 0).reduce((a, b) => a + b, 0)}/${this.selection.length} 条`)
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
loading?.close()
|
||||
},
|
||||
onReset() {
|
||||
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
@ -138,6 +244,14 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof form.dy.enabled === 'boolean') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'enabled',
|
||||
operator: 'eq',
|
||||
value: form.dy.enabled,
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
},
|
||||
|
||||
|
@ -13,6 +13,9 @@
|
||||
<el-form-item :label="$t('项值')" prop="value">
|
||||
<el-input v-model="form.value" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('描述')" prop="summary">
|
||||
<el-input v-model="form.summary" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
|
||||
|
83
src/frontend/admin/src/views/sys/dic/list/savebatch.vue
Normal file
83
src/frontend/admin/src/views/sys/dic/list/savebatch.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="$t('批量修改')" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-tabs tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
<el-form :disabled="mode === 'view'" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
|
||||
<el-form-item :label="$t('项值')" prop="value">
|
||||
<el-input v-model="form.value" clearable></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
|
||||
<json-viewer
|
||||
:expand-depth="5"
|
||||
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
|
||||
:value="form"
|
||||
copyable
|
||||
expanded
|
||||
sort></json-viewer>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">{{ $t('取消') }}</el-button>
|
||||
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
|
||||
</template>
|
||||
</sc-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
//表单数据
|
||||
form: {},
|
||||
loading: true,
|
||||
mode: 'edit',
|
||||
//验证规则
|
||||
rules: {
|
||||
value: [{ required: true, message: '请输入项值' }],
|
||||
},
|
||||
titleMap: {
|
||||
edit: this.$t('批量编辑字典项'),
|
||||
},
|
||||
visible: false,
|
||||
}
|
||||
},
|
||||
emits: ['success', 'closed', 'mounted'],
|
||||
methods: {
|
||||
//显示
|
||||
async open(data) {
|
||||
this.visible = true
|
||||
this.loading = true
|
||||
this.mode = data.mode
|
||||
this.form.catalogId = data.data?.catalogId
|
||||
if (data.row?.id) {
|
||||
const res = await this.$API.sys_dic.getContent.post({ id: data.row.id })
|
||||
Object.assign(this.form, res.data)
|
||||
}
|
||||
this.loading = false
|
||||
return this
|
||||
},
|
||||
|
||||
//表单提交方法
|
||||
async submit() {
|
||||
const valid = await this.$refs.dialogForm.validate().catch(() => {})
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
this.loading = true
|
||||
this.$emit('success', this.form.value, this.mode)
|
||||
this.visible = false
|
||||
this.loading = false
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$emit('mounted')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@ -1,5 +1,19 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="12">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="running" group-separator title="运行"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -50,6 +64,9 @@
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
@ -97,6 +114,7 @@
|
||||
]"
|
||||
:default-sort="{ prop: 'lastExecTime', order: 'descending' }"
|
||||
:export-api="$API.sys_job.export"
|
||||
:on-command="this.getStatistics"
|
||||
:page-size="100"
|
||||
:params="query"
|
||||
:query-api="$API.sys_job.pagedQuery"
|
||||
@ -143,7 +161,7 @@
|
||||
sortable="custom"
|
||||
width="150" />
|
||||
<el-table-column :label="$t('上次执行')" align="center">
|
||||
<el-table-column :label="$t('状态')" align="center" prop="lastExecTime" sortable="custom" width="100">
|
||||
<el-table-column :label="$t('状态')" align="center" prop="lastStatusCode" sortable="custom" width="100">
|
||||
<template #default="{ row }">
|
||||
<na-indicator
|
||||
:data="row"
|
||||
@ -234,6 +252,8 @@ export default {
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
running: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -255,6 +275,17 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const runningFilter = JSON.parse(JSON.stringify(this.query))
|
||||
runningFilter.dynamicFilter.filters.push({
|
||||
field: 'status',
|
||||
operator: 'eq',
|
||||
value: 'running',
|
||||
})
|
||||
const res = await Promise.all([this.$API.sys_job.count.post(this.query), this.$API.sys_job.count.post(runningFilter)])
|
||||
this.total = res[0].data
|
||||
this.running = res[1].data
|
||||
},
|
||||
async copyJob(row) {
|
||||
let loading = this.$loading()
|
||||
try {
|
||||
@ -350,12 +381,12 @@ export default {
|
||||
this.$refs.selectFilter.selected['enabled'] = [true]
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
|
||||
@ -383,9 +414,10 @@ export default {
|
||||
})
|
||||
}
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords || this.$route.query.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords || this.$route.query.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -394,12 +426,15 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.search.form.dy.enabled = true
|
||||
this.$refs.search.keeps.push({
|
||||
field: 'enabled',
|
||||
value: true,
|
||||
type: 'dy',
|
||||
})
|
||||
this.onReset()
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['keywords'],
|
||||
watch: {},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -65,6 +74,7 @@
|
||||
:context-menus="['id', 'duration', 'httpMethod', 'requestUrl', 'httpStatusCode', 'createdTime', 'jobId', 'responseBody']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:export-api="$API.sys_job.exportRecord"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_job.pagedQueryRecord"
|
||||
:vue="this"
|
||||
@ -183,6 +193,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -201,6 +212,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_job.countRecord.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
jobClick(job) {
|
||||
this.dialog.job = { mode: 'view', row: { id: job.id } }
|
||||
},
|
||||
@ -210,7 +225,7 @@ export default {
|
||||
}
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
@ -242,6 +257,14 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof form.dy.id === 'string' && form.dy.id.trim() !== '') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'id',
|
||||
operator: 'eq',
|
||||
value: form.dy.id,
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof form.dy.jobId === 'string' && form.dy.jobId.trim() !== '') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'jobId',
|
||||
@ -266,9 +289,10 @@ export default {
|
||||
})
|
||||
}
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.jobId) {
|
||||
this.$refs.search.selectInputKey = 'jobId'
|
||||
this.$refs.search.form.dy.jobId = this.jobId
|
||||
@ -295,6 +319,7 @@ export default {
|
||||
value: this.$refs.search.form.dy.createdTime,
|
||||
type: 'dy',
|
||||
})
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['statusCodes', 'jobId'],
|
||||
watch: {},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
v-if="showFilter"
|
||||
@ -45,6 +54,7 @@
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:export-api="$API.sys_loginlog.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_loginlog.pagedQuery"
|
||||
:vue="this"
|
||||
@ -100,6 +110,7 @@ export default {
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {
|
||||
info: false,
|
||||
},
|
||||
@ -117,6 +128,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_loginlog.count.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
async dataChange(data) {
|
||||
this.apis = []
|
||||
const ips = data.data.rows?.map((x) => x.createdClientIp) ?? []
|
||||
@ -136,7 +151,7 @@ export default {
|
||||
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
@ -160,6 +175,7 @@ export default {
|
||||
)
|
||||
}
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
|
||||
async rowClick(row) {
|
||||
@ -174,7 +190,7 @@ export default {
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -183,6 +199,7 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: { keywords: { type: String }, showFilter: { type: Boolean, default: true } },
|
||||
watch: {},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -192,6 +201,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {
|
||||
info: false,
|
||||
},
|
||||
@ -252,6 +262,7 @@ export default {
|
||||
this.owners = res[0].data
|
||||
this.apis = res[1].data
|
||||
this.ips = res[2]
|
||||
this.total = data.data.total
|
||||
},
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
@ -260,7 +271,7 @@ export default {
|
||||
this.$refs.search.search()
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
@ -353,7 +364,7 @@ export default {
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -32,6 +41,9 @@
|
||||
:vue="this"
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
@ -44,6 +56,7 @@
|
||||
:context-menus="['id', 'createdUserName', 'msgType', 'title', 'summary', 'createdTime']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:export-api="$API.sys_sitemsg.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_sitemsg.pagedQuery"
|
||||
:vue="this"
|
||||
@ -119,6 +132,7 @@ export default {
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -133,6 +147,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_sitemsg.count.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
|
||||
@ -148,7 +166,7 @@ export default {
|
||||
}
|
||||
this.$refs.table.refresh()
|
||||
},
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
@ -166,9 +184,10 @@ export default {
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -177,6 +196,7 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['keywords'],
|
||||
watch: {},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -49,6 +58,9 @@
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
@ -75,6 +87,7 @@
|
||||
:context-menus="['id', 'name', 'sort', 'enabled', 'ignorePermissionControl', 'dataScope', 'displayDashboard', 'createdTime']"
|
||||
:default-sort="{ prop: 'sort', order: 'descending' }"
|
||||
:export-api="$API.sys_role.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_role.pagedQuery"
|
||||
:vue="this"
|
||||
@ -173,6 +186,7 @@ export default {
|
||||
created() {},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -193,6 +207,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_role.count.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
async copyRole(row) {
|
||||
const loading = this.$loading()
|
||||
await this.$API.sys_role.create.post(Object.assign({}, row, { id: null, name: row.name + '-copy' }))
|
||||
@ -274,12 +292,12 @@ export default {
|
||||
this.$refs.selectFilter.selected['enabled'] = [true]
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
|
||||
@ -307,9 +325,10 @@ export default {
|
||||
})
|
||||
}
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -318,12 +337,15 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.search.form.dy.enabled = true
|
||||
this.$refs.search.keeps.push({
|
||||
field: 'enabled',
|
||||
value: true,
|
||||
type: 'dy',
|
||||
})
|
||||
this.onReset()
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['keywords'],
|
||||
watch: {},
|
||||
|
@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header v-loading="total === '...'" style="height: auto; padding: 1rem 1rem 0 1rem; display: block">
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never">
|
||||
<sc-statistic :value="total" group-separator title="总数"></sc-statistic>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
@ -47,6 +56,9 @@
|
||||
:vue="this"
|
||||
@reset="onReset"
|
||||
@search="onSearch"
|
||||
dateFormat="YYYY-MM-DD HH:mm:ss"
|
||||
dateType="datetimerange"
|
||||
dateValueFormat="YYYY-MM-DD HH:mm:ss"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
@ -73,6 +85,7 @@
|
||||
:context-opers="['view', 'edit']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:export-api="$API.sys_user.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
:query-api="$API.sys_user.pagedQuery"
|
||||
:vue="this"
|
||||
@ -163,6 +176,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
total: '...',
|
||||
dialog: {},
|
||||
loading: false,
|
||||
query: {
|
||||
@ -183,6 +197,10 @@ export default {
|
||||
},
|
||||
inject: ['reload'],
|
||||
methods: {
|
||||
async getStatistics() {
|
||||
const res = await this.$API.sys_user.count.post(this.query)
|
||||
this.total = res.data
|
||||
},
|
||||
async setEnabled(enabled) {
|
||||
let loading
|
||||
try {
|
||||
@ -231,12 +249,12 @@ export default {
|
||||
this.$refs.selectFilter.selected['enabled'] = [true]
|
||||
},
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
async onSearch(form) {
|
||||
if (Array.isArray(form.dy.createdTime)) {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
|
||||
@ -249,9 +267,10 @@ export default {
|
||||
}
|
||||
|
||||
this.$refs.table.upData()
|
||||
await this.getStatistics()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
if (this.keywords) {
|
||||
this.$refs.search.form.root.keywords = this.keywords
|
||||
this.$refs.search.keeps.push({
|
||||
@ -260,12 +279,15 @@ export default {
|
||||
type: 'root',
|
||||
})
|
||||
}
|
||||
|
||||
this.$refs.search.form.dy.enabled = true
|
||||
this.$refs.search.keeps.push({
|
||||
field: 'enabled',
|
||||
value: true,
|
||||
type: 'dy',
|
||||
})
|
||||
this.onReset()
|
||||
await this.getStatistics()
|
||||
},
|
||||
props: ['keywords', 'roleId', 'deptId'],
|
||||
watch: {},
|
||||
|
Reference in New Issue
Block a user