实现设备中心模块编辑,删除,查看详情,查看
This commit is contained in:
parent
1d16db937c
commit
543ab3d027
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
@ -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('已填充完整测试数据')
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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"
|
||||
<!-- 搜索组件 -->
|
||||
<EquipmentSearch
|
||||
:loading="loading"
|
||||
@search="handleSearch"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
</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>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<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)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue