|
|
|
|
@ -80,10 +80,16 @@
|
|
|
|
|
</ContentWrap>
|
|
|
|
|
|
|
|
|
|
<!-- 右侧产品表格 -->
|
|
|
|
|
<ContentWrap class="product-page-right">
|
|
|
|
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
|
|
|
|
<div class="product-page-right">
|
|
|
|
|
<ContentWrap>
|
|
|
|
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" :row-class-name="getRowClassName">
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.tableBarCodeColumn')" align="center" prop="barCode"
|
|
|
|
|
sortable />
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.dialogCategoryTypeLabel')" align="center" prop="categoryType" sortable>
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :type="DICT_TYPE.MATERIAL_CLASSIFICATION_TYPE" :value="scope.row.categoryType" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.tableNameColumn')" align="left" prop="name"
|
|
|
|
|
width="220px" sortable />
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.tableStandardColumn')" align="center"
|
|
|
|
|
@ -100,8 +106,11 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.tableCreateTimeColumn')" align="center"
|
|
|
|
|
prop="createTime" :formatter="dateFormatter" width="180px" sortable />
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.tableOperateColumn')" align="center" width="150px">
|
|
|
|
|
<el-table-column :label="t('FactoryModeling.ProductInformation.tableOperateColumn')" align="center" width="210px">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-button link type="primary" @click="handleShowDetail(scope.row.id)">
|
|
|
|
|
详情
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button link type="primary" @click="openForm('update', scope.row.id)" v-hasPermi="['erp:product:update']">
|
|
|
|
|
{{ t('FactoryModeling.ProductInformation.tableEditAction') }}
|
|
|
|
|
</el-button>
|
|
|
|
|
@ -111,10 +120,178 @@
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
|
|
|
|
|
@pagination="getList" />
|
|
|
|
|
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
|
|
|
|
|
@pagination="getList" />
|
|
|
|
|
</ContentWrap>
|
|
|
|
|
|
|
|
|
|
<ContentWrap v-if="detailVisible" class="product-detail-wrap" v-loading="detailLoading">
|
|
|
|
|
<template v-if="productDetail">
|
|
|
|
|
<div class="detail-header">
|
|
|
|
|
<div class="detail-title">物料详情</div>
|
|
|
|
|
<el-button text @click="closeDetail">
|
|
|
|
|
<Icon icon="ep:close" />
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="detail-card">
|
|
|
|
|
<div class="detail-image-box">
|
|
|
|
|
<div class="detail-image-item">
|
|
|
|
|
<div class="detail-image-label">{{ t('FactoryModeling.ProductInformation.qrcode') }}</div>
|
|
|
|
|
<el-image
|
|
|
|
|
v-if="productDetail.qrcodeUrl"
|
|
|
|
|
class="detail-image"
|
|
|
|
|
:src="productDetail.qrcodeUrl"
|
|
|
|
|
fit="contain"
|
|
|
|
|
:preview-src-list="[productDetail.qrcodeUrl]"
|
|
|
|
|
preview-teleported
|
|
|
|
|
/>
|
|
|
|
|
<el-empty v-else :image-size="64" :description="t('FactoryModeling.ProductInformation.qrcodeEmpty')" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="detail-info">
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogBarCodeLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.barCode) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogCategoryTypeLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatCategoryType(productDetail.categoryType) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogNameLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.name) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogCategoryLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.subCategoryName) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogUnitLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.unitName) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogStandardLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.standard || productDetail.deviceSpec || productDetail.model) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogExpiryDayLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.expiryDay) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogStatusLabel') }}:</span>
|
|
|
|
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="productDetail.status" />
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 产品类型:关联设备、关联模具 -->
|
|
|
|
|
<template v-if="productDetail.categoryType === 1">
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">关联设备:</span>
|
|
|
|
|
<span class="field-value">{{ formatDeviceText(productDetail) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">关联模具:</span>
|
|
|
|
|
<span class="field-value">{{ formatMoldText(productDetail) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<!-- 物料/备件类型:供应商 -->
|
|
|
|
|
<template v-if="productDetail.categoryType === 2 || productDetail.categoryType === 3">
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogSupplierLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatSupplierText(productDetail) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<!-- 备件类型:备件等级、是否易损件、采购周期、品牌 -->
|
|
|
|
|
<template v-if="productDetail.categoryType === 3">
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogSparePartLevelLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatSparePartLevel(productDetail.sparePartLevel) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogFragileFlagLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ productDetail.fragileFlag === 1 ? t('common.yes') : productDetail.fragileFlag === 0 ? t('common.no') : '-' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogPurchaseCycleLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.purchaseCycle) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-field">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogBrandLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.brand) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<div class="detail-field detail-field--full">
|
|
|
|
|
<span class="field-label">{{ t('FactoryModeling.ProductInformation.dialogRemarkLabel') }}:</span>
|
|
|
|
|
<span class="field-value">{{ formatValue(productDetail.remark) }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="detail-summary">
|
|
|
|
|
<div class="section-title">{{ detailSummaryTitle }}</div>
|
|
|
|
|
<!-- 产品类型:包装方案摘要 -->
|
|
|
|
|
<template v-if="productDetail.categoryType === 1">
|
|
|
|
|
<div class="summary-item">
|
|
|
|
|
<Icon icon="ep:box" class="summary-icon" />
|
|
|
|
|
<span>{{ t('FactoryModeling.ProductInformation.dialogPackagingSchemeLabel') }}:{{ packagingSchemeCount }} 个</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="summary-item">
|
|
|
|
|
<Icon icon="ep:document-checked" class="summary-icon" />
|
|
|
|
|
<span>默认参考方案:{{ defaultPackagingSchemeText }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<!-- 物料/备件类型:供应商摘要 -->
|
|
|
|
|
<template v-if="productDetail.categoryType === 2 || productDetail.categoryType === 3">
|
|
|
|
|
<div class="summary-item">
|
|
|
|
|
<Icon icon="ep:office-building" class="summary-icon" />
|
|
|
|
|
<span>{{ t('FactoryModeling.ProductInformation.dialogSupplierLabel') }}:{{ supplierCount }} 个</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="summary-item">
|
|
|
|
|
<Icon icon="ep:star" class="summary-icon" />
|
|
|
|
|
<span>默认供应商:{{ defaultSupplierText }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<div class="detail-image-item" style="margin-top: 12px;">
|
|
|
|
|
<div class="detail-image-label">{{ t('FactoryModeling.ProductInformation.images') }}</div>
|
|
|
|
|
<el-image
|
|
|
|
|
v-if="productDetail.images"
|
|
|
|
|
class="detail-image"
|
|
|
|
|
:src="productDetail.images"
|
|
|
|
|
fit="contain"
|
|
|
|
|
:preview-src-list="[productDetail.images]"
|
|
|
|
|
preview-teleported
|
|
|
|
|
/>
|
|
|
|
|
<el-empty v-else :image-size="64" description="暂无图片" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 产品类型:包装方案表格 -->
|
|
|
|
|
<div v-if="productDetail.categoryType === 1" class="detail-table-box">
|
|
|
|
|
<div class="detail-table-title">
|
|
|
|
|
<span>{{ t('FactoryModeling.ProductInformation.dialogPackagingSchemeLabel') }}</span>
|
|
|
|
|
<span>共 {{ packagingSchemeCount }} 个</span>
|
|
|
|
|
</div>
|
|
|
|
|
<el-table :data="productDetail.packagingSchemes || []" border size="small" :show-overflow-tooltip="true">
|
|
|
|
|
<el-table-column :label="t('ErpStock.PackagingScheme.name')" prop="packagingSchemeName" min-width="130" />
|
|
|
|
|
<el-table-column :label="t('ErpStock.PackagingScheme.packageQuantity')" prop="packageQuantity" min-width="100" />
|
|
|
|
|
<el-table-column :label="t('ErpStock.PackagingScheme.palletPackageQuantity')" prop="palletPackageQuantity" min-width="100" />
|
|
|
|
|
</el-table>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 物料/备件类型:供应商表格 -->
|
|
|
|
|
<div v-else-if="productDetail.categoryType === 2 || productDetail.categoryType === 3" class="detail-table-box">
|
|
|
|
|
<div class="detail-table-title">
|
|
|
|
|
<span>{{ t('FactoryModeling.ProductInformation.dialogSupplierLabel') }}</span>
|
|
|
|
|
<span>共 {{ supplierCount }} 个</span>
|
|
|
|
|
</div>
|
|
|
|
|
<el-table :data="productDetail.suppliers || []" border size="small" :show-overflow-tooltip="true">
|
|
|
|
|
<el-table-column :label="t('ErpPurchase.Supplier.name')" prop="supplierName" min-width="160" />
|
|
|
|
|
<el-table-column :label="t('ErpPurchase.Supplier.contact')" prop="supplierContact" min-width="100" />
|
|
|
|
|
<el-table-column :label="t('ErpPurchase.Supplier.mobile')" prop="supplierMobile" min-width="120" />
|
|
|
|
|
</el-table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</ContentWrap>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<ProductForm v-else-if="formType === 'product'" ref="formRef" @success="getList" @closed="handleFormClosed" />
|
|
|
|
|
@ -126,7 +303,7 @@
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { dateFormatter } from '@/utils/formatTime'
|
|
|
|
|
import { dateFormatter, formatDate } from '@/utils/formatTime'
|
|
|
|
|
import download from '@/utils/download'
|
|
|
|
|
import { ProductApi, ProductVO } from '@/api/erp/product/product'
|
|
|
|
|
import { ProductCategoryApi } from '@/api/erp/product/category'
|
|
|
|
|
@ -156,6 +333,10 @@ const queryFormRef = ref()
|
|
|
|
|
const exportLoading = ref(false)
|
|
|
|
|
const formVisible = ref(false)
|
|
|
|
|
const formType = ref('')
|
|
|
|
|
const detailVisible = ref(false)
|
|
|
|
|
const detailLoading = ref(false)
|
|
|
|
|
const currentDetailId = ref<number>()
|
|
|
|
|
const productDetail = ref<any>()
|
|
|
|
|
|
|
|
|
|
/** 分类树数据 */
|
|
|
|
|
const groupTreeData = ref<any[]>([])
|
|
|
|
|
@ -226,6 +407,9 @@ const getList = async () => {
|
|
|
|
|
const data = await ProductApi.getProductPage(queryParams)
|
|
|
|
|
list.value = data.list
|
|
|
|
|
total.value = data.total
|
|
|
|
|
if (currentDetailId.value && !list.value.some((item) => item.id === currentDetailId.value)) {
|
|
|
|
|
closeDetail()
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
@ -233,11 +417,13 @@ const getList = async () => {
|
|
|
|
|
|
|
|
|
|
const handleQuery = () => {
|
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
|
closeDetail()
|
|
|
|
|
getList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resetQuery = () => {
|
|
|
|
|
queryFormRef.value.resetFields()
|
|
|
|
|
closeDetail()
|
|
|
|
|
handleQuery()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -255,6 +441,9 @@ const handleDelete = async (id: number) => {
|
|
|
|
|
await message.delConfirm()
|
|
|
|
|
await ProductApi.deleteProduct(id)
|
|
|
|
|
message.success(t('common.delSuccess'))
|
|
|
|
|
if (currentDetailId.value === id) {
|
|
|
|
|
closeDetail()
|
|
|
|
|
}
|
|
|
|
|
await getList()
|
|
|
|
|
} catch { }
|
|
|
|
|
}
|
|
|
|
|
@ -293,6 +482,98 @@ const handleFormClosed = () => {
|
|
|
|
|
formVisible.value = false
|
|
|
|
|
formType.value = ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleShowDetail = async (id: number) => {
|
|
|
|
|
detailVisible.value = true
|
|
|
|
|
currentDetailId.value = id
|
|
|
|
|
detailLoading.value = true
|
|
|
|
|
try {
|
|
|
|
|
productDetail.value = await ProductApi.getProduct(id)
|
|
|
|
|
} finally {
|
|
|
|
|
detailLoading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const closeDetail = () => {
|
|
|
|
|
detailVisible.value = false
|
|
|
|
|
detailLoading.value = false
|
|
|
|
|
currentDetailId.value = undefined
|
|
|
|
|
productDetail.value = undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getRowClassName = ({ row }: { row: ProductVO }) => {
|
|
|
|
|
return row.id === currentDetailId.value ? 'current-detail-row' : ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const packagingSchemes = computed(() => productDetail.value?.packagingSchemes || [])
|
|
|
|
|
|
|
|
|
|
const packagingSchemeCount = computed(() => packagingSchemes.value.length)
|
|
|
|
|
|
|
|
|
|
const defaultPackagingScheme = computed(() => {
|
|
|
|
|
const defaultId = productDetail.value?.defaultPackagingSchemeId
|
|
|
|
|
return packagingSchemes.value.find((item: any) => item.defaultStatus === 1)
|
|
|
|
|
|| packagingSchemes.value.find((item: any) => item.packagingSchemeId === defaultId)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const defaultPackagingSchemeText = computed(() => {
|
|
|
|
|
const scheme = defaultPackagingScheme.value
|
|
|
|
|
if (!scheme) return '-'
|
|
|
|
|
return formatValue(scheme.packagingSchemeName)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const detailSummaryTitle = computed(() => {
|
|
|
|
|
const categoryType = formatCategoryType(productDetail.value?.categoryType)
|
|
|
|
|
return categoryType === '-' ? '物料属性摘要' : `${categoryType}属性摘要`
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 供应商相关计算
|
|
|
|
|
const suppliers = computed(() => productDetail.value?.suppliers || [])
|
|
|
|
|
const supplierCount = computed(() => suppliers.value.length)
|
|
|
|
|
const defaultSupplier = computed(() => {
|
|
|
|
|
return suppliers.value.find((item: any) => item.defaultStatus === 1)
|
|
|
|
|
})
|
|
|
|
|
const defaultSupplierText = computed(() => {
|
|
|
|
|
const supplier = defaultSupplier.value
|
|
|
|
|
if (!supplier) return '-'
|
|
|
|
|
return supplier.supplierName || '-'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 格式化辅助函数
|
|
|
|
|
const formatDeviceText = (detail: any) => {
|
|
|
|
|
if (!detail?.devices?.length && !detail?.deviceList?.length) return '-'
|
|
|
|
|
const list = detail.devices || detail.deviceList || []
|
|
|
|
|
return list.map((item: any) => item.name || item.deviceName || `ID:${item.id}`).join('、') || '-'
|
|
|
|
|
}
|
|
|
|
|
const formatMoldText = (detail: any) => {
|
|
|
|
|
if (!detail?.molds?.length && !detail?.moldList?.length) return '-'
|
|
|
|
|
const list = detail.molds || detail.moldList || []
|
|
|
|
|
return list.map((item: any) => item.name || item.code || `ID:${item.id}`).join('、') || '-'
|
|
|
|
|
}
|
|
|
|
|
const formatSupplierText = (detail: any) => {
|
|
|
|
|
if (!detail?.suppliers?.length) return '-'
|
|
|
|
|
return detail.suppliers.map((item: any) => item.supplierName || `ID:${item.supplierId}`).join('、') || '-'
|
|
|
|
|
}
|
|
|
|
|
const formatSparePartLevel = (value: any) => {
|
|
|
|
|
if (value === undefined || value === null || value === '') return '-'
|
|
|
|
|
const dictItem = sparePartLevelDict.value.find((item: any) => item.value === Number(value))
|
|
|
|
|
return dictItem?.label || formatValue(value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sparePartLevelDict = computed(() => getIntDictOptions(DICT_TYPE.SPARE_PARTS_LEVEL))
|
|
|
|
|
|
|
|
|
|
const formatValue = (value: any) => {
|
|
|
|
|
return value === undefined || value === null || value === '' ? '-' : value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const formatCategoryType = (value: any) => {
|
|
|
|
|
const dictItem = typeDict.value.find((item: any) => item.value === Number(value))
|
|
|
|
|
return dictItem?.label || formatValue(value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const formatDateTime = (value: any) => {
|
|
|
|
|
if (value === undefined || value === null || value === '') return '-'
|
|
|
|
|
return formatDate(value)
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
@ -311,6 +592,145 @@ const handleFormClosed = () => {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.product-detail-wrap {
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:deep(.current-detail-row) {
|
|
|
|
|
--el-table-tr-bg-color: var(--el-color-primary-light-9);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-title {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-card {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 200px 1fr 300px 1fr;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
padding: 16px;
|
|
|
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-info {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
gap: 14px 28px;
|
|
|
|
|
align-content: start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-field {
|
|
|
|
|
display: flex;
|
|
|
|
|
min-width: 0;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
line-height: 24px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-field--full {
|
|
|
|
|
grid-column: 1 / -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.field-label {
|
|
|
|
|
flex: 0 0 auto;
|
|
|
|
|
color: var(--el-text-color-regular);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.field-value {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-image-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-image-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: left;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-image-label {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-image {
|
|
|
|
|
width: 170px;
|
|
|
|
|
height: 170px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-summary {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.summary-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
min-height: 32px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.summary-icon {
|
|
|
|
|
flex: 0 0 auto;
|
|
|
|
|
color: var(--el-color-primary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-table-box {
|
|
|
|
|
min-width: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-table-title {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
|
|
|
|
|
span:last-child {
|
|
|
|
|
color: var(--el-text-color-secondary);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 1200px) {
|
|
|
|
|
.detail-card {
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.detail-summary,
|
|
|
|
|
.detail-table-box {
|
|
|
|
|
grid-column: 1 / -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tree-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|