mes-vue/src/views/biz/device/DeviceOperationLog.vue
2026-07-28 09:00:22 +08:00

273 lines
6.4 KiB
Vue

<script setup lang="ts">
import {NButton, NIcon, NSpace} from "naive-ui";
import {ArrowDown, ArrowUp, RefreshOutline, SearchOutline} from "@vicons/ionicons5";
import {onMounted, reactive, ref} from "vue";
import { deviceApi, Device} from '@/api/device.ts'
import {dictDataApi} from "@/api/org.ts";
import {userApi,SysUser} from "@/api/system.ts";
import { deviceOperationLogApi,type DeviceOperationLog } from '@/api/deviceOperationLog.ts'
const pagination = reactive({
page: 1,
pageSize: 10,
itemCount: 0,
showSizePicker: true,
pageSizes: [10, 20, 50]
})
const props = defineProps({
deviceId:Number
})
const showSearchInput = ref<Boolean>(false)
const searchForm = ref({
createTime: undefined,
operationType: undefined,
userId: undefined
})
const doShowInner = () => {
if (showSearchInput.value) {
showSearchInput.value = false
}else {
showSearchInput.value = true
}
}
//设备集合
const deviceList = ref<Device[]>([])
const getDeviceList = async () => {
try {
const res = await deviceApi.deviceList()
deviceList.value = res.map((n:any)=>{
return {
label:n.deviceName,
value:n.id
}
})
} catch (error) {
// 错误已在拦截器处理
}
}
//操作类型
const optionTypeList = ref([])
const loadDictOptions = async ()=>{
try {
const data = await dictDataApi.listByType("option_type")
optionTypeList.value = data.map(d => ({
label: d.dictLabel,
value: (Number(d.dictValue) || d.dictValue),
class: d.listClass
}))
} catch {
}
}
//人员集合
const optionUserList = ref<SysUser[]>([])
const loadUserList = async ()=>{
try {
const data = await userApi.getPathList()
optionUserList.value = data.map(d => ({
label: d.nickname,
value: d.id
}))
} catch {
}
}
//查询操作日志
const data = ref([])
const load = async()=>{
const res = await deviceOperationLogApi.page({
page: pagination.page,
pageSize: pagination.pageSize,
deviceId: props.deviceId,
createTime: searchForm.value.createTime,
operationType: searchForm.value.operationType,
userId: searchForm.value.userId
});
data.value = res.list
pagination.itemCount = res.total
}
//表格
const columns = [
{
title: '设备名称',
key: 'deviceName'
},
{
title: '操作类型',
key: 'operationTypeName'
},
{
title: '操作人员',
key: 'userName'
},
{
title: '操作时间',
key: 'createTime'
},
{
title: '数据来源',
key: 'source',
render(row) {
var opt = row.source
if(opt == 1) return '终端'
if(opt == 2) return '后台'
return '-'
}
}
]
const handleSearch = () => {
load()
}
const handleReset = () => {
searchForm.value.createTime = null
searchForm.value.operationType = null
searchForm.value.userId = null
pagination.page = 1
pagination.pageSize = 10
load()
}
// 分页
function handlePageChange(page: number) {
pagination.page = page
load()
}
function handlePageSizeChange(pageSize: number) {
pagination.pageSize = pageSize
pagination.page = 1
load()
}
onMounted(()=>{
getDeviceList()
loadDictOptions()
loadUserList()
load()
})
</script>
<template>
<div>
<n-button @click="doShowInner" v-if="showSearchInput">
<n-icon size="20" :depth="3">
<ArrowDown/>
</n-icon>
展开
</n-button>
<n-card v-if="!showSearchInput">
<n-form inline :model="searchForm" label-placement="left">
<n-grid :x-gap="8" :cols="4">
<n-gi>
<n-form-item label="日期">
<n-date-picker
v-model:value="searchForm.createTime"
type="date" />
</n-form-item>
</n-gi>
<!-- <n-gi>-->
<!-- <n-form-item label="操作类型">-->
<!-- <n-select-->
<!-- v-model:value="searchForm.operationType"-->
<!-- :options="optionTypeList"-->
<!-- placeholder="请选择设备类型"-->
<!-- clearable-->
<!-- style="width: 200px"-->
<!-- />-->
<!-- </n-form-item>-->
<!-- </n-gi>-->
<n-gi>
<n-form-item label="操作人员">
<n-select
v-model:value="searchForm.userId"
:options="optionUserList"
placeholder="请选择设备类型"
clearable
style="width: 200px"
/>
</n-form-item>
</n-gi>
<n-gi>
<n-form-item>
<n-space>
<n-button type="primary" @click="handleSearch">
<template #icon>
<n-icon>
<SearchOutline/>
</n-icon>
</template>
搜索
</n-button>
<n-button @click="handleReset">
<template #icon>
<n-icon>
<RefreshOutline/>
</n-icon>
</template>
重置
</n-button>
</n-space>
</n-form-item>
</n-gi>
</n-grid>
</n-form>
<n-button @click="doShowInner" v-if="!showSearchInput" style="float: right;margin: 10px">
<n-icon size="20" :depth="3">
<ArrowUp/>
</n-icon>
闭合
</n-button>
</n-card>
<n-card style="margin: 20px 0">
<n-data-table
:columns="columns"
:data="data"
:bordered="false"
/>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
<n-pagination
v-model:page="pagination.page"
v-model:page-size="pagination.pageSize"
:item-count="pagination.itemCount"
:page-sizes="[10, 20, 50, 100]"
show-size-picker
show-quick-jumper
@update:page="handlePageChange"
@update:page-size="handlePageSizeChange"
>
<template #prefix>
{{ pagination.itemCount }}
</template>
</n-pagination>
</div>
</n-card>
</div>
</template>
<style scoped>
</style>