|
|
|
|
@ -98,6 +98,9 @@
|
|
|
|
|
<template slot-scope="{ row }" slot="area">
|
|
|
|
|
{{ row.material_info ? row.material_info.suozaicangku : '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
<template slot-scope="{ row }" slot="executor">
|
|
|
|
|
{{ row.responsible_admin ? row.responsible_admin.name : '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
<template slot-scope="{ row }" slot="startTime">
|
|
|
|
|
{{ row.material_infos_plan ? row.material_infos_plan.start_date : '-' }}
|
|
|
|
|
</template>
|
|
|
|
|
@ -109,7 +112,7 @@
|
|
|
|
|
</template>
|
|
|
|
|
<template slot-scope="{ row }" slot="action">
|
|
|
|
|
<div style="display: flex; gap: 8px; justify-content: center;">
|
|
|
|
|
<Button type="primary" size="small" style="border-radius: 6px;" @click="viewInventoryDetail(row.id)">查看</Button>
|
|
|
|
|
<Button type="primary" size="small" style="border-radius: 6px;" @click="viewInventoryDetail(row)">查看</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</Table>
|
|
|
|
|
@ -248,23 +251,23 @@
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<span class="label">盘点单号:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.no }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<span class="label">所属计划:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.planName }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<span class="label">盘点区域:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.area }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<span class="label">执行人:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.executor }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<span class="label">开始时间:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.startTime }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="detail-item">
|
|
|
|
|
<span class="label">完成时间:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.endTime || '-' }}</span>
|
|
|
|
|
@ -276,36 +279,56 @@
|
|
|
|
|
{{ getInventoryStatusText(detailModal.data.status) }}
|
|
|
|
|
</Tag>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="progress-section">
|
|
|
|
|
<div class="progress-header">
|
|
|
|
|
<h3>盘点进度</h3>
|
|
|
|
|
<div class="progress-stats">
|
|
|
|
|
<span>已盘点:{{ detailModal.data.checked_count || 0 }}</span>
|
|
|
|
|
<span>总数量:{{ detailModal.data.total_count || 0 }}</span>
|
|
|
|
|
<span>完成率:{{ detailModal.data.progress || '0%' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<Progress :percent="detailModal.data.progress_number || 0" :stroke-color="getProgressColor(detailModal.data.progress_number)" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="material-info-section">
|
|
|
|
|
<h3>物资基本信息</h3>
|
|
|
|
|
<div class="material-info-content">
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">物资名称:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.material_info && detailModal.data.material_info.zichanmingcheng || '-' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">物资代码:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.material_info && detailModal.data.material_info.wuzibianma || '-' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">规格型号:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.material_info && detailModal.data.material_info.guigexinghao || '-' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">计量单位:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.material_info && detailModal.data.material_info.jiliangdanwei || '-' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
<span class="label">当前库存:</span>
|
|
|
|
|
<span class="value">{{ detailModal.data.material_info && detailModal.data.material_info.inventorys_total || '0' }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="material-section">
|
|
|
|
|
<h3>盘点物资列表</h3>
|
|
|
|
|
<div class="history-section">
|
|
|
|
|
<h3>盘点历史记录</h3>
|
|
|
|
|
<Table
|
|
|
|
|
:columns="detailColumns"
|
|
|
|
|
:data="detailModal.data.materials || []"
|
|
|
|
|
:data="detailModal.data.history || []"
|
|
|
|
|
:loading="detailModal.loading"
|
|
|
|
|
border
|
|
|
|
|
>
|
|
|
|
|
<template slot-scope="{ row }" slot="status">
|
|
|
|
|
<Tag :color="getInventoryStatusColor(row.status)">{{ getInventoryStatusText(row.status) }}</Tag>
|
|
|
|
|
</template>
|
|
|
|
|
<template slot-scope="{ row }" slot="diff_quantity">
|
|
|
|
|
<span :style="{ color: row.diff_quantity > 0 ? '#19be6b' : row.diff_quantity < 0 ? '#ed4014' : '#515a6e' }">
|
|
|
|
|
{{ row.diff_quantity > 0 ? '+' + row.diff_quantity : row.diff_quantity }}
|
|
|
|
|
</span>
|
|
|
|
|
<template slot-scope="{ row }" slot="photos">
|
|
|
|
|
<div class="photo-list" v-if="row.files && row.files.length">
|
|
|
|
|
<div class="photo-item" v-for="(file, index) in row.files.slice(0, 3)" :key="index">
|
|
|
|
|
<img :src="file.url" @click="previewImage(file.url)" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="photo-more" v-if="row.files.length > 3">
|
|
|
|
|
+{{ row.files.length - 3 }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</template>
|
|
|
|
|
</Table>
|
|
|
|
|
<div class="pagination-container">
|
|
|
|
|
@ -319,17 +342,22 @@
|
|
|
|
|
:total="detailModal.total"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<template slot="footer">
|
|
|
|
|
<Button @click="detailModal.visible = false">关闭</Button>
|
|
|
|
|
</template>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
<!-- 预览弹窗 -->
|
|
|
|
|
<div v-if="previewUrl" class="image-preview-modal" @click="closePreview">
|
|
|
|
|
<img :src="previewUrl" class="image-preview-large" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { saveStocktakingPlan, getStocktakingPlanList, deleteStocktakingPlan, getStocktakingPlanLinkList } from '@/api/system/stocktaking'
|
|
|
|
|
import { saveStocktakingPlan, getStocktakingPlanList, deleteStocktakingPlan, getStocktakingPlanLinkList, getStocktakingPlanLinkDetail } from '@/api/system/stocktaking'
|
|
|
|
|
import { getStorehouseTypeList } from '@/api/system/storehouseType'
|
|
|
|
|
import { getparameteritem } from '@/api/system/dictionary'
|
|
|
|
|
import { index as getWarehouseList } from '@/api/system/baseForm'
|
|
|
|
|
@ -388,7 +416,11 @@ export default {
|
|
|
|
|
slot: 'area',
|
|
|
|
|
key: 'material_info.suozaicangku'
|
|
|
|
|
},
|
|
|
|
|
{ title: '执行人', key: 'executor' },
|
|
|
|
|
{
|
|
|
|
|
title: '执行人',
|
|
|
|
|
slot: 'executor',
|
|
|
|
|
key: 'responsible_admin.name'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '开始时间',
|
|
|
|
|
slot: 'startTime',
|
|
|
|
|
@ -491,24 +523,40 @@ export default {
|
|
|
|
|
total: 0
|
|
|
|
|
},
|
|
|
|
|
detailColumns: [
|
|
|
|
|
{ title: '物资名称', key: 'zichanmingcheng', minWidth: 150 },
|
|
|
|
|
{ title: '规格型号', key: 'guigexinghao', minWidth: 120 },
|
|
|
|
|
{ title: '单位', key: 'jiliangdanwei', width: 80 },
|
|
|
|
|
{ title: '当前库存', key: 'rukushuliang', width: 100 },
|
|
|
|
|
{ title: '盘点数量', key: 'check_quantity', width: 100 },
|
|
|
|
|
{
|
|
|
|
|
title: '差异数量',
|
|
|
|
|
slot: 'diff_quantity',
|
|
|
|
|
key: 'diff_quantity',
|
|
|
|
|
width: 100
|
|
|
|
|
title: '盘点日期',
|
|
|
|
|
key: 'check_date',
|
|
|
|
|
width: 180,
|
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '盘点数量',
|
|
|
|
|
key: 'check_num',
|
|
|
|
|
width: 100,
|
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '状态',
|
|
|
|
|
slot: 'status',
|
|
|
|
|
key: 'status',
|
|
|
|
|
width: 100
|
|
|
|
|
width: 100,
|
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '备注',
|
|
|
|
|
key: 'remark',
|
|
|
|
|
minWidth: 200,
|
|
|
|
|
tooltip: true,
|
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '照片',
|
|
|
|
|
slot: 'photos',
|
|
|
|
|
width: 200,
|
|
|
|
|
align: 'center'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
previewUrl: ''
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
@ -720,33 +768,43 @@ export default {
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async searchList() {
|
|
|
|
|
this.listLoading = true
|
|
|
|
|
this.listLoading = true;
|
|
|
|
|
try {
|
|
|
|
|
const params = {
|
|
|
|
|
keyword: this.listSearch.keyword,
|
|
|
|
|
page: this.listSearch.pageIndex,
|
|
|
|
|
page_size: this.listSearch.pageSize,
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('page', this.listSearch.pageIndex);
|
|
|
|
|
formData.append('page_size', this.listSearch.pageSize);
|
|
|
|
|
|
|
|
|
|
// 只添加非空的搜索条件
|
|
|
|
|
if (this.listSearch.keyword) {
|
|
|
|
|
formData.append('keyword', this.listSearch.keyword);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计划筛选
|
|
|
|
|
if (this.listSearch.planId) {
|
|
|
|
|
params.filter = JSON.stringify([{ key: 'material_infos_plan_id', op: 'eq', value: this.listSearch.planId }])
|
|
|
|
|
const filterIndex = this.listSearch.keyword ? 1 : 0;
|
|
|
|
|
formData.append(`filter[${filterIndex}][key]`, 'material_infos_plan_id');
|
|
|
|
|
formData.append(`filter[${filterIndex}][op]`, 'eq');
|
|
|
|
|
formData.append(`filter[${filterIndex}][value]`, this.listSearch.planId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 状态筛选
|
|
|
|
|
if (this.listSearch.status) {
|
|
|
|
|
params.filter = params.filter || '[]'
|
|
|
|
|
let filterArr = JSON.parse(params.filter)
|
|
|
|
|
filterArr.push({ key: 'status', op: 'eq', value: this.listSearch.status })
|
|
|
|
|
params.filter = JSON.stringify(filterArr)
|
|
|
|
|
const filterIndex = (this.listSearch.keyword ? 1 : 0) + (this.listSearch.planId ? 1 : 0);
|
|
|
|
|
formData.append(`filter[${filterIndex}][key]`, 'status');
|
|
|
|
|
formData.append(`filter[${filterIndex}][op]`, 'eq');
|
|
|
|
|
formData.append(`filter[${filterIndex}][value]`, this.listSearch.status);
|
|
|
|
|
}
|
|
|
|
|
const res = await getStocktakingPlanLinkList(params)
|
|
|
|
|
if (res && res.list.data) {
|
|
|
|
|
this.inventoryList = res.list.data
|
|
|
|
|
this.listTotal = res.list.total || 0
|
|
|
|
|
|
|
|
|
|
const res = await getStocktakingPlanLinkList(formData);
|
|
|
|
|
if (res && res.list) {
|
|
|
|
|
this.inventoryList = res.list.data;
|
|
|
|
|
this.listTotal = res.list.total;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$Message.error('获取盘点列表失败')
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.$Message.error('获取盘点列表失败');
|
|
|
|
|
console.error('获取盘点列表失败:', error);
|
|
|
|
|
} finally {
|
|
|
|
|
this.listLoading = false
|
|
|
|
|
this.listLoading = false;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
resetListSearch() {
|
|
|
|
|
@ -768,57 +826,44 @@ export default {
|
|
|
|
|
this.listSearch.pageIndex = 1
|
|
|
|
|
this.searchList()
|
|
|
|
|
},
|
|
|
|
|
async viewInventoryDetail(id) {
|
|
|
|
|
async viewInventoryDetail(row) {
|
|
|
|
|
this.detailModal.loading = true;
|
|
|
|
|
this.detailModal.visible = true;
|
|
|
|
|
this.detailModal.pageIndex = 1;
|
|
|
|
|
try {
|
|
|
|
|
// 模拟数据
|
|
|
|
|
const mockData = {
|
|
|
|
|
no: 'PD202403150001',
|
|
|
|
|
planName: '2024年第一季度盘点计划',
|
|
|
|
|
area: 'A区仓库',
|
|
|
|
|
executor: '张三',
|
|
|
|
|
startTime: '2024-03-15 09:00:00',
|
|
|
|
|
endTime: '2024-03-15 17:00:00',
|
|
|
|
|
status: '1',
|
|
|
|
|
checked_count: 8,
|
|
|
|
|
total_count: 10,
|
|
|
|
|
progress: '80%',
|
|
|
|
|
progress_number: 80,
|
|
|
|
|
materials: Array.from({ length: 25 }, (_, index) => ({
|
|
|
|
|
id: index + 1,
|
|
|
|
|
zichanmingcheng: `物资${index + 1}`,
|
|
|
|
|
guigexinghao: `型号${index + 1}`,
|
|
|
|
|
jiliangdanwei: '个',
|
|
|
|
|
rukushuliang: Math.floor(Math.random() * 10) + 1,
|
|
|
|
|
check_quantity: Math.floor(Math.random() * 10) + 1,
|
|
|
|
|
diff_quantity: Math.floor(Math.random() * 10) - 5,
|
|
|
|
|
status: Math.random() > 0.5 ? '1' : '0'
|
|
|
|
|
}))
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 模拟分页
|
|
|
|
|
const start = (this.detailModal.pageIndex - 1) * this.detailModal.pageSize;
|
|
|
|
|
const end = start + this.detailModal.pageSize;
|
|
|
|
|
const pagedMaterials = mockData.materials.slice(start, end);
|
|
|
|
|
// 先用列表行数据初始化基本信息
|
|
|
|
|
this.detailModal.data = {
|
|
|
|
|
id: row.id,
|
|
|
|
|
no: row.no,
|
|
|
|
|
planName: row.material_infos_plan ? row.material_infos_plan.name : '-',
|
|
|
|
|
area: row.material_info ? row.material_info.suozaicangku : '-',
|
|
|
|
|
executor: row.responsible_admin ? row.responsible_admin.name : '-',
|
|
|
|
|
startTime: row.material_infos_plan ? row.material_infos_plan.start_date : '-',
|
|
|
|
|
endTime: row.material_infos_plan ? row.material_infos_plan.end_date : '-',
|
|
|
|
|
status: row.status,
|
|
|
|
|
material_info: row.material_info || {},
|
|
|
|
|
history: []
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.detailModal.data = {
|
|
|
|
|
...mockData,
|
|
|
|
|
materials: pagedMaterials
|
|
|
|
|
};
|
|
|
|
|
this.detailModal.total = mockData.materials.length;
|
|
|
|
|
try {
|
|
|
|
|
// 获取物资详情,包含盘点历史
|
|
|
|
|
const res = await request({
|
|
|
|
|
url: '/api/admin/material-infos/show',
|
|
|
|
|
method: 'get',
|
|
|
|
|
params: {
|
|
|
|
|
id: row.material_info.id
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 实际接口调用
|
|
|
|
|
// const res = await getStocktakingPlanLinkList({
|
|
|
|
|
// id,
|
|
|
|
|
// page: this.detailModal.pageIndex,
|
|
|
|
|
// page_size: this.detailModal.pageSize
|
|
|
|
|
// });
|
|
|
|
|
// if (res && res.data) {
|
|
|
|
|
// this.detailModal.data = res.data;
|
|
|
|
|
// this.detailModal.total = res.total || 0;
|
|
|
|
|
// }
|
|
|
|
|
if (res) {
|
|
|
|
|
// 更新物资信息和历史记录数据
|
|
|
|
|
this.detailModal.data = {
|
|
|
|
|
...this.detailModal.data,
|
|
|
|
|
material_info: res || {},
|
|
|
|
|
history: res.material_infos_plan_link || []
|
|
|
|
|
};
|
|
|
|
|
this.detailModal.total = res.material_infos_plan_link ? res.material_infos_plan_link.length : 0;
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.$Message.error('获取盘点任务详情失败');
|
|
|
|
|
console.error('获取盘点任务详情失败:', error);
|
|
|
|
|
@ -834,9 +879,6 @@ export default {
|
|
|
|
|
this.searchMaterials()
|
|
|
|
|
},
|
|
|
|
|
isSelected(item) {
|
|
|
|
|
// console.log('isSelected called', item.id)
|
|
|
|
|
// console.log('materialModal.selectedMaterialIds', this.materialModal.selectedMaterialIds)
|
|
|
|
|
// console.log('this.materialModal.selectedMaterialIds.has(item.id)', this.materialModal.selectedMaterialIds.has(item.id))
|
|
|
|
|
return this.materialModal.selectedMaterialIds.has(item.id);
|
|
|
|
|
},
|
|
|
|
|
handleSelect(selection, item) {
|
|
|
|
|
@ -861,28 +903,6 @@ export default {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// console.log('handleSelectionChange called', selection);
|
|
|
|
|
|
|
|
|
|
// // 如果是初始加载,跳过处理
|
|
|
|
|
// if (this.materialModal.isInitialLoad) {
|
|
|
|
|
// this.materialModal.isInitialLoad = false;
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // 更新选中状态集合
|
|
|
|
|
// const planId = this.materialModal.currentPlanId;
|
|
|
|
|
// if (planId) {
|
|
|
|
|
// // 更新界面
|
|
|
|
|
// this.$nextTick(() => {
|
|
|
|
|
// if (this.$refs.materialTable) {
|
|
|
|
|
// this.materialList.forEach(row => {
|
|
|
|
|
// this.$refs.materialTable.toggleRowSelection(row, this.materialModal.selectedMaterialIds.has(row.id));
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
handleSelectAll(selection) {
|
|
|
|
|
console.log('handleSelectAll called', selection);
|
|
|
|
|
|
|
|
|
|
@ -1129,12 +1149,6 @@ export default {
|
|
|
|
|
this.$Message.error('物资关联失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
getProgressColor(percent) {
|
|
|
|
|
if (percent >= 100) return '#19be6b';
|
|
|
|
|
if (percent >= 60) return '#2d8cf0';
|
|
|
|
|
if (percent >= 30) return '#ff9900';
|
|
|
|
|
return '#ed4014';
|
|
|
|
|
},
|
|
|
|
|
handleDetailPageChange(page) {
|
|
|
|
|
this.detailModal.pageIndex = page;
|
|
|
|
|
this.viewInventoryDetail(this.detailModal.data.id);
|
|
|
|
|
@ -1143,6 +1157,12 @@ export default {
|
|
|
|
|
this.detailModal.pageSize = size;
|
|
|
|
|
this.detailModal.pageIndex = 1;
|
|
|
|
|
this.viewInventoryDetail(this.detailModal.data.id);
|
|
|
|
|
},
|
|
|
|
|
previewImage(url) {
|
|
|
|
|
this.previewUrl = url;
|
|
|
|
|
},
|
|
|
|
|
closePreview() {
|
|
|
|
|
this.previewUrl = '';
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
@ -1341,33 +1361,38 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.progress-section {
|
|
|
|
|
.material-info-section {
|
|
|
|
|
margin-bottom: 30px;
|
|
|
|
|
|
|
|
|
|
.progress-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
|
|
|
|
|
h3 {
|
|
|
|
|
margin: 0;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
color: #17233d;
|
|
|
|
|
}
|
|
|
|
|
h3 {
|
|
|
|
|
margin: 0 0 15px 0;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
color: #17233d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.material-info-content {
|
|
|
|
|
background: #f8f8f9;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
|
|
|
|
.progress-stats {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
.info-item {
|
|
|
|
|
.label {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #666;
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.value {
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.material-section {
|
|
|
|
|
.history-section {
|
|
|
|
|
h3 {
|
|
|
|
|
margin: 0 0 15px 0;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
@ -1375,4 +1400,47 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.photo-list {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
.photo-item {
|
|
|
|
|
width: 40px;
|
|
|
|
|
height: 40px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
img {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
object-fit: cover;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.photo-more {
|
|
|
|
|
color: #666;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-preview-modal {
|
|
|
|
|
position: fixed;
|
|
|
|
|
z-index: 2000;
|
|
|
|
|
left: 0; top: 0; right: 0; bottom: 0;
|
|
|
|
|
background: rgba(0,0,0,0.7);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-preview-large {
|
|
|
|
|
max-width: 90vw;
|
|
|
|
|
max-height: 90vh;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
box-shadow: 0 4px 24px rgba(0,0,0,0.3);
|
|
|
|
|
background: #fff;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|