|
@@ -0,0 +1,745 @@
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { onMounted, reactive, ref } from 'vue'
|
|
|
|
|
+import { clientDownloadExcel, clientGet, clientPost } from '@/utils/request.ts'
|
|
|
|
|
+import type { FormInstance, UploadProps } from 'element-plus'
|
|
|
|
|
+import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
+import { Delete, Download, Edit, Plus, Refresh, Search, Upload } from '@element-plus/icons-vue'
|
|
|
|
|
+
|
|
|
|
|
+interface Property {
|
|
|
|
|
+ id: string // 主键
|
|
|
|
|
+ assetCode?: string // 主资产编号
|
|
|
|
|
+ assetName?: string // 主资产名称
|
|
|
|
|
+ roomNumber?: string // 主房间号/厂房编号
|
|
|
|
|
+ equipmentName?: string // 设备名称
|
|
|
|
|
+ equipmentType?: string // 设备类型编码
|
|
|
|
|
+ modelNumber?: string // 设备型号
|
|
|
|
|
+ serialNumber?: string // 设备序列号
|
|
|
|
|
+ purchaseDate?: string // 采购日期 (改为string)
|
|
|
|
|
+ purchasePrice?: number // 采购价格
|
|
|
|
|
+ installationDate?: string // 安装启用日期 (改为string)
|
|
|
|
|
+ installationLocation?: string // 安装位置
|
|
|
|
|
+ manufacturer?: string // 生产厂家
|
|
|
|
|
+ warrantyPeriod?: number // 质保期限(月)
|
|
|
|
|
+ warrantyEndDate?: string // 质保到期日 (改为string)
|
|
|
|
|
+ maintenanceCycle?: number // 维护周期(月)
|
|
|
|
|
+ currentStatus?: string // 设备状态
|
|
|
|
|
+ lastMaintenanceDate?: string // 上次维护日期 (改为string)
|
|
|
|
|
+ nextMaintenanceDate?: string // 下次维护提醒日期 (改为string)
|
|
|
|
|
+ maintenanceCost?: number // 累计维护费用
|
|
|
|
|
+ repairRecord?: string // 维修记录摘要
|
|
|
|
|
+ operator?: string // 当前操作人员
|
|
|
|
|
+ remark?: string // 其他备注信息
|
|
|
|
|
+ createTime?: Date // 记录创建时间 (保持Date,仅用于显示)
|
|
|
|
|
+ createBy?: string // 创建人
|
|
|
|
|
+ updateTime?: Date // 最后更新时间 (保持Date,仅用于显示)
|
|
|
|
|
+ updateBy?: string // 修改人
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface PropertyOneResponse extends BaseResponse {
|
|
|
|
|
+ data: Property
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface PropertyListResponse extends BaseResponse {
|
|
|
|
|
+ data: PageType<Property>
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface AddProperty {
|
|
|
|
|
+ assetCode?: string // 主资产编号
|
|
|
|
|
+ assetName?: string // 主资产名称
|
|
|
|
|
+ roomNumber?: string // 主房间号/厂房编号
|
|
|
|
|
+ equipmentName?: string // 设备名称
|
|
|
|
|
+ equipmentType?: string // 设备类型编码
|
|
|
|
|
+ modelNumber?: string // 设备型号
|
|
|
|
|
+ serialNumber?: string // 设备序列号
|
|
|
|
|
+ purchaseDate?: string // 采购日期 (改为string)
|
|
|
|
|
+ purchasePrice?: number // 采购价格
|
|
|
|
|
+ installationDate?: string // 安装启用日期 (改为string)
|
|
|
|
|
+ installationLocation?: string // 安装位置
|
|
|
|
|
+ manufacturer?: string // 生产厂家
|
|
|
|
|
+ warrantyPeriod?: number // 质保期限(月)
|
|
|
|
|
+ warrantyEndDate?: string // 质保到期日 (改为string)
|
|
|
|
|
+ maintenanceCycle?: number // 维护周期(月)
|
|
|
|
|
+ currentStatus?: string // 设备状态
|
|
|
|
|
+ lastMaintenanceDate?: string // 上次维护日期 (改为string)
|
|
|
|
|
+ nextMaintenanceDate?: string // 下次维护提醒日期 (改为string)
|
|
|
|
|
+ maintenanceCost?: number // 累计维护费用
|
|
|
|
|
+ repairRecord?: string // 维修记录摘要
|
|
|
|
|
+ operator?: string // 当前操作人员
|
|
|
|
|
+ remark?: string // 其他备注信息
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface UpdateProperty {
|
|
|
|
|
+ id?: string
|
|
|
|
|
+ assetCode?: string // 主资产编号
|
|
|
|
|
+ assetName?: string // 主资产名称
|
|
|
|
|
+ roomNumber?: string // 主房间号/厂房编号
|
|
|
|
|
+ equipmentName?: string // 设备名称
|
|
|
|
|
+ equipmentType?: string // 设备类型编码
|
|
|
|
|
+ modelNumber?: string // 设备型号
|
|
|
|
|
+ serialNumber?: string // 设备序列号
|
|
|
|
|
+ purchaseDate?: string // 采购日期 (改为string)
|
|
|
|
|
+ purchasePrice?: number // 采购价格
|
|
|
|
|
+ installationDate?: string // 安装启用日期 (改为string)
|
|
|
|
|
+ installationLocation?: string // 安装位置
|
|
|
|
|
+ manufacturer?: string // 生产厂家
|
|
|
|
|
+ warrantyPeriod?: number // 质保期限(月)
|
|
|
|
|
+ warrantyEndDate?: string // 质保到期日 (改为string)
|
|
|
|
|
+ maintenanceCycle?: number // 维护周期(月)
|
|
|
|
|
+ currentStatus?: string // 设备状态
|
|
|
|
|
+ lastMaintenanceDate?: string // 上次维护日期 (改为string)
|
|
|
|
|
+ nextMaintenanceDate?: string // 下次维护提醒日期 (改为string)
|
|
|
|
|
+ maintenanceCost?: number // 累计维护费用
|
|
|
|
|
+ repairRecord?: string // 维修记录摘要
|
|
|
|
|
+ operator?: string // 当前操作人员
|
|
|
|
|
+ remark?: string // 其他备注信息
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Reactive state variables
|
|
|
|
|
+const tableData = ref<Property[]>([])
|
|
|
|
|
+const total = ref(0)
|
|
|
|
|
+const pageSize = ref(10)
|
|
|
|
|
+const pageNum = ref(1)
|
|
|
|
|
+
|
|
|
|
|
+const searchForm = reactive({
|
|
|
|
|
+ modelNumber: '',
|
|
|
|
|
+ equipmentType: '',
|
|
|
|
|
+ equipmentName: '',
|
|
|
|
|
+ assetCode: '',
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const dialogVisible = ref(false)
|
|
|
|
|
+const dialogTitle = ref('')
|
|
|
|
|
+const isEdit = ref(false)
|
|
|
|
|
+const formData = reactive<Property>({})
|
|
|
|
|
+const formRef = ref<FormInstance>()
|
|
|
|
|
+const selectedIds = ref<string[]>([])
|
|
|
|
|
+
|
|
|
|
|
+// Options for select dropdowns
|
|
|
|
|
+const equipmentTypeOptions = [
|
|
|
|
|
+ { label: '空调', value: '空调' },
|
|
|
|
|
+ { label: '电梯', value: '电梯' },
|
|
|
|
|
+ { label: '消防设备', value: '消防设备' },
|
|
|
|
|
+ { label: '监控系统', value: '监控系统' },
|
|
|
|
|
+ { label: '照明设备', value: '照明设备' },
|
|
|
|
|
+ { label: '其他', value: '其他' },
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+const currentStatusOptions = [
|
|
|
|
|
+ { label: '正常运行', value: '正常运行' },
|
|
|
|
|
+ { label: '故障', value: '故障' },
|
|
|
|
|
+ { label: '维修中', value: '维修中' },
|
|
|
|
|
+ { label: '停用', value: '停用' },
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+// Helper to get label from value
|
|
|
|
|
+const getEquipmentTypeLabel = (value: string | undefined) => {
|
|
|
|
|
+ return equipmentTypeOptions.find((option) => option.value === value)?.label || '未知'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getCurrentStatusLabel = (value: string | undefined) => {
|
|
|
|
|
+ return currentStatusOptions.find((option) => option.value === value)?.label || '未知'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//新增
|
|
|
|
|
+const add = async (data: AddProperty) => {
|
|
|
|
|
+ const res = await clientPost<AddProperty, BaseResponse>('/aequipmentManagement/save', {
|
|
|
|
|
+ ...data,
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//根据id获取数据
|
|
|
|
|
+const getById = async (id: string) => {
|
|
|
|
|
+ const res = await clientGet<null, PropertyOneResponse>('/aequipmentManagement/getById/' + id)
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ return res.data
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//分页获取数据
|
|
|
|
|
+const getList = async () => {
|
|
|
|
|
+ const res = await clientGet<
|
|
|
|
|
+ {
|
|
|
|
|
+ pageNum: number
|
|
|
|
|
+ pageSize: number
|
|
|
|
|
+ modelNumber?: string
|
|
|
|
|
+ equipmentType?: string
|
|
|
|
|
+ equipmentName?: string
|
|
|
|
|
+ assetCode?: string
|
|
|
|
|
+ },
|
|
|
|
|
+ PropertyListResponse
|
|
|
|
|
+ >('/aequipmentManagement/findByPage', {
|
|
|
|
|
+ params: {
|
|
|
|
|
+ pageNum: pageNum.value,
|
|
|
|
|
+ pageSize: pageSize.value,
|
|
|
|
|
+ modelNumber: searchForm.modelNumber || undefined,
|
|
|
|
|
+ equipmentType: searchForm.equipmentType || undefined,
|
|
|
|
|
+ equipmentName: searchForm.equipmentName || undefined,
|
|
|
|
|
+ assetCode: searchForm.assetCode || undefined,
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ tableData.value = res.data.records
|
|
|
|
|
+ total.value = res.data.total
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//批量删除
|
|
|
|
|
+const delBatch = async (ids: string[]) => {
|
|
|
|
|
+ const res = await clientPost<string[], BaseResponse>('/aequipmentManagement/deleteBatch', ids)
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//修改
|
|
|
|
|
+const update = async (data: UpdateProperty) => {
|
|
|
|
|
+ const res = await clientPost<UpdateProperty, BaseResponse>('/aequipmentManagement/update', {
|
|
|
|
|
+ ...data,
|
|
|
|
|
+ })
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//导出为excel
|
|
|
|
|
+const exportExcel = async () => {
|
|
|
|
|
+ const loading = ElLoading.service({
|
|
|
|
|
+ lock: true,
|
|
|
|
|
+ text: '导出中,请稍候...',
|
|
|
|
|
+ background: 'rgba(0, 0, 0, 0.1)',
|
|
|
|
|
+ fullscreen: true,
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ await clientDownloadExcel('/aequipmentManagement/exportData', {
|
|
|
|
|
+ params: {
|
|
|
|
|
+ equipmentName: searchForm.equipmentName || undefined,
|
|
|
|
|
+ assetCode: searchForm.assetCode || undefined,
|
|
|
|
|
+ equipmentType: searchForm.equipmentType || undefined,
|
|
|
|
|
+ modelNumber: searchForm.modelNumber || undefined,
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ ElMessage.success('导出成功')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('导出失败:', error)
|
|
|
|
|
+ ElMessage.error('导出失败')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.close()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//excel导入
|
|
|
|
|
+const importExcel = async (file: File) => {
|
|
|
|
|
+ const formData = new FormData()
|
|
|
|
|
+ formData.append('file', file)
|
|
|
|
|
+ const res = await clientPost<FormData, BaseResponse>(
|
|
|
|
|
+ '/aequipmentManagement/importData',
|
|
|
|
|
+ formData,
|
|
|
|
|
+ {
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ 'Content-Type': 'multipart/form-data',
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+ if (res.code !== 200) {
|
|
|
|
|
+ ElMessage.error(res.msg)
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessage.success(res.msg)
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// --- CRUD Operations and Handlers ---
|
|
|
|
|
+
|
|
|
|
|
+const handleAdd = () => {
|
|
|
|
|
+ isEdit.value = false
|
|
|
|
|
+ dialogTitle.value = '新增设备信息'
|
|
|
|
|
+ // Reset form data
|
|
|
|
|
+ Object.keys(formData).forEach((key) => delete formData[key as keyof Property])
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleEdit = async (row: Property) => {
|
|
|
|
|
+ isEdit.value = true
|
|
|
|
|
+ dialogTitle.value = '编辑设备信息'
|
|
|
|
|
+ const data = await getById(row.id)
|
|
|
|
|
+ if (data) {
|
|
|
|
|
+ Object.assign(formData, data)
|
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleDelete = async (id: string) => {
|
|
|
|
|
+ ElMessageBox.confirm('确定删除此条记录吗?', '提示', {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(async () => {
|
|
|
|
|
+ const success = await delBatch([id])
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ ElMessage.info('已取消删除')
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleBatchDelete = () => {
|
|
|
|
|
+ if (selectedIds.value.length === 0) {
|
|
|
|
|
+ ElMessage.warning('请选择要删除的记录')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ ElMessageBox.confirm(`确定删除选中的 ${selectedIds.value.length} 条记录吗?`, '提示', {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(async () => {
|
|
|
|
|
+ const success = await delBatch(selectedIds.value)
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ ElMessage.info('已取消批量删除')
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSearch = () => {
|
|
|
|
|
+ pageNum.value = 1 // Reset to first page on search
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleResetSearch = () => {
|
|
|
|
|
+ searchForm.modelNumber = ''
|
|
|
|
|
+ searchForm.equipmentType = ''
|
|
|
|
|
+ searchForm.equipmentName = ''
|
|
|
|
|
+ searchForm.assetCode = ''
|
|
|
|
|
+ pageNum.value = 1
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleConfirm = async () => {
|
|
|
|
|
+ if (!formRef.value) return
|
|
|
|
|
+ await formRef.value.validate(async (valid) => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ let success = false
|
|
|
|
|
+ const dataToSend = { ...formData }
|
|
|
|
|
+
|
|
|
|
|
+ // Date fields are already strings from el-date-picker due to value-format
|
|
|
|
|
+ // No further formatting needed here.
|
|
|
|
|
+
|
|
|
|
|
+ if (isEdit.value) {
|
|
|
|
|
+ success = await update(dataToSend)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ success = await add(dataToSend)
|
|
|
|
|
+ }
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ dialogVisible.value = false
|
|
|
|
|
+ getList()
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('请检查表单填写')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleCurrentChange = (val: number) => {
|
|
|
|
|
+ pageNum.value = val
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSizeChange = (val: number) => {
|
|
|
|
|
+ pageSize.value = val
|
|
|
|
|
+ pageNum.value = 1 // Reset to first page when page size changes
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleSelectionChange = (selection: Property[]) => {
|
|
|
|
|
+ selectedIds.value = selection.map((item) => item.id)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleUploadSuccess: UploadProps['onSuccess'] = async (response, uploadFile) => {
|
|
|
|
|
+ if (response) {
|
|
|
|
|
+ ElMessage.success('文件导入成功')
|
|
|
|
|
+ getList()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(`文件导入失败: ${response?.msg || '未知错误'}`)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleUploadError: UploadProps['onError'] = (error) => {
|
|
|
|
|
+ ElMessage.error(`文件导入失败: ${error.message}`)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleBeforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
|
|
|
|
+ const isExcel =
|
|
|
|
|
+ rawFile.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
|
|
|
|
|
+ rawFile.type === 'application/vnd.ms-excel'
|
|
|
|
|
+ if (!isExcel) {
|
|
|
|
|
+ ElMessage.error('导入文件只能是 Excel 格式!')
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const init = () => {
|
|
|
|
|
+ getList()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ init()
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="p-4">
|
|
|
|
|
+ <h1 class="text-2xl font-bold mb-6">资产附属设施管理</h1>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Search and Action Bar -->
|
|
|
|
|
+ <div class="mb-6 p-4 bg-white rounded-lg shadow-sm flex flex-wrap items-center gap-4">
|
|
|
|
|
+ <el-form :inline="true" :model="searchForm" class="flex-grow flex flex-wrap gap-x-4">
|
|
|
|
|
+ <el-form-item label="资产编号">
|
|
|
|
|
+ <el-input v-model="searchForm.assetCode" placeholder="请输入资产编号" clearable />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备名称">
|
|
|
|
|
+ <el-input v-model="searchForm.equipmentName" placeholder="请输入设备名称" clearable />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备类型">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ style="width: 150px"
|
|
|
|
|
+ v-model="searchForm.equipmentType"
|
|
|
|
|
+ placeholder="请选择设备类型"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in equipmentTypeOptions"
|
|
|
|
|
+ :key="item.value"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :value="item.value"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备型号">
|
|
|
|
|
+ <el-input v-model="searchForm.modelNumber" placeholder="请输入设备型号" clearable />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item>
|
|
|
|
|
+ <el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
|
|
|
|
|
+ <el-button :icon="Refresh" @click="handleResetSearch">重置</el-button>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="flex gap-2">
|
|
|
|
|
+ <el-button type="primary" :icon="Plus" @click="handleAdd">新增</el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ :icon="Delete"
|
|
|
|
|
+ @click="handleBatchDelete"
|
|
|
|
|
+ :disabled="selectedIds.length === 0"
|
|
|
|
|
+ >批量删除</el-button
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-button type="success" :icon="Download" @click="exportExcel">导出</el-button>
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ class="inline-block ml-2"
|
|
|
|
|
+ action="/api/aequipmentManagement/importData"
|
|
|
|
|
+ :show-file-list="false"
|
|
|
|
|
+ :on-success="handleUploadSuccess"
|
|
|
|
|
+ :on-error="handleUploadError"
|
|
|
|
|
+ :before-upload="handleBeforeUpload"
|
|
|
|
|
+ :http-request="(options) => importExcel(options.file)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-button type="info" :icon="Upload">导入</el-button>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Table -->
|
|
|
|
|
+ <div class="bg-white rounded-lg shadow-sm p-4 overflow-x-auto">
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ :data="tableData"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ border
|
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column type="selection" width="55" fixed="left" />
|
|
|
|
|
+ <el-table-column prop="assetCode" label="主资产编号" width="120" />
|
|
|
|
|
+ <el-table-column prop="assetName" label="主资产名称" width="150" />
|
|
|
|
|
+ <el-table-column prop="roomNumber" label="主房间号/厂房编号" width="180" />
|
|
|
|
|
+ <el-table-column prop="equipmentName" label="设备名称" width="150" />
|
|
|
|
|
+ <el-table-column prop="equipmentType" label="设备类型" width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ getEquipmentTypeLabel(row.equipmentType) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="modelNumber" label="设备型号" width="120" />
|
|
|
|
|
+ <el-table-column prop="serialNumber" label="设备序列号" width="150" />
|
|
|
|
|
+ <el-table-column prop="purchaseDate" label="采购日期" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.purchaseDate ? new Date(row.purchaseDate).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="purchasePrice" label="采购价格(元)" width="120" />
|
|
|
|
|
+ <el-table-column prop="installationDate" label="安装启用日期" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.installationDate ? new Date(row.installationDate).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="installationLocation" label="安装位置" width="150" />
|
|
|
|
|
+ <el-table-column prop="manufacturer" label="生产厂家" width="150" />
|
|
|
|
|
+ <el-table-column prop="warrantyPeriod" label="质保期限(月)" width="120" />
|
|
|
|
|
+ <el-table-column prop="warrantyEndDate" label="质保到期日" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.warrantyEndDate ? new Date(row.warrantyEndDate).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="maintenanceCycle" label="维护周期(月)" width="120" />
|
|
|
|
|
+ <el-table-column prop="currentStatus" label="设备状态" width="100">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ getCurrentStatusLabel(row.currentStatus) }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="lastMaintenanceDate" label="上次维护日期" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.lastMaintenanceDate ? new Date(row.lastMaintenanceDate).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="nextMaintenanceDate" label="下次维护提醒日期" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.nextMaintenanceDate ? new Date(row.nextMaintenanceDate).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="maintenanceCost" label="累计维护费用(元)" width="150" />
|
|
|
|
|
+ <el-table-column prop="repairRecord" label="维修记录摘要" width="200" />
|
|
|
|
|
+ <el-table-column prop="operator" label="当前操作人员" width="120" />
|
|
|
|
|
+ <el-table-column prop="remark" label="其他备注信息" width="200" />
|
|
|
|
|
+ <el-table-column prop="createTime" label="记录创建时间" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.createTime ? new Date(row.createTime).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="updateTime" label="最后更新时间" width="180">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.updateTime ? new Date(row.updateTime).toLocaleString() : '-' }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="操作" width="150" fixed="right">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <el-button :icon="Edit" size="small" @click="handleEdit(row)">编辑</el-button>
|
|
|
|
|
+ <el-button type="danger" :icon="Delete" size="small" @click="handleDelete(row.id)"
|
|
|
|
|
+ >删除</el-button
|
|
|
|
|
+ >
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Pagination -->
|
|
|
|
|
+ <div class="mt-4 flex justify-end">
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ @size-change="handleSizeChange"
|
|
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
|
|
+ :current-page="pageNum"
|
|
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
|
|
+ :page-size="pageSize"
|
|
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
+ :total="total"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Add/Edit Dialog -->
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ v-model="dialogVisible"
|
|
|
|
|
+ :title="dialogTitle"
|
|
|
|
|
+ width="1200px"
|
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
|
+ :close-on-press-escape="false"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ :model="formData"
|
|
|
|
|
+ ref="formRef"
|
|
|
|
|
+ label-width="150px"
|
|
|
|
|
+ class="grid grid-cols-2 md:grid-cols-3 gap-4"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form-item label="主资产编号" prop="assetCode">
|
|
|
|
|
+ <el-input v-model="formData.assetCode" placeholder="请输入主资产编号" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="主资产名称" prop="assetName">
|
|
|
|
|
+ <el-input v-model="formData.assetName" placeholder="请输入主资产名称" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="主房间号/厂房编号" prop="roomNumber">
|
|
|
|
|
+ <el-input v-model="formData.roomNumber" placeholder="请输入主房间号或厂房编号" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item
|
|
|
|
|
+ label="设备名称"
|
|
|
|
|
+ prop="equipmentName"
|
|
|
|
|
+ :rules="[{ required: true, message: '请输入设备名称', trigger: 'blur' }]"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-input v-model="formData.equipmentName" placeholder="请输入设备名称" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备类型" prop="equipmentType">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="formData.equipmentType"
|
|
|
|
|
+ placeholder="请选择设备类型"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in equipmentTypeOptions"
|
|
|
|
|
+ :key="item.value"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :value="item.value"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备型号" prop="modelNumber">
|
|
|
|
|
+ <el-input v-model="formData.modelNumber" placeholder="请输入设备型号" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备序列号" prop="serialNumber">
|
|
|
|
|
+ <el-input v-model="formData.serialNumber" placeholder="请输入设备序列号" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="采购日期" prop="purchaseDate">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.purchaseDate"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择采购日期时间"
|
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="采购价格(元)" prop="purchasePrice">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="formData.purchasePrice"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :precision="2"
|
|
|
|
|
+ :step="100"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="安装启用日期" prop="installationDate">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.installationDate"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择安装启用日期时间"
|
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="安装位置" prop="installationLocation">
|
|
|
|
|
+ <el-input v-model="formData.installationLocation" placeholder="请输入安装位置" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="生产厂家" prop="manufacturer">
|
|
|
|
|
+ <el-input v-model="formData.manufacturer" placeholder="请输入生产厂家" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="质保期限(月)" prop="warrantyPeriod">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="formData.warrantyPeriod"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :step="1"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="质保到期日" prop="warrantyEndDate">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.warrantyEndDate"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择质保到期日期时间"
|
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="维护周期(月)" prop="maintenanceCycle">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="formData.maintenanceCycle"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :step="1"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备状态" prop="currentStatus">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="formData.currentStatus"
|
|
|
|
|
+ placeholder="请选择设备状态"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in currentStatusOptions"
|
|
|
|
|
+ :key="item.value"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :value="item.value"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="上次维护日期" prop="lastMaintenanceDate">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.lastMaintenanceDate"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择上次维护日期时间"
|
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="下次维护提醒日期" prop="nextMaintenanceDate">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="formData.nextMaintenanceDate"
|
|
|
|
|
+ type="datetime"
|
|
|
|
|
+ placeholder="选择下次维护提醒日期时间"
|
|
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="累计维护费用(元)" prop="maintenanceCost">
|
|
|
|
|
+ <el-input-number
|
|
|
|
|
+ v-model="formData.maintenanceCost"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ :precision="2"
|
|
|
|
|
+ :step="10"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="维修记录摘要" prop="repairRecord" class="md:col-span-2">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="formData.repairRecord"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ placeholder="请输入维修记录摘要"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="当前操作人员" prop="operator">
|
|
|
|
|
+ <el-input v-model="formData.operator" placeholder="请输入当前操作人员" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="其他备注信息" prop="remark" class="md:col-span-2">
|
|
|
|
|
+ <el-input v-model="formData.remark" type="textarea" placeholder="请输入其他备注信息" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <span class="dialog-footer">
|
|
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="handleConfirm">确定</el-button>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+/* Add any specific styles here if needed, otherwise UnoCSS handles most */
|
|
|
|
|
+</style>
|