Browse Source

fix:审计页面左侧菜单新增选项:操作记录、消毒记录,设置页面去除消毒默认配置选项。

master
白凤吉 2 weeks ago
parent
commit
701df6c8cd
  1. 5
      src/components/audit/History.vue
  2. 140
      src/components/audit/OperationRecord.vue
  3. 21
      src/stores/auditStore.ts
  4. 4
      src/stores/settingStore.ts
  5. 212
      src/views/audit/index.vue
  6. 4
      src/views/setting/index.vue

5
src/components/setting/History.vue → src/components/audit/History.vue

@ -2,11 +2,10 @@
// import { useSettingStore } from '@/stores/settingStore' // import { useSettingStore } from '@/stores/settingStore'
import { syncSendCmd } from 'apis/system' import { syncSendCmd } from 'apis/system'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import { FtMessage } from 'libs/message'
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import { FtMessage } from '@/libs/message'
import HistoryDetail from './HistoryDetail.vue'
import HistoryDetail from '../setting/HistoryDetail.vue'
// const settingStore = useSettingStore() // const settingStore = useSettingStore()
const tableData = ref<string[]>([]) const tableData = ref<string[]>([])
const selectedRecords = ref<Setting.History[]>([]) const selectedRecords = ref<Setting.History[]>([])

140
src/components/audit/OperationRecord.vue

@ -0,0 +1,140 @@
<script lang="ts" setup>
import { sendCmd, syncSendCmd } from 'apis/system'
import type { TableColumnCtx } from 'element-plus'
import { onMounted, ref } from 'vue'
import { FtMessage } from '@/libs/message'
/**
* 操作记录组件
*/
//
const pageNum = ref(1) //
const pageSize = ref(10) //
const totle = ref(0) //
//
const tableData = ref<Audit.AuditItem[]>([]) //
/**
* @hook 生命周期钩子 - 组件挂载完成时执行
* @description 初始化加载审计日志列表
*/
onMounted(() => {
getAuditList()
})
/**
* @function 获取审计日志列表
* @desc 从服务端获取分页后的审计日志数据
*/
const getAuditList = async () => {
const params = {
className: 'AuditMgrService',
fnName: 'getRecords',
params: {
page: pageNum.value,
pageSize: pageSize.value,
},
}
try {
const res = await sendCmd(params)
tableData.value = res.items || []
totle.value = res.total || 0
}
catch (error) {
FtMessage.error('获取日志列表失败')
console.error('获取审计日志失败:', error)
}
}
/**
* @function 导出全部审计记录
* @desc 导出单条审计记录需先选择一条记录
*/
const onExportRecord = () => {
// if (selectedUserList.value.length !== 1) {
// FtMessage.warning('')
// return
// }
const params = {
className: 'AuditMgrService',
fnName: 'exportData',
}
syncSendCmd(params)
.then((res) => {
if (res.ackcode === 0) {
FtMessage.success('导出成功')
}
})
.catch((error) => {
console.error('导出审计记录失败:', error)
})
}
/**
* @function 页码变更处理
* @param {number} page - 新的页码
* @desc 更新页码并重新加载数据
*/
const handleCurrentChange = (page: number) => {
pageNum.value = page
getAuditList()
}
const formatIndex = (
_row: unknown,
_column: TableColumnCtx<unknown>,
_cellValue: unknown,
index: number,
): number => {
return (pageNum.value - 1) * pageSize.value + index + 1
}
</script>
<template>
<div class="dashboard-container">
<main class="main-content">
<div class="audit-export">
<bt-button type="primary" button-text="全部导出" @click="onExportRecord" />
</div>
<div class="audit-table">
<el-table :data="tableData" style="width: 100%" height="100%">
<el-table-column label="序号" width="100" :formatter="formatIndex" />
<el-table-column prop="usrName" label="操作人" width="250" />
<el-table-column prop="behaviorinfo" label="操作内容" />
<el-table-column prop="date" label="操作时间" width="250" />
</el-table>
</div>
<div class="audit-pagination">
<el-pagination layout="prev, pager, next" :total="totle" @current-change="handleCurrentChange" />
</div>
</main>
</div>
</template>
<style lang="scss" scoped>
.main-content {
height: $main-container-height;
overflow: hidden;
background: $gradient-color;
box-shadow: 0px 1px 5px 0px rgba(9, 39, 62, 0.15);
.audit-export {
height: 50px;
padding: 0 10px;
display: flex;
align-items: center;
}
.audit-table {
overflow: auto;
height: calc(100% - 100px);
}
.audit-pagination {
height: 50px;
display: flex;
align-items: center;
float: right;
}
}
</style>

21
src/stores/auditStore.ts

@ -0,0 +1,21 @@
import { defineStore } from 'pinia'
/**
*
*/
export const useAuditStore = defineStore('audit', () => {
// 设置菜单配置
const auditMenus = [{
name: '操作记录',
code: 'history',
roleType: 'admin',
}, {
name: '消毒记录',
code: 'operationRecord',
roleType: 'admin,maintainer',
}]
const historyList: Record<string, string>[] = []
return {
auditMenus,
historyList,
}
})

4
src/stores/settingStore.ts

@ -8,10 +8,6 @@ import { ref } from 'vue'
export const useSettingStore = defineStore('setting', () => { export const useSettingStore = defineStore('setting', () => {
// 设置菜单配置 // 设置菜单配置
const settingMenus = [{ const settingMenus = [{
name: '消毒历史记录',
code: 'history',
roleType: 'admin,maintainer',
}, {
name: '消毒默认配置', name: '消毒默认配置',
code: 'defaultFormula', code: 'defaultFormula',
roleType: 'admin,maintainer', roleType: 'admin,maintainer',

212
src/views/audit/index.vue

@ -1,115 +1,42 @@
<script lang="ts" setup> <script lang="ts" setup>
import { sendCmd, syncSendCmd } from 'apis/system'
import type { TableColumnCtx } from 'element-plus'
import { onMounted, ref } from 'vue'
import History from 'components/audit/History.vue'
import OperationRecord from 'components/audit/OperationRecord.vue'
import { useAuditStore } from 'stores/auditStore'
import { ref } from 'vue'
import { FtMessage } from '@/libs/message'
/**
* 审计日志管理组件
* @description 展示审计日志列表支持分页和单条记录导出功能
*/
//
const pageNum = ref(1) //
const pageSize = ref(10) //
const totle = ref(0) //
//
const tableData = ref<Audit.AuditItem[]>([]) //
/**
* @hook 生命周期钩子 - 组件挂载完成时执行
* @description 初始化加载审计日志列表
*/
onMounted(() => {
getAuditList()
})
/**
* @function 获取审计日志列表
* @desc 从服务端获取分页后的审计日志数据
*/
const getAuditList = async () => {
const params = {
className: 'AuditMgrService',
fnName: 'getRecords',
params: {
page: pageNum.value,
pageSize: pageSize.value,
},
}
try {
const res = await sendCmd(params)
tableData.value = res.items || []
totle.value = res.total || 0
}
catch (error) {
FtMessage.error('获取日志列表失败')
console.error('获取审计日志失败:', error)
}
}
/**
* @function 导出全部审计记录
* @desc 导出单条审计记录需先选择一条记录
*/
const onExportRecord = () => {
// if (selectedUserList.value.length !== 1) {
// FtMessage.warning('')
// return
// }
const params = {
className: 'AuditMgrService',
fnName: 'exportData',
}
syncSendCmd(params)
.then((res) => {
if (res.ackcode === 0) {
FtMessage.success('导出成功')
}
})
.catch((error) => {
console.error('导出审计记录失败:', error)
})
}
/**
* @function 页码变更处理
* @param {number} page - 新的页码
* @desc 更新页码并重新加载数据
*/
const handleCurrentChange = (page: number) => {
pageNum.value = page
getAuditList()
}
const formatIndex = (
_row: unknown,
_column: TableColumnCtx<unknown>,
_cellValue: unknown,
index: number,
): number => {
return (pageNum.value - 1) * pageSize.value + index + 1
const auditStore = useAuditStore()
const currentUserRoleType = JSON.parse(localStorage.getItem('user') || '{}')?.roleType
const auditMenus = auditStore.auditMenus.filter((item): boolean => item.roleType.includes(currentUserRoleType))
const selectedMenuCode = ref('history')
//
const selectItem = (menuCode: string) => {
selectedMenuCode.value = menuCode
} }
</script> </script>
<template> <template>
<div class="dashboard-container"> <div class="dashboard-container">
<main class="main-content"> <main class="main-content">
<div class="audit-export">
<bt-button type="primary" button-text="全部导出" @click="onExportRecord" />
<div class="setting-left">
<div class="menu-container">
<ul class="menu-container">
<li
v-for="item in auditMenus"
:key="item.code"
:class="{ active: selectedMenuCode === item.code }"
class="setting-menu-li menu-item"
@click="selectItem(item.code)"
>
{{ item.name }}
</li>
</ul>
</div>
</div> </div>
<div class="audit-table">
<el-table :data="tableData" style="width: 100%" height="100%">
<el-table-column label="序号" width="100" :formatter="formatIndex" />
<el-table-column prop="usrName" label="操作人" width="250" />
<el-table-column prop="behaviorinfo" label="操作内容" />
<el-table-column prop="date" label="操作时间" width="250" />
</el-table>
</div>
<div class="audit-pagination">
<el-pagination layout="prev, pager, next" :total="totle" @current-change="handleCurrentChange" />
<div class="setting-right">
<History v-if="selectedMenuCode === 'history'" />
<div v-if="selectedMenuCode === 'operationRecord'">
<OperationRecord />
</div>
</div> </div>
</main> </main>
</div> </div>
@ -117,25 +44,74 @@ const formatIndex = (
<style lang="scss" scoped> <style lang="scss" scoped>
.main-content { .main-content {
display: grid;
grid-template-columns: repeat(3, 1fr);
height: $main-container-height; height: $main-container-height;
gap: 10px;
overflow: hidden; overflow: hidden;
background: $gradient-color;
box-shadow: 0px 1px 5px 0px rgba(9, 39, 62, 0.15);
.audit-export {
height: 50px;
padding: 0 10px;
display: flex;
align-items: center;
.setting-left {
background: linear-gradient(180deg, rgba(147, 203, 255, 0.01) 50%, #ffffff 24%);
box-shadow: 0 0 4px #0000001f;
border-radius: 10px;
border: 1px solid #e1e1e1;
overflow: hidden;
} }
.audit-table {
overflow: auto;
height: calc(100% - 100px);
.setting-right {
grid-column: 2 / 4;
box-shadow: 0 1px 5px 0 rgba(9, 39, 62, 0.15);
background: #ffffff;
border: 1px solid #e1e1e1;
background: $gradient-color;
border-radius: 10px;
overflow: hidden;
padding: 10px;
} }
.audit-pagination {
height: 50px;
display: flex;
align-items: center;
float: right;
}
.menu-container {
padding: 5px 0;
width: 100%;
height: 100%;
overflow: auto;
.setting-menu-li {
font-size: 18px;
} }
} }
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
padding: 15px 15px;
font-size: 15px;
display: flex;
align-items: center;
//border-radius: 10px;
height: 60px;
border-left: 5px solid #fff;
transition: border-left-color 0.3s ease;
}
li.active {
border-left: 5px solid #2892f3;
// color: #e6f7ff;
background: #e8f3ff;
//border-radius: 10px;
color: #2892f3;
}
.menu-container {
width: 100%; /* 占满父容器 */
background: #fff;
// border: 1px solid #eee;
overflow: hidden; /* 配合圆角,避免阴影/边框溢出 */
}
.menu-item {
padding: 14px 20px; /* 更大触摸区域 */
font-size: 15px; /* 适配手机阅读 */
border-bottom: 1px solid #f5f5f5;
}
/* 最后一项去掉分隔线 */
.menu-item:last-child {
border-bottom: none;
}
</style> </style>

4
src/views/setting/index.vue

@ -1,5 +1,4 @@
<script lang="ts" setup> <script lang="ts" setup>
import History from 'components/setting/History.vue'
import { ref } from 'vue' import { ref } from 'vue'
import FormulaConfig from '@/components/formula/FormulaConfig.vue' import FormulaConfig from '@/components/formula/FormulaConfig.vue'
@ -11,7 +10,7 @@ import { useSettingStore } from '@/stores/settingStore'
const settingStore = useSettingStore() const settingStore = useSettingStore()
const currentUserRoleType = JSON.parse(localStorage.getItem('user') || '{}')?.roleType const currentUserRoleType = JSON.parse(localStorage.getItem('user') || '{}')?.roleType
const settingMenus = settingStore.settingMenus.filter((item): boolean => item.roleType.includes(currentUserRoleType)) const settingMenus = settingStore.settingMenus.filter((item): boolean => item.roleType.includes(currentUserRoleType))
const selectedMenuCode = ref('history')
const selectedMenuCode = ref('defaultFormula')
// //
const selectItem = (menuCode: string) => { const selectItem = (menuCode: string) => {
selectedMenuCode.value = menuCode selectedMenuCode.value = menuCode
@ -37,7 +36,6 @@ const selectItem = (menuCode: string) => {
</div> </div>
</div> </div>
<div class="setting-right"> <div class="setting-right">
<History v-if="selectedMenuCode === 'history'" />
<div v-if="selectedMenuCode === 'defaultFormula'"> <div v-if="selectedMenuCode === 'defaultFormula'">
<FormulaConfig type="setting" :formula-name-visible="false" /> <FormulaConfig type="setting" :formula-name-visible="false" />
</div> </div>

Loading…
Cancel
Save