refactor: 优化系统日志、在线用户、存储管理、部门管理相关代码

This commit is contained in:
2024-04-22 23:13:35 +08:00
parent 2ddd900121
commit 2987d3eb4d
12 changed files with 57 additions and 51 deletions

View File

@@ -1,7 +1,7 @@
import http from '@/utils/http' import http from '@/utils/http'
import type * as Monitor from './type' import type * as Monitor from './type'
const BASE_URL = '/monitor/online/user' const BASE_URL = '/monitor/online'
/** @desc 查询在线用户列表 */ /** @desc 查询在线用户列表 */
export function listOnlineUser(query: Monitor.OnlineUserQuery) { export function listOnlineUser(query: Monitor.OnlineUserQuery) {

View File

@@ -22,7 +22,7 @@
</template> </template>
<template #custom-right> <template #custom-right>
<a-tooltip content="导出"> <a-tooltip content="导出">
<a-button @click="onExport"> <a-button v-permission="['monitor:log:export']" @click="onExport">
<template #icon> <template #icon>
<icon-download /> <icon-download />
</template> </template>
@@ -109,6 +109,17 @@ const {
search search
} = useTable((p) => listLog({ ...queryForm, page: p.page, size: p.size }), { immediate: true }) } = useTable((p) => listLog({ ...queryForm, page: p.page, size: p.size }), { immediate: true })
// 过滤查询
const filterChange = (dataIndex, filteredValues) => {
try {
const slotName = columns[dataIndex.split('_').pop()].slotName as string
queryForm[slotName] = filteredValues.join(',')
search()
} catch (error) {
search()
}
}
// 重置 // 重置
const reset = () => { const reset = () => {
queryForm.ip = undefined queryForm.ip = undefined
@@ -125,17 +136,6 @@ const reset = () => {
const onExport = () => { const onExport = () => {
useDownload(() => exportLoginLog(queryForm)) useDownload(() => exportLoginLog(queryForm))
} }
// 过滤查询
const filterChange = (dataIndex, filteredValues) => {
try {
const slotName = columns[dataIndex.split('_').pop()].slotName as string
queryForm[slotName] = filteredValues.join(',')
search()
} catch (error) {
search()
}
}
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@@ -82,14 +82,14 @@ const getDataDetail = async () => {
} }
const visible = ref(false) const visible = ref(false)
// 打开详情 // 详情
const open = async (id: string) => { const onDetail = async (id: string) => {
dataId.value = id dataId.value = id
await getDataDetail() await getDataDetail()
visible.value = true visible.value = true
} }
defineExpose({ open }) defineExpose({ onDetail })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -23,7 +23,7 @@
</template> </template>
<template #custom-right> <template #custom-right>
<a-tooltip content="导出"> <a-tooltip content="导出">
<a-button @click="onExport"> <a-button v-permission="['monitor:log:export']" @click="onExport">
<template #icon> <template #icon>
<icon-download /> <icon-download />
</template> </template>
@@ -31,7 +31,7 @@
</a-tooltip> </a-tooltip>
</template> </template>
<template #createTime="{ record }"> <template #createTime="{ record }">
<a-link @click="openDetail(record)">{{ record.createTime }}</a-link> <a-link @click="onDetail(record)">{{ record.createTime }}</a-link>
</template> </template>
<template #status="{ record }"> <template #status="{ record }">
<a-tag v-if="record.status === 1" color="green"> <a-tag v-if="record.status === 1" color="green">
@@ -57,9 +57,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { listLog, exportOperationLog, type LogResp } from '@/apis' import { listLog, exportOperationLog, type LogResp } from '@/apis'
import OperationLogDetailDrawer from './OperationLogDetailDrawer.vue'
import type { TableInstanceColumns } from '@/components/GiTable/type' import type { TableInstanceColumns } from '@/components/GiTable/type'
import DateRangePicker from '@/components/DateRangePicker/index.vue' import DateRangePicker from '@/components/DateRangePicker/index.vue'
import OperationLogDetailDrawer from './OperationLogDetailDrawer.vue'
import { useTable, useDownload } from '@/hooks' import { useTable, useDownload } from '@/hooks'
import dayjs from 'dayjs' import dayjs from 'dayjs'
@@ -121,7 +121,18 @@ const {
search search
} = useTable((p) => listLog({ ...queryForm, page: p.page, size: p.size }), { immediate: true }) } = useTable((p) => listLog({ ...queryForm, page: p.page, size: p.size }), { immediate: true })
// 重置查询 // 过滤查询
const filterChange = (dataIndex, filteredValues) => {
try {
const slotName = columns[dataIndex.split('_').pop()].slotName as string
queryForm[slotName] = filteredValues.join(',')
search()
} catch (error) {
search()
}
}
// 重置
const reset = () => { const reset = () => {
queryForm.description = undefined queryForm.description = undefined
queryForm.ip = undefined queryForm.ip = undefined
@@ -139,21 +150,10 @@ const onExport = () => {
useDownload(() => exportOperationLog(queryForm)) useDownload(() => exportOperationLog(queryForm))
} }
// 过滤查询
const filterChange = (dataIndex, filteredValues) => {
try {
const slotName = columns[dataIndex.split('_').pop()].slotName as string
queryForm[slotName] = filteredValues.join(',')
search()
} catch (error) {
search()
}
}
const OperationLogDetailDrawerRef = ref<InstanceType<typeof OperationLogDetailDrawer>>() const OperationLogDetailDrawerRef = ref<InstanceType<typeof OperationLogDetailDrawer>>()
// 查询详情 // 详情
const openDetail = (item: LogResp) => { const onDetail = (item: LogResp) => {
OperationLogDetailDrawerRef.value?.open(item.id) OperationLogDetailDrawerRef.value?.onDetail(item.id)
} }
</script> </script>

View File

@@ -28,6 +28,7 @@
@ok="handleKickout(record.token)" @ok="handleKickout(record.token)"
> >
<a-link <a-link
v-permission="['monitor:online:kickout']"
status="danger" status="danger"
:title="currentToken === record.token ? '不能强退自己' : '强退'" :title="currentToken === record.token ? '不能强退自己' : '强退'"
:disabled="currentToken === record.token" :disabled="currentToken === record.token"
@@ -50,9 +51,12 @@ import DateRangePicker from '@/components/DateRangePicker/index.vue'
import { useUserStore } from '@/stores' import { useUserStore } from '@/stores'
import { useTable } from '@/hooks' import { useTable } from '@/hooks'
import { isMobile } from '@/utils' import { isMobile } from '@/utils'
import has from '@/utils/has'
defineOptions({ name: 'MonitorOnline' }) defineOptions({ name: 'MonitorOnline' })
const userStore = useUserStore()
const currentToken = userStore.token
const columns: TableInstanceColumns[] = [ const columns: TableInstanceColumns[] = [
{ {
title: '序号', title: '序号',
@@ -66,7 +70,13 @@ const columns: TableInstanceColumns[] = [
{ title: '浏览器', dataIndex: 'browser', ellipsis: true, tooltip: true }, { title: '浏览器', dataIndex: 'browser', ellipsis: true, tooltip: true },
{ title: '终端系统', dataIndex: 'os', ellipsis: true, tooltip: true }, { title: '终端系统', dataIndex: 'os', ellipsis: true, tooltip: true },
{ title: '登录时间', dataIndex: 'loginTime', width: 180 }, { title: '登录时间', dataIndex: 'loginTime', width: 180 },
{ title: '操作', slotName: 'action', align: 'center', fixed: !isMobile() ? 'right' : undefined } {
title: '操作',
slotName: 'action',
align: 'center',
fixed: !isMobile() ? 'right' : undefined,
show: has.hasPermOr(['monitor:online:kickout'])
}
] ]
const queryForm = reactive({ const queryForm = reactive({
@@ -89,8 +99,6 @@ const reset = () => {
search() search()
} }
const userStore = useUserStore()
const currentToken = userStore.token
// 强退 // 强退
const handleKickout = (token: string) => { const handleKickout = (token: string) => {
kickout(token).then(() => { kickout(token).then(() => {

View File

@@ -84,10 +84,10 @@ import DeptAddModal from './DeptAddModal.vue'
import { Message } from '@arco-design/web-vue' import { Message } from '@arco-design/web-vue'
import type GiTable from '@/components/GiTable/index.vue' import type GiTable from '@/components/GiTable/index.vue'
import type { TableInstanceColumns } from '@/components/GiTable/type' import type { TableInstanceColumns } from '@/components/GiTable/type'
import { DisEnableStatusList } from '@/constant/common'
import { useDownload } from '@/hooks' import { useDownload } from '@/hooks'
import { isMobile } from '@/utils' import { isMobile } from '@/utils'
import has from '@/utils/has' import has from '@/utils/has'
import { DisEnableStatusList } from '@/constant/common'
defineOptions({ name: 'SystemDept' }) defineOptions({ name: 'SystemDept' })

View File

@@ -4,7 +4,7 @@
:title="title" :title="title"
:mask-closable="false" :mask-closable="false"
:esc-to-close="false" :esc-to-close="false"
:width="width >= 580 ? 580 : '100%'" :width="width >= 600 ? 600 : '100%'"
@before-ok="save" @before-ok="save"
@close="reset" @close="reset"
> >

View File

@@ -1,5 +1,5 @@
<template> <template>
<a-drawer v-model:visible="visible" title="角色详情" :width="width >= 580 ? 580 : '100%'" :footer="false"> <a-drawer v-model:visible="visible" title="角色详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
<a-descriptions title="基础信息" :column="2" size="large" class="general-description"> <a-descriptions title="基础信息" :column="2" size="large" class="general-description">
<a-descriptions-item label="ID" :span="2">{{ dataDetail?.id }}</a-descriptions-item> <a-descriptions-item label="ID" :span="2">{{ dataDetail?.id }}</a-descriptions-item>
<a-descriptions-item label="名称">{{ dataDetail?.name }}</a-descriptions-item> <a-descriptions-item label="名称">{{ dataDetail?.name }}</a-descriptions-item>

View File

@@ -4,7 +4,7 @@
:title="title" :title="title"
:mask-closable="false" :mask-closable="false"
:esc-to-close="false" :esc-to-close="false"
:width="width >= 580 ? 580 : '100%'" :width="width >= 600 ? 600 : '100%'"
@before-ok="save" @before-ok="save"
@close="reset" @close="reset"
> >

View File

@@ -51,7 +51,7 @@
<a-link <a-link
v-permission="['system:storage:delete']" v-permission="['system:storage:delete']"
status="danger" status="danger"
:title="record.isDefault ? '默认存储不能删除' : undefined" :title="record.isDefault ? '默认存储不能删除' : undefined"
:disabled="record.disabled" :disabled="record.disabled"
@click="onDelete(record)" @click="onDelete(record)"
> >
@@ -104,9 +104,9 @@ const columns: TableInstanceColumns[] = [
title: '操作', title: '操作',
slotName: 'action', slotName: 'action',
width: 130, width: 130,
show: has.hasPermOr(['system:storage:update', 'system:storage:delete']),
align: 'center', align: 'center',
fixed: !isMobile() ? 'right' : undefined fixed: !isMobile() ? 'right' : undefined,
show: has.hasPermOr(['system:storage:update', 'system:storage:delete'])
} }
] ]

View File

@@ -4,7 +4,7 @@
:title="title" :title="title"
:mask-closable="false" :mask-closable="false"
:esc-to-close="false" :esc-to-close="false"
:width="width >= 580 ? 580 : '100%'" :width="width >= 600 ? 600 : '100%'"
@before-ok="save" @before-ok="save"
@close="reset" @close="reset"
> >
@@ -160,6 +160,7 @@ const onUpdate = async (id: string) => {
// 保存 // 保存
const save = async () => { const save = async () => {
const rawPassword = form.password
try { try {
const isInvalid = await formRef.value?.validate() const isInvalid = await formRef.value?.validate()
if (isInvalid) return false if (isInvalid) return false
@@ -167,19 +168,16 @@ const save = async () => {
await updateUser(form, dataId.value) await updateUser(form, dataId.value)
Message.success('修改成功') Message.success('修改成功')
} else { } else {
const rawPassword = form.password
if (rawPassword) { if (rawPassword) {
form.password = encryptByRsa(rawPassword) || '' form.password = encryptByRsa(rawPassword) || ''
} }
await addUser(form).catch(() => { await addUser(form)
form.password = rawPassword
return false
})
Message.success('新增成功') Message.success('新增成功')
} }
emit('save-success') emit('save-success')
return true return true
} catch (error) { } catch (error) {
form.password = rawPassword
return false return false
} }
} }

View File

@@ -1,5 +1,5 @@
<template> <template>
<a-drawer v-model:visible="visible" title="用户详情" :width="width >= 580 ? 580 : '100%'" :footer="false"> <a-drawer v-model:visible="visible" title="用户详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
<a-descriptions :column="2" size="large" class="general-description"> <a-descriptions :column="2" size="large" class="general-description">
<a-descriptions-item label="ID" :span="2">{{ dataDetail?.id }}</a-descriptions-item> <a-descriptions-item label="ID" :span="2">{{ dataDetail?.id }}</a-descriptions-item>
<a-descriptions-item label="用户名">{{ dataDetail?.username }}</a-descriptions-item> <a-descriptions-item label="用户名">{{ dataDetail?.username }}</a-descriptions-item>