实现设备中心添加设备类型弹窗页面以及另外搭建完成设备盘库页面
This commit is contained in:
parent
b1b34e630f
commit
bac2e99f0d
|
@ -49,4 +49,24 @@ export function returnEquipment(equipmentId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出设备采购 API
|
// 导出设备采购 API
|
||||||
export * from './procurement'
|
export * from './procurement'
|
||||||
|
|
||||||
|
// 设备盘库相关 API
|
||||||
|
/** @desc 分页查询设备盘库记录 */
|
||||||
|
export function pageEquipmentInventory(query: T.EquipmentPageQuery) {
|
||||||
|
return http.get<T.EquipmentResp[]>(`${BASE_URL}/inventory/page`, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @desc 执行设备盘库 */
|
||||||
|
export function executeEquipmentInventory(equipmentId: string, inventoryResult: string, remark?: string) {
|
||||||
|
return http.post(`${BASE_URL}/inventory/${equipmentId}`, null, {
|
||||||
|
params: { inventoryResult, remark }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @desc 批量执行设备盘库 */
|
||||||
|
export function batchExecuteEquipmentInventory(equipmentIds: string[], inventoryResult: string, remark?: string) {
|
||||||
|
return http.post(`${BASE_URL}/inventory/batch`, null, {
|
||||||
|
params: { equipmentIds, inventoryResult, remark }
|
||||||
|
})
|
||||||
|
}
|
|
@ -1282,6 +1282,16 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
hidden: false,
|
hidden: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/system-resource/device-management/inventory',
|
||||||
|
name: 'DeviceInventory',
|
||||||
|
component: () => import('@/views/system-resource/device-management/inventory.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '设备盘库',
|
||||||
|
icon: 'inbox',
|
||||||
|
hidden: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/system-resource/device-management/online',
|
path: '/system-resource/device-management/online',
|
||||||
name: 'SystemResourceDeviceOnline',
|
name: 'SystemResourceDeviceOnline',
|
||||||
|
|
|
@ -226,6 +226,20 @@ const storeSetup = () => {
|
||||||
{
|
{
|
||||||
id: 2013,
|
id: 2013,
|
||||||
parentId: 2010,
|
parentId: 2010,
|
||||||
|
title: '设备盘库',
|
||||||
|
type: 2,
|
||||||
|
path: '/asset-management/device-management/inventory',
|
||||||
|
name: 'DeviceInventory',
|
||||||
|
component: 'system-resource/device-management/inventory',
|
||||||
|
icon: 'inbox',
|
||||||
|
isExternal: false,
|
||||||
|
isCache: false,
|
||||||
|
isHidden: false,
|
||||||
|
sort: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2014,
|
||||||
|
parentId: 2010,
|
||||||
title: '审批台',
|
title: '审批台',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/approval',
|
path: '/asset-management/device-management/approval',
|
||||||
|
@ -235,10 +249,10 @@ const storeSetup = () => {
|
||||||
isExternal: false,
|
isExternal: false,
|
||||||
isCache: false,
|
isCache: false,
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
sort: 3,
|
sort: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2014,
|
id: 2015,
|
||||||
parentId: 2010,
|
parentId: 2010,
|
||||||
title: '在线管理',
|
title: '在线管理',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
@ -250,11 +264,11 @@ const storeSetup = () => {
|
||||||
isExternal: false,
|
isExternal: false,
|
||||||
isCache: false,
|
isCache: false,
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
sort: 4,
|
sort: 5,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 20141,
|
id: 20151,
|
||||||
parentId: 2014,
|
parentId: 2015,
|
||||||
title: '无人机',
|
title: '无人机',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/online/drone',
|
path: '/asset-management/device-management/online/drone',
|
||||||
|
@ -267,8 +281,8 @@ const storeSetup = () => {
|
||||||
sort: 1,
|
sort: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 20142,
|
id: 20152,
|
||||||
parentId: 2014,
|
parentId: 2015,
|
||||||
title: '机巢',
|
title: '机巢',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/online/nest',
|
path: '/asset-management/device-management/online/nest',
|
||||||
|
@ -281,8 +295,8 @@ const storeSetup = () => {
|
||||||
sort: 2,
|
sort: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 20143,
|
id: 20153,
|
||||||
parentId: 2014,
|
parentId: 2015,
|
||||||
title: '其他智能终端',
|
title: '其他智能终端',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/online/smart-terminal',
|
path: '/asset-management/device-management/online/smart-terminal',
|
||||||
|
@ -297,7 +311,7 @@ const storeSetup = () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2015,
|
id: 2016,
|
||||||
parentId: 2010,
|
parentId: 2010,
|
||||||
title: '设备详情',
|
title: '设备详情',
|
||||||
type: 2,
|
type: 2,
|
||||||
|
@ -308,7 +322,7 @@ const storeSetup = () => {
|
||||||
isExternal: false,
|
isExternal: false,
|
||||||
isCache: false,
|
isCache: false,
|
||||||
isHidden: true,
|
isHidden: true,
|
||||||
sort: 5,
|
sort: 6,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,6 +7,7 @@ export {}
|
||||||
|
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
CircularProgress: typeof import('./../components/CircularProgress/index.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
title="设备类型管理"
|
||||||
|
width="600px"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-item label="类型名称" field="typeName" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.typeName"
|
||||||
|
placeholder="请输入设备类型名称"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="类型编码" field="typeCode" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.typeCode"
|
||||||
|
placeholder="请输入设备类型编码"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="20"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="类型描述" field="description">
|
||||||
|
<a-textarea
|
||||||
|
v-model="formData.description"
|
||||||
|
placeholder="请输入设备类型描述"
|
||||||
|
:rows="4"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="200"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="排序" field="sort">
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.sort"
|
||||||
|
placeholder="请输入排序值"
|
||||||
|
:min="0"
|
||||||
|
:max="999"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="状态" field="status">
|
||||||
|
<a-select
|
||||||
|
v-model="formData.status"
|
||||||
|
placeholder="请选择状态"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="1">启用</a-option>
|
||||||
|
<a-option value="0">禁用</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import type { FormInstance } from '@arco-design/web-vue'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
typeData?: any
|
||||||
|
mode: 'add' | 'edit'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FormDataType {
|
||||||
|
typeName: string
|
||||||
|
typeCode: string
|
||||||
|
description: string
|
||||||
|
sort: number
|
||||||
|
status: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
visible: false,
|
||||||
|
typeData: null,
|
||||||
|
mode: 'add',
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:visible': [value: boolean]
|
||||||
|
'success': []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive<FormDataType>({
|
||||||
|
typeName: '',
|
||||||
|
typeCode: '',
|
||||||
|
description: '',
|
||||||
|
sort: 0,
|
||||||
|
status: '1'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
typeName: [
|
||||||
|
{ required: true, message: '请输入设备类型名称' },
|
||||||
|
{ min: 2, max: 50, message: '类型名称长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
typeCode: [
|
||||||
|
{ required: true, message: '请输入设备类型编码' },
|
||||||
|
{ min: 2, max: 20, message: '类型编码长度应在2-20个字符之间' },
|
||||||
|
{ pattern: /^[A-Z_]+$/, message: '类型编码只能包含大写字母和下划线' }
|
||||||
|
],
|
||||||
|
description: [
|
||||||
|
{ max: 200, message: '类型描述不能超过200个字符' }
|
||||||
|
],
|
||||||
|
sort: [
|
||||||
|
{ type: 'number', min: 0, max: 999, message: '排序值应在0-999之间' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听数据变化
|
||||||
|
watch(() => props.typeData, (newData) => {
|
||||||
|
if (newData) {
|
||||||
|
Object.assign(formData, {
|
||||||
|
typeName: newData.typeName || '',
|
||||||
|
typeCode: newData.typeCode || '',
|
||||||
|
description: newData.description || '',
|
||||||
|
sort: newData.sort || 0,
|
||||||
|
status: newData.status || '1'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// 监听弹窗显示状态
|
||||||
|
watch(() => props.visible, (visible) => {
|
||||||
|
if (visible && props.mode === 'add') {
|
||||||
|
// 新增模式时重置表单
|
||||||
|
Object.assign(formData, {
|
||||||
|
typeName: '',
|
||||||
|
typeCode: '',
|
||||||
|
description: '',
|
||||||
|
sort: 0,
|
||||||
|
status: '1'
|
||||||
|
})
|
||||||
|
formRef.value?.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
// 这里应该调用API保存数据
|
||||||
|
// 暂时模拟保存成功
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
|
|
||||||
|
Message.success(props.mode === 'add' ? '设备类型添加成功' : '设备类型更新成功')
|
||||||
|
emit('success')
|
||||||
|
emit('update:visible', false)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存失败:', error)
|
||||||
|
Message.error('保存失败,请检查表单信息')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input,
|
||||||
|
.arco-textarea,
|
||||||
|
.arco-select,
|
||||||
|
.arco-input-number {
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -19,6 +19,12 @@
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@reset="handleReset"
|
@reset="handleReset"
|
||||||
/>
|
/>
|
||||||
|
<a-button type="outline" @click="handleAddEquipmentType" size="large">
|
||||||
|
<template #icon>
|
||||||
|
<IconTag />
|
||||||
|
</template>
|
||||||
|
添加设备类型
|
||||||
|
</a-button>
|
||||||
<a-button type="primary" @click="handleAdd" size="large">
|
<a-button type="primary" @click="handleAdd" size="large">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<IconPlus />
|
<IconPlus />
|
||||||
|
@ -235,6 +241,14 @@
|
||||||
:mode="modalMode"
|
:mode="modalMode"
|
||||||
@success="handleModalSuccess"
|
@success="handleModalSuccess"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 设备类型管理弹窗 -->
|
||||||
|
<EquipmentTypeModal
|
||||||
|
v-model:visible="equipmentTypeModalVisible"
|
||||||
|
:type-data="currentEquipmentType"
|
||||||
|
:mode="equipmentTypeModalMode"
|
||||||
|
@success="handleEquipmentTypeModalSuccess"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -250,9 +264,11 @@ import {
|
||||||
IconPlus,
|
IconPlus,
|
||||||
IconRefresh,
|
IconRefresh,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
|
IconTag,
|
||||||
} from '@arco-design/web-vue/es/icon'
|
} from '@arco-design/web-vue/es/icon'
|
||||||
import message from '@arco-design/web-vue/es/message'
|
import message from '@arco-design/web-vue/es/message'
|
||||||
import DeviceModal from './components/DeviceModal.vue'
|
import DeviceModal from './components/DeviceModal.vue'
|
||||||
|
import EquipmentTypeModal from './components/EquipmentTypeModal.vue'
|
||||||
import EquipmentSearch from './components/EquipmentSearch.vue'
|
import EquipmentSearch from './components/EquipmentSearch.vue'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { EquipmentAPI } from '@/apis'
|
import { EquipmentAPI } from '@/apis'
|
||||||
|
@ -287,6 +303,11 @@ const modalVisible = ref(false)
|
||||||
const currentEquipment = ref<EquipmentResp | null>(null)
|
const currentEquipment = ref<EquipmentResp | null>(null)
|
||||||
const modalMode = ref<'add' | 'edit' | 'view'>('add')
|
const modalMode = ref<'add' | 'edit' | 'view'>('add')
|
||||||
|
|
||||||
|
// 设备类型弹窗控制
|
||||||
|
const equipmentTypeModalVisible = ref(false)
|
||||||
|
const currentEquipmentType = ref<any>(null)
|
||||||
|
const equipmentTypeModalMode = ref<'add' | 'edit'>('add')
|
||||||
|
|
||||||
// 表格列配置
|
// 表格列配置
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -913,6 +934,19 @@ const handleModalSuccess = () => {
|
||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增设备类型
|
||||||
|
const handleAddEquipmentType = () => {
|
||||||
|
equipmentTypeModalMode.value = 'add'
|
||||||
|
currentEquipmentType.value = null
|
||||||
|
equipmentTypeModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备类型弹窗成功回调
|
||||||
|
const handleEquipmentTypeModalSuccess = () => {
|
||||||
|
equipmentTypeModalVisible.value = false
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
// 监听表格数据变化
|
// 监听表格数据变化
|
||||||
watch(tableData, (_newData) => {
|
watch(tableData, (_newData) => {
|
||||||
// 数据变化监听
|
// 数据变化监听
|
||||||
|
|
|
@ -0,0 +1,330 @@
|
||||||
|
<template>
|
||||||
|
<div class="equipment-inventory">
|
||||||
|
<a-card title="设备盘库管理" :bordered="false">
|
||||||
|
<template #extra>
|
||||||
|
<a-button type="primary" @click="handleBatchInventory">
|
||||||
|
<template #icon>
|
||||||
|
<IconPlus />
|
||||||
|
</template>
|
||||||
|
批量盘库
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 搜索区域 -->
|
||||||
|
<div class="search-container">
|
||||||
|
<a-form layout="inline" :model="searchForm" class="search-form">
|
||||||
|
<a-form-item label="设备名称">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.equipmentName"
|
||||||
|
placeholder="请输入设备名称"
|
||||||
|
allow-clear
|
||||||
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="资产编号">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.assetCode"
|
||||||
|
placeholder="请输入资产编号"
|
||||||
|
allow-clear
|
||||||
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="设备类型">
|
||||||
|
<a-select
|
||||||
|
v-model="searchForm.equipmentType"
|
||||||
|
placeholder="请选择类型"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<a-option value="">全部</a-option>
|
||||||
|
<a-option value="COMPUTER">计算机设备</a-option>
|
||||||
|
<a-option value="NETWORK">网络设备</a-option>
|
||||||
|
<a-option value="STORAGE">存储设备</a-option>
|
||||||
|
<a-option value="SECURITY">安防设备</a-option>
|
||||||
|
<a-option value="OTHER">其他设备</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item>
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="search">
|
||||||
|
<template #icon><IconSearch /></template>
|
||||||
|
搜索
|
||||||
|
</a-button>
|
||||||
|
<a-button @click="reset">
|
||||||
|
<template #icon><IconRefresh /></template>
|
||||||
|
重置
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
:columns="columns"
|
||||||
|
:data="tableData"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination"
|
||||||
|
:row-selection="rowSelection"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
@page-size-change="handlePageSizeChange"
|
||||||
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<span class="search-result-info">
|
||||||
|
共找到 <strong>{{ pagination.total }}</strong> 条记录
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #equipmentStatus="{ record }">
|
||||||
|
<a-tag :color="getStatusColor(record.equipmentStatus)">
|
||||||
|
{{ getStatusText(record.equipmentStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #operations="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="text" size="small" @click="handleView(record)">
|
||||||
|
查看详情
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" size="small" @click="handleInventory(record)">
|
||||||
|
执行盘库
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import { IconSearch, IconRefresh, IconPlus } from '@arco-design/web-vue/es/icon'
|
||||||
|
import { pageEquipmentInventory } from '@/apis/equipment'
|
||||||
|
import type { EquipmentResp } from '@/types/equipment.d'
|
||||||
|
|
||||||
|
// 防抖函数
|
||||||
|
const debounce = (func: Function, delay: number) => {
|
||||||
|
let timeoutId: NodeJS.Timeout
|
||||||
|
return (...args: any[]) => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => func.apply(null, args), delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({ name: 'EquipmentInventory' })
|
||||||
|
|
||||||
|
// 表格列定义
|
||||||
|
const columns = [
|
||||||
|
{ title: '设备名称', dataIndex: 'equipmentName', key: 'equipmentName', width: 180 },
|
||||||
|
{ title: '资产编号', dataIndex: 'assetCode', key: 'assetCode', width: 150 },
|
||||||
|
{ title: '设备类型', dataIndex: 'equipmentType', key: 'equipmentType', width: 120 },
|
||||||
|
{ title: '品牌', dataIndex: 'brand', key: 'brand', width: 100 },
|
||||||
|
{ title: '型号', dataIndex: 'equipmentModel', key: 'equipmentModel', width: 120 },
|
||||||
|
{ title: '设备状态', dataIndex: 'equipmentStatus', key: 'equipmentStatus', slotName: 'equipmentStatus', width: 100 },
|
||||||
|
{ title: '负责人', dataIndex: 'responsiblePerson', key: 'responsiblePerson', width: 100 },
|
||||||
|
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
||||||
|
{ title: '操作', key: 'operations', slotName: 'operations', width: 200 }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
equipmentName: '',
|
||||||
|
assetCode: '',
|
||||||
|
equipmentType: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref<EquipmentResp[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
showTotal: true,
|
||||||
|
showJumper: true,
|
||||||
|
showPageSize: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格选择
|
||||||
|
const selectedRowKeys = ref<string[]>([])
|
||||||
|
const rowSelection = computed(() => ({
|
||||||
|
selectedRowKeys: selectedRowKeys.value,
|
||||||
|
onChange: (keys: string[]) => {
|
||||||
|
selectedRowKeys.value = keys
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
const colors: Record<string, string> = {
|
||||||
|
'IDLE': 'blue',
|
||||||
|
'IN_USE': 'green',
|
||||||
|
'MAINTENANCE': 'orange',
|
||||||
|
'REPAIR': 'red',
|
||||||
|
'SCRAPPED': 'gray'
|
||||||
|
}
|
||||||
|
return colors[status] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
const texts: Record<string, string> = {
|
||||||
|
'IDLE': '空闲中',
|
||||||
|
'IN_USE': '使用中',
|
||||||
|
'MAINTENANCE': '保养中',
|
||||||
|
'REPAIR': '维修中',
|
||||||
|
'SCRAPPED': '已报废'
|
||||||
|
}
|
||||||
|
return texts[status] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表格数据
|
||||||
|
const getTableData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await pageEquipmentInventory({
|
||||||
|
pageNum: pagination.current,
|
||||||
|
pageSize: pagination.pageSize,
|
||||||
|
equipmentName: searchForm.equipmentName || undefined,
|
||||||
|
assetCode: searchForm.assetCode || undefined,
|
||||||
|
equipmentType: searchForm.equipmentType || undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
// 检查响应数据结构
|
||||||
|
if (response.data && Array.isArray(response.data)) {
|
||||||
|
// 如果直接返回数组,说明没有分页信息
|
||||||
|
tableData.value = response.data
|
||||||
|
pagination.total = response.data.length
|
||||||
|
} else if (response.data && typeof response.data === 'object' && 'records' in response.data) {
|
||||||
|
// 如果有分页信息
|
||||||
|
const pageData = response.data as any
|
||||||
|
tableData.value = pageData.records || []
|
||||||
|
pagination.total = pageData.total || pageData.records?.length || 0
|
||||||
|
pagination.current = pageData.current || 1
|
||||||
|
} else {
|
||||||
|
tableData.value = []
|
||||||
|
pagination.total = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error('获取数据失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取设备盘库列表失败:', error)
|
||||||
|
Message.error('获取数据失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防抖搜索函数
|
||||||
|
const debouncedSearch = debounce(() => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const search = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const reset = () => {
|
||||||
|
Object.assign(searchForm, {
|
||||||
|
equipmentName: '',
|
||||||
|
assetCode: '',
|
||||||
|
equipmentType: ''
|
||||||
|
})
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情
|
||||||
|
const handleView = (record: EquipmentResp) => {
|
||||||
|
console.log('查看设备详情:', record)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行盘库
|
||||||
|
const handleInventory = (record: EquipmentResp) => {
|
||||||
|
console.log('执行设备盘库:', record)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量盘库
|
||||||
|
const handleBatchInventory = () => {
|
||||||
|
if (selectedRowKeys.value.length === 0) {
|
||||||
|
Message.warning('请先选择要盘库的设备')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('批量盘库设备:', selectedRowKeys.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页事件
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
pagination.current = page
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePageSizeChange = (pageSize: number) => {
|
||||||
|
pagination.pageSize = pageSize
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTableData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.equipment-inventory {
|
||||||
|
.arco-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
padding: 16px;
|
||||||
|
background: var(--color-bg-2);
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-right: 16px;
|
||||||
|
|
||||||
|
.arco-form-item-label {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input,
|
||||||
|
.arco-select {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-btn {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-info {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue