实现设备中心模块编辑,删除,查看详情,查看

This commit is contained in:
Mr.j 2025-08-01 15:14:24 +08:00
parent 1d16db937c
commit 543ab3d027
6 changed files with 749 additions and 171 deletions

BIN
.env

Binary file not shown.

View File

@ -11,6 +11,18 @@ export interface EquipmentPageQuery {
useStatus?: string
projectId?: string
userId?: string
equipmentModel?: string
specification?: string
physicalLocation?: string
supplierName?: string
maintenancePerson?: string
inventoryBarcode?: string
assetRemark?: string
// 新增搜索字段
usingDepartment?: string
invoice?: string
barcode?: string
importer?: string
page?: number
pageSize?: number
orderBy?: string
@ -50,6 +62,26 @@ export interface EquipmentReq {
maintenancePerson?: string
inventoryBarcode?: string
assetRemark?: string
// 新增字段
usingDepartment?: string
borrowingTime?: string
returnTime?: string
outStockTime?: string
totalUsageTime?: string
depreciationRate?: number
depreciationMethodDesc?: string
invoice?: string
invoiceStatus?: string
attachments?: string
photos?: string
barcode?: string
importer?: string
inventoryTimeStatus1?: string
inventoryTimeStatus2?: string
inventoryTimeStatus3?: string
inventoryCheckTimeStatus1?: string
inventoryCheckTimeStatus2?: string
inventoryCheckTimeStatus3?: string
}
export interface EquipmentResp {
@ -90,6 +122,26 @@ export interface EquipmentResp {
maintenancePerson?: string
inventoryBarcode?: string
assetRemark?: string
// 新增字段
usingDepartment?: string
borrowingTime?: string
returnTime?: string
outStockTime?: string
totalUsageTime?: string
depreciationRate?: number
depreciationMethodDesc?: string
invoice?: string
invoiceStatus?: string
attachments?: string
photos?: string
barcode?: string
importer?: string
inventoryTimeStatus1?: string
inventoryTimeStatus2?: string
inventoryTimeStatus3?: string
inventoryCheckTimeStatus1?: string
inventoryCheckTimeStatus2?: string
inventoryCheckTimeStatus3?: string
projectId?: string
projectName?: string
userId?: string

View File

@ -30,7 +30,7 @@ const StatusCodeMessage: ICodeMessage = {
}
const http: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_PREFIX ?? import.meta.env.VITE_API_BASE_URL,
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 30 * 1000,
})

View File

@ -213,6 +213,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -224,6 +226,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -238,6 +242,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -249,6 +255,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -263,6 +271,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -274,6 +284,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -382,6 +394,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -407,6 +421,8 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
@ -418,6 +434,144 @@
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
</a-row>
</div>
<!-- 使用与盘点信息 -->
<div v-show="activeTab === 'usage'">
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="领用时间" field="borrowingTime">
<a-date-picker
v-model="formData.borrowingTime"
placeholder="请选择领用时间"
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="归还时间" field="returnTime">
<a-date-picker
v-model="formData.returnTime"
placeholder="请选择归还时间"
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="出库时间" field="outStockTime">
<a-date-picker
v-model="formData.outStockTime"
placeholder="请选择出库时间"
:disabled="isView"
style="width: 100%"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="折旧率" field="depreciationRate">
<a-input-number
v-model="formData.depreciationRate"
placeholder="请输入折旧率"
:disabled="isView"
style="width: 100%"
:precision="2"
:min="0"
:max="100"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="盘库时间/状态1" field="inventoryTimeStatus1">
<a-input
v-model="formData.inventoryTimeStatus1"
placeholder="请输入盘库时间/状态1"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="盘库时间/状态2" field="inventoryTimeStatus2">
<a-input
v-model="formData.inventoryTimeStatus2"
placeholder="请输入盘库时间/状态2"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="盘库时间/状态3" field="inventoryTimeStatus3">
<a-input
v-model="formData.inventoryTimeStatus3"
placeholder="请输入盘库时间/状态3"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="盘点时间/状态1" field="inventoryCheckTimeStatus1">
<a-input
v-model="formData.inventoryCheckTimeStatus1"
placeholder="请输入盘点时间/状态1"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="盘点时间/状态2" field="inventoryCheckTimeStatus2">
<a-input
v-model="formData.inventoryCheckTimeStatus2"
placeholder="请输入盘点时间/状态2"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="盘点时间/状态3" field="inventoryCheckTimeStatus3">
<a-input
v-model="formData.inventoryCheckTimeStatus3"
placeholder="请输入盘点时间/状态3"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
@ -436,6 +590,112 @@
:max-length="1000"
/>
</a-form-item>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="使用部门/人" field="usingDepartment">
<a-input
v-model="formData.usingDepartment"
placeholder="请输入使用部门/人"
:disabled="isView"
show-word-limit
:max-length="200"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="导入人" field="importer">
<a-input
v-model="formData.importer"
placeholder="请输入导入人"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="条码" field="barcode">
<a-input
v-model="formData.barcode"
placeholder="请输入条码"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="总使用时间" field="totalUsageTime">
<a-input
v-model="formData.totalUsageTime"
placeholder="请输入总使用时间"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="发票" field="invoice">
<a-input
v-model="formData.invoice"
placeholder="请输入发票"
:disabled="isView"
show-word-limit
:max-length="100"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="发票状态" field="invoiceStatus">
<a-input
v-model="formData.invoiceStatus"
placeholder="请输入发票状态"
:disabled="isView"
show-word-limit
:max-length="50"
/>
</a-form-item>
</a-col>
</a-row>
<a-form-item label="附件" field="attachments">
<a-input
v-model="formData.attachments"
placeholder="请输入附件"
:disabled="isView"
show-word-limit
:max-length="500"
/>
</a-form-item>
<a-form-item label="照片" field="photos">
<a-input
v-model="formData.photos"
placeholder="请输入照片"
:disabled="isView"
show-word-limit
:max-length="500"
/>
</a-form-item>
<a-form-item label="折旧方法说明" field="depreciationMethodDesc">
<a-textarea
v-model="formData.depreciationMethodDesc"
placeholder="请输入折旧方法说明"
:disabled="isView"
:rows="3"
show-word-limit
:max-length="500"
/>
</a-form-item>
</div>
</div>
</a-form>
@ -492,6 +752,7 @@ const tabs = [
{ key: 'time', label: '时间与金额' },
{ key: 'purchase', label: '采购及相关信息' },
{ key: 'maintenance', label: '维保与健康信息' },
{ key: 'usage', label: '使用与盘点信息' },
{ key: 'remark', label: '备注信息' },
]
@ -544,6 +805,27 @@ const formData = ref<FormDataType>({
//
assetRemark: '',
//
usingDepartment: '',
borrowingTime: '',
returnTime: '',
outStockTime: '',
totalUsageTime: '',
depreciationRate: undefined,
depreciationMethodDesc: '',
invoice: '',
invoiceStatus: '',
attachments: '',
photos: '',
barcode: '',
importer: '',
inventoryTimeStatus1: '',
inventoryTimeStatus2: '',
inventoryTimeStatus3: '',
inventoryCheckTimeStatus1: '',
inventoryCheckTimeStatus2: '',
inventoryCheckTimeStatus3: '',
})
//
@ -769,6 +1051,27 @@ const resetFormData = () => {
//
assetRemark: '',
//
usingDepartment: '',
borrowingTime: '',
returnTime: '',
outStockTime: '',
totalUsageTime: '',
depreciationRate: undefined,
depreciationMethodDesc: '',
invoice: '',
invoiceStatus: '',
attachments: '',
photos: '',
barcode: '',
importer: '',
inventoryTimeStatus1: '',
inventoryTimeStatus2: '',
inventoryTimeStatus3: '',
inventoryCheckTimeStatus1: '',
inventoryCheckTimeStatus2: '',
inventoryCheckTimeStatus3: '',
}
}
@ -841,6 +1144,27 @@ const handleSubmit = async () => {
maintenancePerson: formData.value.maintenancePerson?.trim(),
inventoryBarcode: formData.value.inventoryBarcode?.trim(),
assetRemark: formData.value.assetRemark?.trim(),
//
usingDepartment: formData.value.usingDepartment?.trim(),
borrowingTime: formData.value.borrowingTime,
returnTime: formData.value.returnTime,
outStockTime: formData.value.outStockTime,
totalUsageTime: formData.value.totalUsageTime?.trim(),
depreciationRate: formData.value.depreciationRate,
depreciationMethodDesc: formData.value.depreciationMethodDesc?.trim(),
invoice: formData.value.invoice?.trim(),
invoiceStatus: formData.value.invoiceStatus?.trim(),
attachments: formData.value.attachments?.trim(),
photos: formData.value.photos?.trim(),
barcode: formData.value.barcode?.trim(),
importer: formData.value.importer?.trim(),
inventoryTimeStatus1: formData.value.inventoryTimeStatus1?.trim(),
inventoryTimeStatus2: formData.value.inventoryTimeStatus2?.trim(),
inventoryTimeStatus3: formData.value.inventoryTimeStatus3?.trim(),
inventoryCheckTimeStatus1: formData.value.inventoryCheckTimeStatus1?.trim(),
inventoryCheckTimeStatus2: formData.value.inventoryCheckTimeStatus2?.trim(),
inventoryCheckTimeStatus3: formData.value.inventoryCheckTimeStatus3?.trim(),
}
// API
@ -917,6 +1241,27 @@ const fillTestData = () => {
//
assetRemark: '这是一台测试设备,用于系统功能验证和演示。设备性能良好,维护记录完整。',
//
usingDepartment: '技术部-张三',
borrowingTime: '2025-01-15 09:00:00',
returnTime: '',
outStockTime: '2025-01-15 09:00:00',
totalUsageTime: '120小时',
depreciationRate: 20.00,
depreciationMethodDesc: '直线折旧法年折旧率20%',
invoice: 'INV20250101001',
invoiceStatus: '已开具',
attachments: '设备说明书.pdf,保修卡.pdf',
photos: '设备正面.jpg,设备侧面.jpg',
barcode: 'BAR20250101001',
importer: '系统管理员',
inventoryTimeStatus1: '2025-01-01 已完成',
inventoryTimeStatus2: '2025-04-01 待盘点',
inventoryTimeStatus3: '2025-07-01 待盘点',
inventoryCheckTimeStatus1: '2025-01-01 已核对',
inventoryCheckTimeStatus2: '2025-04-01 待核对',
inventoryCheckTimeStatus3: '2025-07-01 待核对',
}
Message.success('已填充完整测试数据')
}

View File

@ -0,0 +1,230 @@
<template>
<div class="equipment-search-container">
<a-card class="search-card" :bordered="false">
<template #title>
<div class="search-title">
<IconSearch />
<span>设备搜索</span>
</div>
</template>
<a-form layout="inline" :model="searchForm" @submit="handleSearch">
<div class="search-row">
<a-form-item label="设备名称">
<a-input
v-model:value="searchForm.equipmentName"
placeholder="请输入设备名称"
allow-clear
style="width: 200px"
/>
</a-form-item>
<a-form-item label="设备类型">
<a-select
v-model:value="searchForm.equipmentType"
:options="equipmentTypeOptions"
placeholder="请选择设备类型"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="设备状态">
<a-select
v-model:value="searchForm.equipmentStatus"
:options="equipmentStatusOptions"
placeholder="请选择设备状态"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="位置状态">
<a-select
v-model:value="searchForm.locationStatus"
:options="locationStatusOptions"
placeholder="请选择位置状态"
allow-clear
style="width: 150px"
/>
</a-form-item>
</div>
<div class="search-row">
<a-form-item label="健康状态">
<a-select
v-model:value="searchForm.healthStatus"
:options="healthStatusOptions"
placeholder="请选择健康状态"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="使用部门/人">
<a-input
v-model:value="searchForm.usingDepartment"
placeholder="请输入使用部门/人"
allow-clear
style="width: 200px"
/>
</a-form-item>
<a-form-item label="发票">
<a-input
v-model:value="searchForm.invoice"
placeholder="请输入发票"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="条码">
<a-input
v-model:value="searchForm.barcode"
placeholder="请输入条码"
allow-clear
style="width: 150px"
/>
</a-form-item>
</div>
<div class="search-actions">
<a-button type="primary" html-type="submit" :loading="loading">
<template #icon>
<IconSearch />
</template>
搜索
</a-button>
<a-button style="margin-left: 8px" @click="handleReset">
<template #icon>
<IconRefresh />
</template>
重置
</a-button>
</div>
</a-form>
</a-card>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
import { IconRefresh, IconSearch } from '@arco-design/web-vue/es/icon'
import type { EquipmentPageQuery } from '@/types/equipment.d'
//
interface Props {
loading?: boolean
}
// eslint-disable-next-line unused-imports/no-unused-vars
const props = withDefaults(defineProps<Props>(), {
loading: false,
})
//
const emit = defineEmits<{
search: [params: EquipmentPageQuery]
reset: []
}>()
//
const searchForm = reactive<EquipmentPageQuery>({
equipmentName: '',
equipmentType: '',
equipmentStatus: '',
locationStatus: '',
healthStatus: '',
usingDepartment: '',
invoice: '',
barcode: '',
importer: '',
})
//
const equipmentTypeOptions = [
{ label: '计算机设备', value: 'computer' },
{ label: '网络设备', value: 'network' },
{ label: '存储设备', value: 'storage' },
{ label: '安全设备', value: 'security' },
{ label: '办公设备', value: 'office' },
{ label: '其他设备', value: 'other' },
]
const equipmentStatusOptions = [
{ label: '正常', value: 'normal' },
{ label: '维修中', value: 'repair' },
{ label: '报废', value: 'scrap' },
{ label: '闲置', value: 'idle' },
]
const locationStatusOptions = [
{ label: '在库', value: 'in_stock' },
{ label: '已分配', value: 'allocated' },
{ label: '外借中', value: 'borrowed' },
{ label: '维修中', value: 'repair' },
{ label: '已报废', value: 'scrapped' },
]
const healthStatusOptions = [
{ label: '良好', value: 'good' },
{ label: '一般', value: 'normal' },
{ label: '较差', value: 'poor' },
{ label: '故障', value: 'fault' },
]
//
const handleSearch = () => {
emit('search', { ...searchForm })
}
//
const handleReset = () => {
Object.keys(searchForm).forEach((key) => {
searchForm[key as keyof EquipmentPageQuery] = '' as any
})
emit('reset')
}
//
defineExpose({
reset: handleReset,
getSearchForm: () => ({ ...searchForm }),
})
</script>
<style lang="scss" scoped>
.equipment-search-container {
.search-card {
margin-bottom: 16px;
.search-title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
}
}
.search-row {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 16px;
.arco-form-item {
margin-bottom: 0;
flex: 0 0 auto;
}
}
.search-actions {
display: flex;
justify-content: center;
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid #f0f0f0;
}
}
</style>

View File

@ -1,68 +1,11 @@
<template>
<div class="equipment-center-container">
<!-- 搜索表单 -->
<a-card class="search-card" :bordered="false">
<a-form layout="inline" :model="searchForm" @submit="handleSearch">
<a-form-item label="设备名称">
<a-input
v-model:value="searchForm.equipmentName"
placeholder="请输入设备名称"
allow-clear
style="width: 200px"
/>
</a-form-item>
<a-form-item label="设备类型">
<a-select
v-model:value="searchForm.equipmentType"
:options="equipmentTypeOptions"
placeholder="请选择设备类型"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="设备状态">
<a-select
v-model:value="searchForm.equipmentStatus"
:options="equipmentStatusOptions"
placeholder="请选择设备状态"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="位置状态">
<a-select
v-model:value="searchForm.locationStatus"
:options="locationStatusOptions"
placeholder="请选择位置状态"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item label="健康状态">
<a-select
v-model:value="searchForm.healthStatus"
:options="healthStatusOptions"
placeholder="请选择健康状态"
allow-clear
style="width: 150px"
/>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit" :loading="loading">
<template #icon>
<IconSearch />
</template>
搜索
</a-button>
<a-button style="margin-left: 8px" @click="handleReset">
<template #icon>
<IconRefresh />
</template>
重置
</a-button>
</a-form-item>
</a-form>
</a-card>
<!-- 搜索组件 -->
<EquipmentSearch
:loading="loading"
@search="handleSearch"
@reset="handleReset"
/>
<!-- 操作按钮 -->
<a-card class="table-card" :bordered="false">
@ -189,6 +132,7 @@ import { Modal } from '@arco-design/web-vue'
import { IconPlus, IconRefresh, IconSearch } from '@arco-design/web-vue/es/icon'
import message from '@arco-design/web-vue/es/message'
import DeviceModal from './components/DeviceModal.vue'
import EquipmentSearch from './components/EquipmentSearch.vue'
import router from '@/router'
import {
assignEquipment,
@ -200,14 +144,7 @@ import type { EquipmentPageQuery, EquipmentResp } from '@/types/equipment.d'
defineOptions({ name: 'EquipmentCenter' })
//
const searchForm = reactive<EquipmentPageQuery>({
equipmentName: '',
equipmentType: '',
equipmentStatus: '',
locationStatus: '',
healthStatus: '',
})
//
//
const tableData = ref<EquipmentResp[]>([])
@ -356,42 +293,15 @@ const columns = [
]
//
const equipmentTypeOptions = [
{ label: '检测设备', value: '1' },
{ label: '安全设备', value: '2' },
{ label: '车辆', value: '3' },
]
const equipmentStatusOptions = [
{ label: '正常', value: 'normal' },
{ label: '维修中', value: 'maintenance' },
{ label: '报废', value: 'scrapped' },
]
const locationStatusOptions = [
{ label: '库存中', value: 'in_stock' },
{ label: '已分配', value: 'allocated' },
{ label: '维修中', value: 'repair' },
{ label: '待报废', value: 'scrap' },
{ label: '已报废', value: 'scrapped' },
{ label: '外借中', value: 'borrowed' },
{ label: '丢失', value: 'lost' },
]
const healthStatusOptions = [
{ label: '优秀', value: 'excellent' },
{ label: '良好', value: 'good' },
{ label: '一般', value: 'normal' },
{ label: '较差', value: 'poor' },
{ label: '差', value: 'bad' },
]
//
const getEquipmentTypeText = (type: string) => {
const typeMap: Record<string, string> = {
1: '检测设备',
2: '安全设备',
3: '车辆',
detection: '检测设备',
maintain: '维修设备',
security: '安全设备',
office: '办公设备',
car: '车辆',
}
return typeMap[type] || type
}
@ -399,9 +309,11 @@ const getEquipmentTypeText = (type: string) => {
//
const getEquipmentTypeColor = (type: string) => {
const colorMap: Record<string, string> = {
1: 'blue',
2: 'green',
3: 'orange',
detection: 'blue',
maintain: 'green',
security: 'orange',
office: 'purple',
car: 'red',
}
return colorMap[type] || 'default'
}
@ -410,8 +322,9 @@ const getEquipmentTypeColor = (type: string) => {
const getEquipmentStatusText = (status: string) => {
const statusMap: Record<string, string> = {
normal: '正常',
maintenance: '维修中',
scrapped: '报废',
repair: '维修中',
maintain: '保养中',
scrap: '报废',
}
return statusMap[status] || status
}
@ -420,8 +333,9 @@ const getEquipmentStatusText = (status: string) => {
const getEquipmentStatusColor = (status: string) => {
const colorMap: Record<string, string> = {
normal: 'green',
maintenance: 'orange',
scrapped: 'red',
repair: 'orange',
maintain: 'blue',
scrap: 'red',
}
return colorMap[status] || 'default'
}
@ -482,8 +396,9 @@ const getHealthStatusColor = (status: string) => {
const getStatusDotClass = (status: string) => {
const classMap: Record<string, string> = {
normal: 'normal-dot',
maintenance: 'maintenance-dot',
scrapped: 'scrapped-dot',
repair: 'maintenance-dot',
maintain: 'maintenance-dot',
scrap: 'scrapped-dot',
}
return classMap[status] || 'normal-dot'
}
@ -520,63 +435,55 @@ const transformBackendData = (data: any[]) => {
console.log('转换前的数据:', data)
return data.map((item) => {
console.log('处理单个项目:', item)
//
const formatDateTime = (dateTime: any) => {
if (!dateTime) return ''
try {
return new Date(dateTime).toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
})
// eslint-disable-next-line unused-imports/no-unused-vars
} catch (error) {
return dateTime
}
}
//
return {
equipmentId: item.equipmentId || item.id,
assetCode: item.assetCode,
equipmentName: item.equipmentName || item.name,
equipmentType: item.equipmentType || item.type,
equipmentTypeLabel: item.equipmentTypeLabel,
equipmentModel: item.equipmentModel || item.model,
equipmentSn: item.equipmentSn || item.sn,
brand: item.brand,
specification: item.specification,
equipmentStatus: item.equipmentStatus || item.status,
equipmentStatusLabel: item.equipmentStatusLabel,
useStatus: item.useStatus,
locationStatus: item.locationStatus,
locationStatusLabel: item.locationStatusLabel,
physicalLocation: item.physicalLocation,
responsiblePerson: item.responsiblePerson,
healthStatus: item.healthStatus,
healthStatusLabel: item.healthStatusLabel,
purchaseTime: item.purchaseTime,
inStockTime: item.inStockTime,
activationTime: item.activationTime,
expectedScrapTime: item.expectedScrapTime,
actualScrapTime: item.actualScrapTime,
statusChangeTime: item.statusChangeTime,
purchaseOrder: item.purchaseOrder,
supplierName: item.supplierName,
purchasePrice: item.purchasePrice,
currentNetValue: item.currentNetValue,
depreciationMethod: item.depreciationMethod,
depreciationYears: item.depreciationYears,
salvageValue: item.salvageValue,
warrantyExpireDate: item.warrantyExpireDate,
lastMaintenanceDate: item.lastMaintenanceDate,
nextMaintenanceDate: item.nextMaintenanceDate,
maintenancePerson: item.maintenancePerson,
inventoryBarcode: item.inventoryBarcode,
assetRemark: item.assetRemark,
projectId: item.projectId,
projectName: item.projectName,
userId: item.userId,
name: item.name,
createTime: item.createTime ? new Date(item.createTime).toLocaleString() : '',
updateTime: item.updateTime ? new Date(item.updateTime).toLocaleString() : '',
...item,
createTime: formatDateTime(item.createTime),
updateTime: formatDateTime(item.updateTime),
purchaseTime: formatDateTime(item.purchaseTime),
inStockTime: formatDateTime(item.inStockTime),
activationTime: formatDateTime(item.activationTime),
expectedScrapTime: formatDateTime(item.expectedScrapTime),
actualScrapTime: formatDateTime(item.actualScrapTime),
statusChangeTime: formatDateTime(item.statusChangeTime),
warrantyExpireDate: formatDateTime(item.warrantyExpireDate),
lastMaintenanceDate: formatDateTime(item.lastMaintenanceDate),
nextMaintenanceDate: formatDateTime(item.nextMaintenanceDate),
}
})
}
//
const loadData = async () => {
const loadData = async (searchParams?: EquipmentPageQuery) => {
loading.value = true
try {
const params = {
pageSize: pagination.pageSize,
page: pagination.current,
...searchForm, //
...(searchParams || {}), //
}
console.log('发送的请求参数:', params)
console.log('当前分页配置:', pagination)
const res = await pageEquipment(params)
console.log('API响应:', res)
@ -622,20 +529,13 @@ const loadData = async () => {
}
//
const handleSearch = () => {
const handleSearch = (searchParams: EquipmentPageQuery) => {
pagination.current = 1
loadData()
loadData(searchParams)
}
//
const handleReset = () => {
Object.assign(searchForm, {
equipmentName: '',
equipmentType: '',
equipmentStatus: '',
locationStatus: '',
healthStatus: '',
})
pagination.current = 1
loadData()
}
@ -712,17 +612,68 @@ const handleReturn = async (record: EquipmentResp) => {
//
const handleDelete = async (record: EquipmentResp) => {
//
let confirmContent = `确定要删除设备"${record.equipmentName}"吗?`
let canDelete = true
let statusWarning = ''
// 使
if (record.useStatus === '1') {
canDelete = false
statusWarning = '该设备正在使用中,无法删除。请先归还设备后再进行删除操作。'
}
//
if (record.locationStatus === 'allocated' || record.locationStatus === 'borrowed') {
canDelete = false
statusWarning = '该设备已分配或外借中,无法删除。请先归还设备后再进行删除操作。'
}
//
if (record.locationStatus === 'repair' || record.equipmentStatus === 'repair') {
canDelete = false
statusWarning = '该设备正在维修中,无法删除。请等待维修完成后再进行删除操作。'
}
//
if (!canDelete) {
Modal.warning({
title: '无法删除设备',
content: statusWarning,
okText: '确定',
hideCancel: true,
})
return
}
//
const deviceInfo = [
`设备名称:${record.equipmentName || '无'}`,
`资产编号:${record.assetCode || '无'}`,
`设备型号:${record.equipmentModel || '无'}`,
`序列号:${record.equipmentSn || '无'}`,
`当前状态:${getEquipmentStatusText(record.equipmentStatus || '')}`,
`位置状态:${getLocationStatusText(record.locationStatus || '')}`,
].join('\n')
confirmContent = `确定要删除以下设备吗?\n\n${deviceInfo}\n\n⚠ 删除后设备将被标记为已报废,此操作不可恢复!\n\n删除原因\n• 设备信息本身不可更改,但可以通过删除操作标记为报废\n• 删除后设备将不再出现在正常列表中\n• 历史记录将被保留,不影响其他模块功能`
Modal.confirm({
title: '确认删除',
content: `确定要删除设备"${record.equipmentName}"吗?此操作不可恢复!`,
title: '确认删除设备',
content: confirmContent,
okText: '确认删除',
cancelText: '取消',
okButtonProps: { status: 'danger' },
onOk: async () => {
try {
await deleteEquipment(record.equipmentId)
message.success('删除成功')
message.success('设备删除成功')
loadData()
} catch (error: any) {
console.error('删除失败:', error)
message.error(error?.message || '删除失败')
//
const errorMessage = error?.response?.data?.msg || error?.message || '删除失败'
message.error(errorMessage)
}
},
})