273 lines
9.1 KiB
Vue
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> |