feat: 材料新增/编辑/详情改用抽屉展示
- 新增/编辑弹窗换成 el-drawer(size 60%,禁止点遮罩关闭) - 列表"详情"不再跳路由,改为打开只读抽屉,内联展示字段和宣传页 - 移除未使用的 useRouter 引用 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
1245fb3da8
commit
b4a4314058
|
|
@ -73,7 +73,14 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="820px" class="dialog-scroll">
|
||||
<el-drawer
|
||||
v-model="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
size="60%"
|
||||
:close-on-click-modal="false"
|
||||
:destroy-on-close="false"
|
||||
class="material-drawer"
|
||||
>
|
||||
<el-form :model="form" label-width="110px">
|
||||
<el-form-item label="材料名称" required>
|
||||
<el-input v-model="form.name" />
|
||||
|
|
@ -224,7 +231,52 @@
|
|||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSave">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-drawer>
|
||||
|
||||
<el-drawer
|
||||
v-model="detailVisible"
|
||||
title="材料详情"
|
||||
size="60%"
|
||||
class="material-drawer"
|
||||
>
|
||||
<el-descriptions v-if="detailData" :column="1" border>
|
||||
<el-descriptions-item label="材料名称">{{ displayText(detailData.name) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="材料大类">{{ displayText(detailData.major_category_display) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="细分种类">{{ displayText(detailData.material_category) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="材料子类">{{ displayText(detailData.material_subcategory) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="阶段">{{ displayText(detailData.stage_display) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="重要等级">{{ displayText(detailData.importance_level_display) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="落地项目">{{ displayText(detailData.landing_project) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="对接人">{{ displayText(detailData.contact_person) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="对接人联系方式">{{ displayText(detailData.contact_phone) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="经办人">{{ displayText(detailData.handler) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注">{{ displayText(detailData.remark) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="规格型号">{{ displayText(detailData.spec) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="符合标准">{{ displayText(detailData.standard) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="应用场景">{{ displayList(detailData.application_scene_display) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="应用说明">{{ displayText(detailData.application_desc) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="替代材料类型">{{ displayText(detailData.replace_type_display) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="竞争优势">{{ displayList(detailData.advantage_display) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="优势说明">{{ displayText(detailData.advantage_desc) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="成本对比">{{ formatPercent(detailData.cost_compare) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="成本说明">{{ displayText(detailData.cost_desc) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="案例">{{ displayText(detailData.cases) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="供应商">{{ displayText(detailData.factory_name) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="品牌">{{ displayText(detailData.brand_name) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="质量等级">{{ formatStarLevel(detailData.quality_level) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="耐久等级">{{ formatStarLevel(detailData.durability_level) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="环保等级">{{ formatStarLevel(detailData.eco_level) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="低碳等级">{{ formatStarLevel(detailData.carbon_level) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="总评分">{{ formatStarLevel(detailData.score_level) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="连接方式">{{ displayText(detailData.connection_method) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="施工工艺">{{ displayText(detailData.construction_method) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="限制条件">{{ displayText(detailData.limit_condition) }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div v-if="detailData?.brochure_url" class="brochure">
|
||||
<div class="brochure-title">宣传页</div>
|
||||
<img :src="detailData.brochure_url" alt="宣传页" />
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog v-model="importDialogVisible" title="导入材料" width="420px">
|
||||
<div class="import-dialog">
|
||||
|
|
@ -249,7 +301,6 @@
|
|||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useAuth } from '@/store/auth'
|
||||
import { fetchMaterials, fetchMaterialDetail, createMaterial, updateMaterial, deleteMaterial, submitMaterial, approveMaterial, rejectMaterial, fetchMaterialChoices, uploadImage, importMaterialsExcel, exportMaterialsExcel } from '@/api/material'
|
||||
|
|
@ -257,7 +308,6 @@ import { fetchCategories, fetchSubcategories } from '@/api/category'
|
|||
import { fetchFactorySimple } from '@/api/factory'
|
||||
import { fetchBrands } from '@/api/brand'
|
||||
|
||||
const router = useRouter()
|
||||
const { isAdmin } = useAuth()
|
||||
const materials = ref([])
|
||||
const tableLoading = ref(false)
|
||||
|
|
@ -268,6 +318,8 @@ const pagination = reactive({
|
|||
})
|
||||
const factories = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const detailVisible = ref(false)
|
||||
const detailData = ref(null)
|
||||
const importDialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const isEdit = ref(false)
|
||||
|
|
@ -635,10 +687,20 @@ const canDelete = (row) => isAdmin.value || row.status === 'draft'
|
|||
const canSubmit = (row) => !isAdmin.value && row.status === 'draft'
|
||||
const canApprove = (row) => isAdmin.value && row.status === 'pending'
|
||||
|
||||
const goDetail = (row) => {
|
||||
router.push(`/materials/${row.id}`)
|
||||
const goDetail = async (row) => {
|
||||
try {
|
||||
detailData.value = await fetchMaterialDetail(row.id)
|
||||
detailVisible.value = true
|
||||
} catch (error) {
|
||||
ElMessage.error(error.response?.data?.detail || '加载详情失败')
|
||||
}
|
||||
}
|
||||
|
||||
const displayText = (value) => value || '-'
|
||||
const displayList = (value) => (value?.length ? value.join('、') : '-')
|
||||
const formatPercent = (value) => (value === null || value === undefined || value === '' ? '-' : `${value}%`)
|
||||
const formatStarLevel = (value) => (value ? `${value}星` : '-')
|
||||
|
||||
const onPageChange = (page) => {
|
||||
pagination.page = page
|
||||
loadMaterials()
|
||||
|
|
@ -688,6 +750,31 @@ onMounted(() => {
|
|||
overflow: auto;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.material-drawer :deep(.el-drawer__body) {
|
||||
padding: 20px 24px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.material-drawer :deep(.el-drawer__footer) {
|
||||
padding: 12px 24px;
|
||||
}
|
||||
|
||||
.brochure {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.brochure-title {
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.brochure img {
|
||||
max-width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
|||
Loading…
Reference in New Issue