273 lines
9.1 KiB
Vue

<template>
<div class="asset-detail-container" v-loading="loading">
<el-tabs v-model="activeTab">
<el-tab-pane label="基础信息" name="basic">
<el-descriptions class="margin-top" title="资产基础信息" :column="3" border>
<el-descriptions-item label="资产编码">{{ assetDetail.assetCode || assetDetail.code }}</el-descriptions-item>
<el-descriptions-item label="资产分类">{{ getClassificationName(assetDetail.classificationId) }}</el-descriptions-item>
<el-descriptions-item label="资产名称">{{ assetDetail.assetName || assetDetail.name }}</el-descriptions-item>
<el-descriptions-item label="资产状态">
<el-tag :type="getStatusType(assetDetail.assetStatus || assetDetail.status)">{{ getStatusText(assetDetail.assetStatus || assetDetail.status) }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="品牌">{{ assetDetail.brand }}</el-descriptions-item>
<el-descriptions-item label="型号">{{ assetDetail.model }}</el-descriptions-item>
<el-descriptions-item label="设备序列号">{{ assetDetail.serialNumber }}</el-descriptions-item>
<el-descriptions-item label="管理员">{{ assetDetail.administratorName }}</el-descriptions-item>
<el-descriptions-item label="所属公司">{{ assetDetail.companyName }}</el-descriptions-item>
<el-descriptions-item label="所在位置">{{ getLocationName(assetDetail.locationId) }}</el-descriptions-item>
<el-descriptions-item label="购置方式">
{{ assetDetail.purchaseType === '1' ? '采购' : assetDetail.purchaseType === '2' ? '租赁' : '-' }}
</el-descriptions-item>
<el-descriptions-item label="购置金额(含税)">{{ assetDetail.purchaseAmount }}</el-descriptions-item>
<el-descriptions-item label="购置时间">{{ assetDetail.purchaseDate || assetDetail.purchaseTime }}</el-descriptions-item>
<el-descriptions-item label="入库时间">{{ assetDetail.storageDate || assetDetail.storageTime }}</el-descriptions-item>
<el-descriptions-item label="预计使用期限(月)">{{ assetDetail.expectedUsePeriod || assetDetail.expectedDepreciationPeriod }}</el-descriptions-item>
<el-descriptions-item label="预计折旧期限(月)">{{ assetDetail.expectedDepreciationPeriod }}</el-descriptions-item>
<el-descriptions-item label="保养到期时间">{{ assetDetail.maintenanceDueDate || assetDetail.maintenanceTime }}</el-descriptions-item>
<el-descriptions-item label="保养说明" :span="3">{{ assetDetail.maintenanceDescription }}</el-descriptions-item>
<el-descriptions-item label="备注" :span="3">{{ assetDetail.remark }}</el-descriptions-item>
</el-descriptions>
<div class="image-section" v-if="assetDetail.imageUrl">
<div class="section-title">资产照片</div>
<div class="image-container">
<el-image
:src="assetDetail.imageUrl"
:preview-src-list="[assetDetail.imageUrl]"
fit="cover"
style="width: 300px; height: 200px; border-radius: 4px;">
</el-image>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import { getAsset } from '@/api/asset/inventory'
import { getClassificationTree } from '@/api/asset/classification'
import { getLocationTree } from '@/api/asset/location'
import { API_SUCCESS_CODE } from '@/utils/constants'
export default {
name: 'AssetDetail',
props: {
assetId: {
type: [String, Number],
required: true
}
},
data() {
return {
loading: false,
activeTab: 'basic',
assetDetail: {},
// 资产分类选项
classificationOptions: [],
// 资产位置选项
locationOptions: []
}
},
watch: {
assetId: {
handler(val) {
if (val) {
this.getAssetDetail()
}
},
immediate: true
}
},
created() {
this.getClassificationOptions()
this.getLocationOptions()
},
methods: {
/** 获取资产详情 */
getAssetDetail() {
if (!this.assetId) return
this.loading = true
getAsset(this.assetId).then(response => {
if (response.code === API_SUCCESS_CODE) {
this.assetDetail = response.data || {}
console.log('资产详情数据:', this.assetDetail)
} else {
this.$message.error(response.msg || '获取资产详情失败')
}
this.loading = false
}).catch(() => {
this.loading = false
})
},
/** 获取资产状态显示文本 */
getStatusText(status) {
const statusMap = {
'空闲': '空闲',
'在用': '在用',
'借用': '借用',
'派发中': '派发中',
'退库中': '退库中',
'借出中': '借出中',
'归还中': '归还中',
'维修中': '维修中'
}
return statusMap[status] || '未知'
},
/** 获取资产状态显示类型 */
getStatusType(status) {
const typeMap = {
'空闲': 'success',
'在用': 'primary',
'借用': 'info',
'派发中': 'warning',
'退库中': 'warning',
'借出中': 'warning',
'归还中': 'warning',
'维修中': 'danger'
}
return typeMap[status] || 'info'
},
/** 获取资产分类树形选项 */
getClassificationOptions() {
getClassificationTree({ status: '1' }).then(response => {
if (response.code === API_SUCCESS_CODE) {
this.classificationOptions = this.processClassificationTree(response.data || [])
}
})
},
/** 处理分类树形数据 */
processClassificationTree(data) {
if (!data || !Array.isArray(data)) return []
const processNode = (node) => {
const processedNode = {
id: node.id,
name: `${node.classificationCode || node.code || ''}-${node.classificationName || node.label || ''}`,
children: []
}
if (node.children && Array.isArray(node.children) && node.children.length > 0) {
processedNode.children = node.children.map(child => processNode(child))
}
return processedNode
}
return data.map(item => processNode(item))
},
/** 获取位置树选项 */
getLocationOptions() {
getLocationTree().then(response => {
if (response.code === API_SUCCESS_CODE) {
this.locationOptions = this.processLocationTree(response.data || [])
}
})
},
processLocationTree(data) {
if (!data || !Array.isArray(data)) return []
const processNode = (node) => {
const processedNode = {
id: node.id,
name: `${node.code || ''}-${node.locationName || node.label || ''}`,
children: []
}
if (node.children && Array.isArray(node.children) && node.children.length > 0) {
processedNode.children = node.children.map(child => processNode(child))
}
return processedNode
}
return data.map(item => processNode(item))
},
/** 获取分类名称 */
getClassificationName(classificationId) {
if (!classificationId) return '未知分类'
// 如果已有名称,直接返回
if (this.assetDetail.classificationName) return this.assetDetail.classificationName
// 递归查找分类
const findClassification = (items) => {
for (const item of items) {
if (item.id === classificationId) {
return item.name
}
if (item.children && item.children.length > 0) {
const found = findClassification(item.children)
if (found) return found
}
}
return null
}
const name = findClassification(this.classificationOptions)
return name || '未知分类'
},
/** 获取位置名称 */
getLocationName(locationId) {
if (!locationId) return '未知位置'
// 如果已有名称,直接返回
if (this.assetDetail.locationName) return this.assetDetail.locationName
// 递归查找位置
const findLocation = (items) => {
for (const item of items) {
if (item.id === locationId) {
return item.name
}
if (item.children && item.children.length > 0) {
const found = findLocation(item.children)
if (found) return found
}
}
return null
}
const name = findLocation(this.locationOptions)
return name || '未知位置'
}
}
}
</script>
<style lang="scss" scoped>
.asset-detail-container {
padding: 10px;
.margin-top {
margin-top: 15px;
}
.section-title {
font-size: 16px;
font-weight: 500;
margin: 20px 0 15px;
padding-left: 10px;
border-left: 3px solid #409EFF;
}
.image-section {
margin-top: 20px;
}
.image-container {
display: flex;
justify-content: center;
margin-top: 15px;
}
}
</style>