mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-07-05 10:08:15 +08:00
@ -11,14 +11,14 @@
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@tinymce/tinymce-vue": "^5.1.1",
|
||||
"ace-builds": "^1.33.0",
|
||||
"ace-builds": "^1.33.1",
|
||||
"axios": "^1.6.8",
|
||||
"clipboard": "^2.0.11",
|
||||
"core-js": "^3.37.0",
|
||||
"cropperjs": "^1.6.1",
|
||||
"cropperjs": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.0",
|
||||
"element-plus": "^2.7.0",
|
||||
"element-plus": "^2.7.1",
|
||||
"json-bigint": "^1.0.0",
|
||||
"json5-to-table": "^0.1.8",
|
||||
"markdown-it": "^14.1.0",
|
||||
@ -29,9 +29,9 @@
|
||||
"sortablejs": "^1.15.2",
|
||||
"tinymce": "^6.8.3",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"vue": "^3.4.23",
|
||||
"vue-i18n": "^9.12.1",
|
||||
"vue-router": "^4.3.1",
|
||||
"vue": "^3.4.25",
|
||||
"vue-i18n": "^9.13.1",
|
||||
"vue-router": "^4.3.2",
|
||||
"vue3-ace-editor": "^2.2.4",
|
||||
"vue3-json-viewer": "^2.2.2",
|
||||
"vuedraggable": "^4.0.3",
|
||||
@ -44,8 +44,8 @@
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-organize-attributes": "^1.0.0",
|
||||
"sass": "^1.75.0",
|
||||
"terser": "^5.30.3",
|
||||
"vite": "^5.2.9"
|
||||
"terser": "^5.30.4",
|
||||
"vite": "^5.2.10"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
@ -82,6 +82,39 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取作业记录条形图数据
|
||||
*/
|
||||
getRecordBarChart: {
|
||||
url: `${config.API_URL}/api/sys/job/get.record.bar.chart`,
|
||||
name: `获取作业记录条形图数据`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 状态码分组作业记录饼图数据
|
||||
*/
|
||||
getRecordPieChartByHttpStatusCode: {
|
||||
url: `${config.API_URL}/api/sys/job/get.record.pie.chart.by.http.status.code`,
|
||||
name: `状态码分组作业记录饼图数据`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 名称分组作业记录饼图数据
|
||||
*/
|
||||
getRecordPieChartByName: {
|
||||
url: `${config.API_URL}/api/sys/job/get.record.pie.chart.by.name`,
|
||||
name: `名称分组作业记录饼图数据`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询计划作业
|
||||
*/
|
||||
|
@ -27,6 +27,39 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取条形图数据
|
||||
*/
|
||||
getBarChart: {
|
||||
url: `${config.API_URL}/api/sys/log/get.bar.chart`,
|
||||
name: `获取条形图数据`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 描述分组饼图数据
|
||||
*/
|
||||
getPieChartByApiSummary: {
|
||||
url: `${config.API_URL}/api/sys/log/get.pie.chart.by.api.summary`,
|
||||
name: `描述分组饼图数据`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 状态码分组饼图数据
|
||||
*/
|
||||
getPieChartByHttpStatusCode: {
|
||||
url: `${config.API_URL}/api/sys/log/get.pie.chart.by.http.status.code`,
|
||||
name: `状态码分组饼图数据`,
|
||||
post: async function (data = {}, config = {}) {
|
||||
return await http.post(this.url, data, config)
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 分页查询请求日志
|
||||
*/
|
||||
|
7
src/frontend/admin/src/assets/icons/ECharts.vue
Normal file
7
src/frontend/admin/src/assets/icons/ECharts.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<svg class="icon" height="128" p-id="5271" t="1713938893902" version="1.1" viewBox="0 0 1024 1024" width="128" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M802.752 806.58A413.836 413.836 0 1 1 924 513.904a414.072 414.072 0 0 1-121.248 292.676z m-300.868-278.768a13.408 13.408 0 0 1-2.8-1.748l-0.236-0.212a8.652 8.652 0 0 1-0.72-0.764 12.5 12.5 0 0 1-1.432-1.6 4.736 4.736 0 0 1-0.328-0.4c-0.172-0.264-0.264-0.552-0.42-0.828a12.224 12.224 0 0 1-0.864-1.892c-0.092-0.24-0.212-0.476-0.316-0.684a3.248 3.248 0 0 1-0.104-0.672 3.44 3.44 0 0 1-0.252-0.776 11.492 11.492 0 0 1-0.076-1.484c-0.028-0.304 1.672-0.4 1.672-0.716V148c-197.6 7.104-355.944 169.648-355.972 367.796a367.156 367.156 0 0 0 696.02 164.244z m34.164-379.844v300l216-212.132a334.984 334.984 0 0 0-216-87.868z m247.4 116.076L552 498.672 850 636a353.712 353.712 0 0 0-66.552-371.956zM716 488h100v28h-100v-28z m0-56h100v28h-100v-28z m-52-180h-100v-28h100v28z m-56 56h-44v-28h44v28z m-304 396h164v28H304v-28z m0-56h164v28H304v-28z m0-56h164v28H304v-28z"
|
||||
p-id="5272"></path>
|
||||
</svg>
|
||||
</template>
|
@ -66,4 +66,5 @@ export { default as Exception } from './Exception.vue'
|
||||
export { default as Collect } from './Collect.vue'
|
||||
export { default as FreeSql } from './FreeSql.vue'
|
||||
export { default as Performance } from './Performance.vue'
|
||||
export { default as Proxy } from './Proxy.vue'
|
||||
export { default as Proxy } from './Proxy.vue'
|
||||
export { default as ECharts } from './ECharts.vue'
|
@ -81,7 +81,7 @@ import tool from '@/utils/tool'
|
||||
import vkbeautify from 'vkbeautify/index'
|
||||
|
||||
export default {
|
||||
emits: ['search'],
|
||||
emits: ['search', 'reset'],
|
||||
props: {
|
||||
hasDate: { type: Boolean, default: true },
|
||||
dateType: { type: String, default: 'daterange' },
|
||||
@ -252,10 +252,10 @@ export default {
|
||||
extend: {
|
||||
remote: true,
|
||||
request: async (query) => {
|
||||
var data = {
|
||||
const data = {
|
||||
keyword: query,
|
||||
}
|
||||
var list = await this.$API.system.dic.get.get(data)
|
||||
const list = await this.$API.system.dic.get.get(data)
|
||||
return list.data.map((item) => {
|
||||
return {
|
||||
label: item.label,
|
||||
@ -322,6 +322,7 @@ export default {
|
||||
],
|
||||
casLoaded: false,
|
||||
keepKeywords: null,
|
||||
keepCreatedTime: null,
|
||||
form: {
|
||||
root: {},
|
||||
filter: {},
|
||||
@ -400,6 +401,10 @@ export default {
|
||||
if (this.keepKeywords) {
|
||||
this.form.root.keywords = this.keepKeywords
|
||||
}
|
||||
if (this.keepCreatedTime) {
|
||||
this.form.dy.createdTime = this.keepCreatedTime
|
||||
}
|
||||
this.$emit('reset')
|
||||
this.search()
|
||||
},
|
||||
},
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div v-if="data.length <= 0" class="sc-select-filter__no-data">暂无数据</div>
|
||||
<div v-for="item in data" :key="item.key" class="sc-select-filter__item">
|
||||
<div :style="{ width: labelWidth + 'rem' }" class="sc-select-filter__item-title">
|
||||
<label>{{ item.title }}:</label>
|
||||
<label>{{ item.title }}</label>
|
||||
</div>
|
||||
<div class="sc-select-filter__item-options">
|
||||
<ul>
|
||||
@ -134,6 +134,7 @@ export default {
|
||||
|
||||
.sc-select-filter__item {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.sc-select-filter__item-title {
|
||||
|
@ -111,9 +111,8 @@
|
||||
</div>
|
||||
<sc-contextmenu @command="contextMenuCommand" @visible-change="contextMenuVisibleChange" ref="contextmenu">
|
||||
<sc-contextmenu-item
|
||||
v-for="(menu, index) in contextMenus"
|
||||
v-for="(menu, index) in contextMenus.filter((x) => x === current.column.property)"
|
||||
:command="menu"
|
||||
:disabled="menu !== current.column.property"
|
||||
:key="index"
|
||||
:title="`${menu}`">
|
||||
<sc-contextmenu-item :command="`${menu}^|^Equal^|^${current.row[menu]}`" title="="></sc-contextmenu-item>
|
||||
|
File diff suppressed because one or more lines are too long
@ -60,9 +60,17 @@ const DEFAULT_CONFIG = {
|
||||
//控制台首页默认布局
|
||||
DEFAULT_GRID: {
|
||||
//默认分栏数量和宽度 例如 [24] [18,6] [8,8,8] [6,12,6]
|
||||
layout: [24, 12, 12],
|
||||
layout: [8, 8, 8, 12, 12, 12, 12],
|
||||
//小组件分布,com取值:views/home/components 文件名
|
||||
compsList: [['ver'], ['modules'], ['change-log']],
|
||||
compsList: [
|
||||
['chart-bar-request'],
|
||||
['ver'],
|
||||
['chart-bar-jobrecord'],
|
||||
['chart-pie-request'],
|
||||
['chart-pie-jobrecord'],
|
||||
['modules'],
|
||||
['change-log'],
|
||||
],
|
||||
},
|
||||
|
||||
//默认头像
|
||||
|
@ -40,6 +40,7 @@ import scUpload from '@/components/scUpload'
|
||||
import scUploadFile from '@/components/scUpload/file'
|
||||
import scUploadMultiple from '@/components/scUpload/multiple'
|
||||
import scWaterMark from '@/components/scWaterMark'
|
||||
import scSelectFilter from '@/components/scSelectFilter'
|
||||
|
||||
// net-admin组件
|
||||
import naArea from '@/components/naArea/index.vue'
|
||||
@ -113,6 +114,7 @@ export default {
|
||||
app.component('scUploadFile', scUploadFile)
|
||||
app.component('scUploadMultiple', scUploadMultiple)
|
||||
app.component('scWaterMark', scWaterMark)
|
||||
app.component('scSelectFilter', scSelectFilter)
|
||||
|
||||
//注册全局指令
|
||||
app.directive('auth', auth)
|
||||
|
@ -1,10 +1,6 @@
|
||||
<template>
|
||||
<el-card header="changelog" shadow="never">
|
||||
<el-skeleton :loading="loading" :rows="10" animated>
|
||||
<template #default>
|
||||
<div v-html="changeLog" class="change-log"></div>
|
||||
</template>
|
||||
</el-skeleton>
|
||||
<el-card v-loading="loading" header="更新日志" shadow="never">
|
||||
<div v-html="changeLog" class="change-log"></div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
@ -39,6 +35,7 @@ export default {
|
||||
<style scoped></style>
|
||||
<style lang="scss">
|
||||
.change-log {
|
||||
min-height: 30rem;
|
||||
line-height: 3rem;
|
||||
li {
|
||||
margin: 0 0 0 2rem;
|
||||
|
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<el-card :header="$t('作业趋势')" shadow="never" style="height: 25rem">
|
||||
<chart-bar
|
||||
:api="[
|
||||
{
|
||||
file: 'sys_job',
|
||||
name: 'getRecordBarChart',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
},
|
||||
{
|
||||
file: 'sys_job',
|
||||
name: 'getRecordBarChart',
|
||||
value: [
|
||||
tool.dateFormat(new Date().setDate(new Date().getDate() - 1), 'yyyy-MM-dd'),
|
||||
tool.dateFormat(new Date().setDate(new Date().getDate() - 1), 'yyyy-MM-dd'),
|
||||
],
|
||||
},
|
||||
]"></chart-bar>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChartBar from '@/views/home/widgets/components/components/chart-bar.vue'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
tool() {
|
||||
return tool
|
||||
},
|
||||
},
|
||||
title: '作业趋势',
|
||||
icon: 'el-icon-data-line',
|
||||
description: '作业趋势',
|
||||
components: {
|
||||
ChartBar,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
async created() {},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<el-card :header="$t('访问趋势')" shadow="never" style="height: 25rem">
|
||||
<chart-bar
|
||||
:api="[
|
||||
{
|
||||
file: 'sys_log',
|
||||
name: 'getBarChart',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
},
|
||||
{
|
||||
file: 'sys_log',
|
||||
name: 'getBarChart',
|
||||
value: [
|
||||
tool.dateFormat(new Date().setDate(new Date().getDate() - 1), 'yyyy-MM-dd'),
|
||||
tool.dateFormat(new Date().setDate(new Date().getDate() - 1), 'yyyy-MM-dd'),
|
||||
],
|
||||
},
|
||||
]"></chart-bar>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChartBar from '@/views/home/widgets/components/components/chart-bar.vue'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
tool() {
|
||||
return tool
|
||||
},
|
||||
},
|
||||
title: '访问趋势',
|
||||
icon: 'el-icon-data-line',
|
||||
description: '访问趋势',
|
||||
components: {
|
||||
ChartBar,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
async created() {},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<el-card :header="$t('作业分布')" shadow="never" style="height: 25rem">
|
||||
<chart-pie
|
||||
:api="[
|
||||
{
|
||||
file: 'sys_job',
|
||||
name: 'getRecordPieChartByName',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
radius: ['70%', '100%'],
|
||||
},
|
||||
{
|
||||
file: 'sys_job',
|
||||
name: 'getRecordPieChartByHttpStatusCode',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
radius: [0, '30%'],
|
||||
},
|
||||
]"></chart-pie>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChartPie from '@/views/home/widgets/components/components/chart-pie.vue'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
tool() {
|
||||
return tool
|
||||
},
|
||||
},
|
||||
title: '作业分布',
|
||||
icon: 'el-icon-data-line',
|
||||
description: '作业分布',
|
||||
components: {
|
||||
ChartPie,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
async created() {},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<el-card :header="$t('访问分布')" shadow="never" style="height: 25rem">
|
||||
<chart-pie
|
||||
:api="[
|
||||
{
|
||||
file: 'sys_log',
|
||||
name: 'getPieChartByApiSummary',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
radius: ['70%', '100%'],
|
||||
},
|
||||
{
|
||||
file: 'sys_log',
|
||||
name: 'getPieChartByHttpStatusCode',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
radius: [0, '30%'],
|
||||
},
|
||||
]"></chart-pie>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChartPie from '@/views/home/widgets/components/components/chart-pie.vue'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
tool() {
|
||||
return tool
|
||||
},
|
||||
},
|
||||
title: '访问分布',
|
||||
icon: 'el-icon-data-line',
|
||||
description: '访问分布',
|
||||
components: {
|
||||
ChartPie,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
async created() {},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<scEcharts :option="option" height="20rem"></scEcharts>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import scEcharts from '@/components/scEcharts'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
scEcharts,
|
||||
},
|
||||
props: ['api'],
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
option: {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: [],
|
||||
},
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
const res = await Promise.all(
|
||||
this.api.map((x) => {
|
||||
return this.$API[x.file][x.name].post({
|
||||
dynamicFilter: {
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: x.value,
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
this.loading = false
|
||||
this.option.xAxis.data = res[0].data.map((x) => {
|
||||
return x.timestamp
|
||||
})
|
||||
this.option.series = res.map((x) => {
|
||||
return { type: 'line', data: x.data.map((y) => y.value), symbol: 'none', areaStyle: {} }
|
||||
})
|
||||
},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<scEcharts :option="option" height="20rem"></scEcharts>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import scEcharts from '@/components/scEcharts'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
scEcharts,
|
||||
},
|
||||
props: ['api'],
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
option: {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}<br />{c}({d}%)',
|
||||
},
|
||||
series: [],
|
||||
},
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
const res = await Promise.all(
|
||||
this.api.map((x) => {
|
||||
return this.$API[x.file][x.name].post({
|
||||
dynamicFilter: {
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: x.value,
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
this.loading = false
|
||||
let i = 0
|
||||
this.option.series = res.map((x) => {
|
||||
return {
|
||||
label: {
|
||||
show: true,
|
||||
alignTo: 'labelLine',
|
||||
formatter: '{b} {d}%',
|
||||
textStyle: {
|
||||
textBorderColor: 'transparent',
|
||||
},
|
||||
},
|
||||
radius: this.api[i++].radius,
|
||||
type: 'pie',
|
||||
data: x.data.map((y) => {
|
||||
return { name: y.key, value: y.value }
|
||||
}),
|
||||
}
|
||||
})
|
||||
},
|
||||
mounted() {},
|
||||
}
|
||||
</script>
|
@ -1,96 +0,0 @@
|
||||
<template>
|
||||
<el-card v-loading="loading" :header="$t('实时收入')" shadow="hover">
|
||||
<scEcharts :option="option" height="300px" ref="c1"></scEcharts>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import scEcharts from '@/components/scEcharts'
|
||||
|
||||
export default {
|
||||
title: '实时收入',
|
||||
icon: 'el-icon-data-line',
|
||||
description: 'Echarts组件演示',
|
||||
components: {
|
||||
scEcharts,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
option: {},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const _this = this
|
||||
setTimeout(function () {
|
||||
_this.loading = false
|
||||
}, 500)
|
||||
|
||||
this.option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
xAxis: {
|
||||
boundaryGap: false,
|
||||
type: 'category',
|
||||
data: (function () {
|
||||
let now = new Date()
|
||||
const res = []
|
||||
let len = 30
|
||||
while (len--) {
|
||||
res.unshift(now.toLocaleTimeString().replace(/^\D*/, ''))
|
||||
now = new Date(now - 2000)
|
||||
}
|
||||
return res
|
||||
})(),
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '价格',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '收入',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#409EFF',
|
||||
},
|
||||
areaStyle: {
|
||||
opacity: 0.1,
|
||||
color: '#79bbff',
|
||||
},
|
||||
data: (function () {
|
||||
const res = []
|
||||
let len = 30
|
||||
while (len--) {
|
||||
res.push(Math.round(0))
|
||||
}
|
||||
return res
|
||||
})(),
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const _this = this
|
||||
setInterval(function () {
|
||||
const o = _this.option
|
||||
|
||||
o.series[0].data.shift()
|
||||
o.series[0].data.push(Math.round(Math.random() * 100))
|
||||
|
||||
o.xAxis.data.shift()
|
||||
o.xAxis.data.push(new Date().toLocaleTimeString().replace(/^\D*/, ''))
|
||||
|
||||
//_this.$refs.c1.myChart.setOption(o)
|
||||
}, 2100)
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,33 +1,19 @@
|
||||
<template>
|
||||
<el-card header="dependencies" shadow="never">
|
||||
<el-skeleton :loading="loading" :rows="5" animated>
|
||||
<template #default>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item v-for="(value, key) in packageJson.dependencies" :key="key" :label="key">{{ value }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
<el-card header="devDependencies" shadow="never">
|
||||
<el-skeleton :loading="loading" :rows="5" animated>
|
||||
<template #default>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item v-for="(value, key) in packageJson.devDependencies" :key="key" :label="key">{{
|
||||
value
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
<el-card header="assemblies" shadow="never">
|
||||
<el-skeleton :loading="loading" :rows="5" animated>
|
||||
<template #default>
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item v-for="(value, key) in modules" :key="key" :label="value.name">{{ value.version }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
<div v-loading="loading">
|
||||
<el-card header="开发依赖" shadow="never">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item v-for="(value, key) in packageJson.devDependencies" :key="key" :label="key">{{ value }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
<el-card header="运行依赖" shadow="never">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item v-for="(value, key) in packageJson.dependencies" :key="key" :label="key">{{ value }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" border style="margin-top: 1rem">
|
||||
<el-descriptions-item v-for="(value, key) in modules" :key="key" :label="value.name">{{ value.version }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<el-card :header="$t('时钟')" class="item-background" shadow="hover">
|
||||
<div class="time">
|
||||
<h2>{{ time }}</h2>
|
||||
<p>{{ day }}</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
title: '时钟',
|
||||
icon: 'el-icon-clock',
|
||||
description: '演示部件效果',
|
||||
data() {
|
||||
return {
|
||||
time: '',
|
||||
day: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.showTime()
|
||||
setInterval(() => {
|
||||
this.showTime()
|
||||
}, 1000)
|
||||
},
|
||||
methods: {
|
||||
showTime() {
|
||||
this.time = this.$TOOL.dateFormat(new Date(), 'hh:mm:ss')
|
||||
this.day = this.$TOOL.dateFormat(new Date(), 'yyyy年MM月dd日')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.item-background {
|
||||
background: linear-gradient(to right, rgb(66, 76, 80), #ccc);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.time h2 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.time p {
|
||||
font-size: 1.1rem;
|
||||
margin-top: 1rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
@ -1,14 +1,10 @@
|
||||
<template>
|
||||
<el-card :class="loading ? '' : 'aboutTop'" shadow="never">
|
||||
<el-skeleton :loading="loading" :rows="5" animated>
|
||||
<template #default>
|
||||
<div class="aboutTop-info">
|
||||
<img alt="" src="@/assets/img/logo.png" />
|
||||
<h2>{{ packageJson.name }}</h2>
|
||||
<p>{{ ver }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-skeleton>
|
||||
<el-card v-loading="loading" class="main" shadow="never">
|
||||
<div class="wrap">
|
||||
<img alt="" src="@/assets/img/logo.png" />
|
||||
<h2>{{ packageJson.name }}</h2>
|
||||
<p>{{ ver }}</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
@ -40,22 +36,18 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.aboutTop {
|
||||
border: 0;
|
||||
background: linear-gradient(to right, rgb(66, 76, 80), #ccc);
|
||||
color: #fff;
|
||||
}
|
||||
.aboutTop-info {
|
||||
.main,
|
||||
.wrap {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.aboutTop-info img {
|
||||
width: 10rem;
|
||||
.main {
|
||||
height: 25rem;
|
||||
}
|
||||
.aboutTop-info h2 {
|
||||
font-size: 2rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.aboutTop-info p {
|
||||
margin-top: 1rem;
|
||||
.wrap {
|
||||
gap: 1rem;
|
||||
}
|
||||
</style>
|
@ -1,5 +1,23 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('作业状态'),
|
||||
key: 'status',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
...Object.entries(this.$GLOBAL.enums.jobStatues).map((x) => {
|
||||
return { value: x[0], label: x[1][1] }
|
||||
}),
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -10,15 +28,6 @@
|
||||
placeholder: $t('作业编号 / 作业名称'),
|
||||
style: 'width:20rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'status'],
|
||||
options: Object.entries(this.$GLOBAL.enums.jobStatues).map((x) => {
|
||||
return { value: x[0], label: x[1][1] }
|
||||
}),
|
||||
placeholder: $t('作业状态'),
|
||||
style: 'width:10rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'httpMethod'],
|
||||
@ -40,6 +49,7 @@
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
@ -151,9 +161,11 @@
|
||||
import saveDialog from './save'
|
||||
import table from '@/config/table'
|
||||
import naColOperation from '@/config/naColOperation'
|
||||
import ScSelectFilter from '@/components/scSelectFilter/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ScSelectFilter,
|
||||
saveDialog,
|
||||
},
|
||||
inject: ['reload'],
|
||||
@ -192,6 +204,12 @@ export default {
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value
|
||||
})
|
||||
this.$refs.search.search()
|
||||
},
|
||||
//表格内开关事件
|
||||
async changeSwitch(event, row) {
|
||||
try {
|
||||
|
@ -1,73 +1,69 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="[
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'httpStatusCode'],
|
||||
options: [
|
||||
{ label: '成功', value: '200,299' },
|
||||
{ label: '失败', value: '300,999' },
|
||||
],
|
||||
placeholder: '登录结果',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'extraData'],
|
||||
placeholder: '登录名',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'createdClientIp'],
|
||||
placeholder: '客户端IP',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel"></div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<el-container>
|
||||
<el-header class="headerPublic">
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="[
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'httpStatusCode'],
|
||||
options: [
|
||||
{ label: '成功', value: '200,299' },
|
||||
{ label: '失败', value: '300,999' },
|
||||
],
|
||||
placeholder: '登录结果',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'extraData'],
|
||||
placeholder: '登录名',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'createdClientIp'],
|
||||
placeholder: '客户端IP',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel"></div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:apiObj="$API.sys_log.pagedQuery"
|
||||
:context-menus="['id', 'httpStatusCode', 'extraData', 'createdClientIp', 'os', 'createdUserAgent', 'createdTime']"
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:params="query"
|
||||
:vue="this"
|
||||
@row-click="rowClick"
|
||||
ref="table"
|
||||
remoteFilter
|
||||
remoteSort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column :label="$t('日志编号')" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('结果')" align="center" prop="httpStatusCode" sortable="custom" width="80">
|
||||
<template #default="scope">
|
||||
<sc-status-indicator :type="scope.row.httpStatusCode === 200 ? 'success' : 'danger'" />
|
||||
{{ scope.row.httpStatusCode === 200 ? '成功' : '失败' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('登录名')" prop="extraData" sortable="custom" width="200"></el-table-column>
|
||||
<el-table-column :label="$t('客户端IP')" prop="createdClientIp" sortable="custom" width="200">
|
||||
<template #default="scope">
|
||||
<na-ip :ip="scope.row.createdClientIp"></na-ip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" prop="os" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('用户代理')" prop="createdUserAgent" show-overflow-tooltip sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170"></el-table-column>
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<sc-table
|
||||
:apiObj="$API.sys_log.pagedQuery"
|
||||
:context-menus="['id', 'httpStatusCode', 'extraData', 'createdClientIp', 'os', 'createdUserAgent', 'createdTime']"
|
||||
:context-opers="['view']"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:params="query"
|
||||
:vue="this"
|
||||
@row-click="rowClick"
|
||||
ref="table"
|
||||
remoteFilter
|
||||
remoteSort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column :label="$t('日志编号')" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('结果')" align="center" prop="httpStatusCode" sortable="custom" width="80">
|
||||
<template #default="scope">
|
||||
<sc-status-indicator :type="scope.row.httpStatusCode === 200 ? 'success' : 'danger'" />
|
||||
{{ scope.row.httpStatusCode === 200 ? '成功' : '失败' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('登录名')" prop="extraData" sortable="custom" width="200"></el-table-column>
|
||||
<el-table-column :label="$t('客户端IP')" prop="createdClientIp" sortable="custom" width="200">
|
||||
<template #default="scope">
|
||||
<na-ip :ip="scope.row.createdClientIp"></na-ip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" prop="os" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('用户代理')" prop="createdUserAgent" show-overflow-tooltip sortable="custom"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170"></el-table-column>
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
|
@ -1,131 +1,121 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="[
|
||||
{
|
||||
type: 'input',
|
||||
field: ['filter', 'id'],
|
||||
placeholder: '日志编号',
|
||||
style: 'width:12rem',
|
||||
},
|
||||
{
|
||||
multiple: true,
|
||||
type: 'select',
|
||||
field: ['dy', 'httpStatusCode'],
|
||||
options: [
|
||||
{ label: '20x', value: '200,299' },
|
||||
{ label: '30x', value: '300,399' },
|
||||
{ label: '40x', value: '400,499' },
|
||||
{ label: '50x', value: '500,599' },
|
||||
{ label: '90x', value: '900,999' },
|
||||
],
|
||||
placeholder: '状态码',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'cascader',
|
||||
field: ['dy', 'apiId'],
|
||||
api: $API.sys_api.query,
|
||||
props: { label: 'summary', value: 'id', checkStrictly: true, expandTrigger: 'hover', emitPath: false },
|
||||
placeholder: '请求服务',
|
||||
style: 'width:20rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'createdUserName'],
|
||||
placeholder: '用户名',
|
||||
style: 'width:12rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'createdClientIp'],
|
||||
placeholder: '客户端IP',
|
||||
style: 'width:12rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@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"></div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<el-container>
|
||||
<el-header class="headerPublic">
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
:controls="[
|
||||
{
|
||||
type: 'input',
|
||||
field: ['filter', 'id'],
|
||||
placeholder: '日志编号',
|
||||
style: 'width:12rem',
|
||||
},
|
||||
{
|
||||
multiple: true,
|
||||
type: 'select',
|
||||
field: ['dy', 'httpStatusCode'],
|
||||
options: [
|
||||
{ label: '20x', value: '200,299' },
|
||||
{ label: '30x', value: '300,399' },
|
||||
{ label: '40x', value: '400,499' },
|
||||
{ label: '50x', value: '500,599' },
|
||||
{ label: '90x', value: '900,999' },
|
||||
],
|
||||
placeholder: '状态码',
|
||||
style: 'width:15rem',
|
||||
},
|
||||
{
|
||||
type: 'cascader',
|
||||
field: ['dy', 'apiId'],
|
||||
api: $API.sys_api.query,
|
||||
props: { label: 'summary', value: 'id', checkStrictly: true, expandTrigger: 'hover', emitPath: false },
|
||||
placeholder: '请求服务',
|
||||
style: 'width:20rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'createdUserName'],
|
||||
placeholder: '用户名',
|
||||
style: 'width:12rem',
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: ['dy', 'createdClientIp'],
|
||||
placeholder: '客户端IP',
|
||||
style: 'width:12rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch" />
|
||||
</div>
|
||||
<div class="right-panel"></div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:apiObj="$API.sys_log.pagedQuery"
|
||||
:context-menus="[
|
||||
'id',
|
||||
'httpStatusCode',
|
||||
'apiId',
|
||||
'createdUserName',
|
||||
'method',
|
||||
'duration',
|
||||
'createdClientIp',
|
||||
'os',
|
||||
'createdTime',
|
||||
]"
|
||||
:context-opers="[]"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:params="query"
|
||||
:vue="this"
|
||||
@row-click="rowClick"
|
||||
ref="table"
|
||||
remoteFilter
|
||||
remoteSort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column :label="$t('日志编号')" align="center" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('响应码')" align="center" prop="httpStatusCode" sortable="custom" width="100">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.httpStatusCode)).toString(16).substring(0, 6)}`" />
|
||||
<span> {{ scope.row.httpStatusCode }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('请求服务')" align="center">
|
||||
<el-table-column :label="$t('路径')" prop="apiId" show-overflow-tooltip sortable="custom">
|
||||
<template #default="scope">
|
||||
<p>{{ scope.row.apiId }}</p>
|
||||
<p>{{ scope.row.apiSummary }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('方法')" align="center" prop="method" sortable="custom" width="100">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.method)).toString(16).substring(0, 6)}`" />
|
||||
<span> {{ scope.row.method }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:formatter="(row) => `${tool.groupSeparator((row.duration / 1000).toFixed(0))} ms`"
|
||||
:label="$t('耗时')"
|
||||
align="right"
|
||||
prop="duration"
|
||||
sortable="custom"
|
||||
width="120">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('用户名')" prop="createdUserName" sortable="custom" width="150">
|
||||
<template #default="scope">
|
||||
{{ scope.row.apiId === 'api/sys/user/pwd.login' ? scope.row.extraData : scope.row.createdUserName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('客户端IP')" prop="createdClientIp" show-overflow-tooltip sortable="custom" width="200">
|
||||
<template #default="scope">
|
||||
<na-ip :ip="scope.row.createdClientIp"></na-ip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" align="center" prop="os" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170"></el-table-column>
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
<sc-table
|
||||
:apiObj="$API.sys_log.pagedQuery"
|
||||
:context-menus="['id', 'httpStatusCode', 'apiId', 'createdUserName', 'method', 'duration', 'createdClientIp', 'os', 'createdTime']"
|
||||
:context-opers="[]"
|
||||
:default-sort="{ prop: 'createdTime', order: 'descending' }"
|
||||
:params="query"
|
||||
:vue="this"
|
||||
@row-click="rowClick"
|
||||
ref="table"
|
||||
remoteFilter
|
||||
remoteSort
|
||||
row-key="id"
|
||||
stripe>
|
||||
<el-table-column :label="$t('日志编号')" align="center" prop="id" sortable="custom" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('响应码')" align="center" prop="httpStatusCode" sortable="custom" width="100">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.httpStatusCode)).toString(16).substring(0, 6)}`" />
|
||||
<span> {{ scope.row.httpStatusCode }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('请求服务')" align="center">
|
||||
<el-table-column :label="$t('路径')" prop="apiId" show-overflow-tooltip sortable="custom">
|
||||
<template #default="scope">
|
||||
<p>{{ scope.row.apiId }}</p>
|
||||
<p>{{ scope.row.apiSummary }}</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('方法')" align="center" prop="method" sortable="custom" width="100">
|
||||
<template #default="scope">
|
||||
<div class="indicator">
|
||||
<sc-status-indicator
|
||||
:style="`background: #${Math.abs(this.$TOOL.crypto.hashCode(scope.row.method)).toString(16).substring(0, 6)}`" />
|
||||
<span> {{ scope.row.method }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:formatter="(row) => `${tool.groupSeparator((row.duration / 1000).toFixed(0))} ms`"
|
||||
:label="$t('耗时')"
|
||||
align="right"
|
||||
prop="duration"
|
||||
sortable="custom"
|
||||
width="120">
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('用户名')" prop="createdUserName" sortable="custom" width="150">
|
||||
<template #default="scope">
|
||||
{{ scope.row.apiId === 'api/sys/user/pwd.login' ? scope.row.extraData : scope.row.createdUserName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('客户端IP')" prop="createdClientIp" show-overflow-tooltip sortable="custom" width="200">
|
||||
<template #default="scope">
|
||||
<na-ip :ip="scope.row.createdClientIp"></na-ip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('操作系统')" align="center" prop="os" width="150"></el-table-column>
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170"></el-table-column>
|
||||
</sc-table>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
@ -153,7 +143,13 @@ export default {
|
||||
return {
|
||||
query: {
|
||||
dynamicFilter: {
|
||||
filters: [],
|
||||
filters: [
|
||||
{
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')],
|
||||
},
|
||||
],
|
||||
},
|
||||
filter: {},
|
||||
},
|
||||
@ -162,7 +158,12 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
mounted() {
|
||||
this.$refs.search.form.dy.createdTime = this.$refs.search.keepCreatedTime = [
|
||||
`${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`,
|
||||
`${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`,
|
||||
]
|
||||
},
|
||||
methods: {
|
||||
//搜索
|
||||
onSearch(form) {
|
||||
@ -170,41 +171,35 @@ export default {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdTime',
|
||||
operator: 'dateRange',
|
||||
value: form.dy.createdTime,
|
||||
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
|
||||
})
|
||||
}
|
||||
if (Array.isArray(form.dy.httpStatusCode) && form.dy.httpStatusCode.length !== 0) {
|
||||
const filters = []
|
||||
for (const code of form.dy.httpStatusCode) {
|
||||
filters.push({
|
||||
field: 'httpStatusCode',
|
||||
operator: 'range',
|
||||
value: code,
|
||||
})
|
||||
}
|
||||
this.query.dynamicFilter.filters.push({
|
||||
logic: 'or',
|
||||
filters: filters,
|
||||
filters: form.dy.httpStatusCode.map((x) => {
|
||||
return { field: 'httpStatusCode', operator: 'range', value: x }
|
||||
}),
|
||||
})
|
||||
}
|
||||
if (form.dy.apiId) {
|
||||
if (typeof form.dy.apiId === 'string' && form.dy.apiId.trim() !== '') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'apiId',
|
||||
operator: 'contains',
|
||||
operator: 'eq',
|
||||
value: form.dy.apiId,
|
||||
})
|
||||
}
|
||||
if (form.dy.createdUserName) {
|
||||
if (typeof form.dy.createdUserName === 'string' && form.dy.createdUserName.trim() !== '') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdUserName',
|
||||
operator: 'contains',
|
||||
operator: 'eq',
|
||||
value: form.dy.createdUserName,
|
||||
})
|
||||
}
|
||||
if (form.dy.createdClientIp) {
|
||||
if (typeof form.dy.createdClientIp === 'string' && form.dy.createdClientIp.trim() !== '') {
|
||||
this.query.dynamicFilter.filters.push({
|
||||
field: 'createdClientIp',
|
||||
operator: 'contains',
|
||||
operator: 'eq',
|
||||
value: form.dy.createdClientIp,
|
||||
})
|
||||
}
|
||||
|
@ -1,5 +1,23 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header style="height: auto; padding: 0 1rem">
|
||||
<sc-select-filter
|
||||
:data="[
|
||||
{
|
||||
title: $t('消息类型'),
|
||||
key: 'msgType',
|
||||
options: [
|
||||
{ label: $t('全部'), value: '' },
|
||||
...Object.entries(this.$GLOBAL.enums.siteMsgTypes).map((x) => {
|
||||
return { value: x[0], label: x[1][1] }
|
||||
}),
|
||||
],
|
||||
},
|
||||
]"
|
||||
:label-width="6"
|
||||
@on-change="filterChange"
|
||||
ref="selectFilter"></sc-select-filter>
|
||||
</el-header>
|
||||
<el-header>
|
||||
<div class="left-panel">
|
||||
<na-search
|
||||
@ -10,18 +28,11 @@
|
||||
placeholder: $t('消息编号 / 消息主题 / 消息内容'),
|
||||
style: 'width:20rem',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: ['dy', 'msgType'],
|
||||
options: Object.entries(this.$GLOBAL.enums.siteMsgTypes).map((x) => {
|
||||
return { value: x[0], label: x[1][1] }
|
||||
}),
|
||||
placeholder: $t('消息类型'),
|
||||
style: 'width:15rem',
|
||||
},
|
||||
]"
|
||||
:vue="this"
|
||||
@search="onSearch" />
|
||||
@reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))"
|
||||
@search="onSearch"
|
||||
ref="search" />
|
||||
</div>
|
||||
<div class="right-panel">
|
||||
<na-button-add :vue="this" />
|
||||
@ -51,13 +62,14 @@
|
||||
<na-col-avatar :label="$t('用户名')" prop="createdUserName" />
|
||||
<na-col-indicator
|
||||
:label="$t('消息类型')"
|
||||
:options="[
|
||||
{ text: '私信', type: 'success', value: 'private' },
|
||||
{ text: '公告', type: 'warning', value: 'public' },
|
||||
]"
|
||||
:options="
|
||||
Object.entries(this.$GLOBAL.enums.siteMsgTypes).map((x) => {
|
||||
return { value: x[0], text: x[1][1] }
|
||||
})
|
||||
"
|
||||
prop="msgType"
|
||||
width="100"></na-col-indicator>
|
||||
|
||||
width="100">
|
||||
</na-col-indicator>
|
||||
<el-table-column :label="$t('消息主题')" prop="title" show-overflow-tooltip sortable="custom" />
|
||||
<el-table-column :label="$t('消息摘要')" prop="summary" show-overflow-tooltip sortable="custom" />
|
||||
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170" />
|
||||
@ -120,6 +132,12 @@ export default {
|
||||
mounted() {},
|
||||
created() {},
|
||||
methods: {
|
||||
filterChange(data) {
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
this.$refs.search.form.dy[key] = value
|
||||
})
|
||||
this.$refs.search.search()
|
||||
},
|
||||
//删除
|
||||
async rowDel(row) {
|
||||
try {
|
||||
|
Reference in New Issue
Block a user