178 lines
6.2 KiB
Vue
178 lines
6.2 KiB
Vue
<template>
|
|
<el-drawer
|
|
:model-value="visible"
|
|
:title="title"
|
|
size="78%"
|
|
destroy-on-close
|
|
append-to-body
|
|
@close="emit('update:visible', false)"
|
|
>
|
|
<div class="toolbar">
|
|
<el-input v-model="keyword" clearable placeholder="产品名称 / 工作表 / 国家" style="width: 260px" />
|
|
<el-button type="danger" plain :disabled="!selectedIds.length" @click="handleRemove" v-hasPermi="['price:label:remove']">移除</el-button>
|
|
</div>
|
|
<el-table
|
|
v-loading="loading"
|
|
:data="filteredRows"
|
|
border
|
|
height="calc(100vh - 220px)"
|
|
row-key="termId"
|
|
@selection-change="onSelect"
|
|
>
|
|
<el-table-column type="selection" width="48" align="center" />
|
|
<el-table-column prop="productId" label="产品编号" width="90" align="center" />
|
|
<el-table-column prop="productName" label="产品名称" min-width="150" show-overflow-tooltip />
|
|
<el-table-column prop="supplierName" label="价卡归属" width="100" align="center" />
|
|
<el-table-column prop="countryScope" label="国家/口岸" min-width="120" show-overflow-tooltip />
|
|
<el-table-column prop="chargeType" label="费用类型" width="110" align="center" />
|
|
<el-table-column prop="sheetName" label="报价工作表" min-width="140" show-overflow-tooltip />
|
|
<el-table-column prop="versionNo" label="版本" width="70" align="center" />
|
|
<el-table-column label="有效期" min-width="180" align="center">
|
|
<template #default="{ row }">{{ termText(row) }}</template>
|
|
</el-table-column>
|
|
<el-table-column label="状态" width="90" align="center">
|
|
<template #default="{ row }">
|
|
<el-tag :type="termStatusTag(row.termStatus)" size="small">{{ termStatusText(row.termStatus) }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="weightCount" label="重量段" width="80" align="center" />
|
|
<el-table-column prop="surchargeCount" label="附加费" width="80" align="center" />
|
|
<el-table-column label="操作" width="160" align="center" fixed="right">
|
|
<template #default="{ row }">
|
|
<el-button link type="primary" @click="openProduct(row)" v-hasPermi="['price:label:query']">查看</el-button>
|
|
<el-button link type="danger" @click="handleRemove([row.productId])" v-hasPermi="['price:label:remove']">移除</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<el-drawer v-model="detailVisible" :title="detailTitle" size="78%" destroy-on-close append-to-body>
|
|
<pay-config-detail v-loading="detailLoading" :product="detail" :editable="false" />
|
|
<template #footer>
|
|
<el-button @click="detailVisible = false">关闭</el-button>
|
|
</template>
|
|
</el-drawer>
|
|
</el-drawer>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { listLabelProducts, getLabelProduct, removeLabelProducts } from '@/api/price/label'
|
|
import PayConfigDetail from '@/views/price/basic/pay/components/PayConfigDetail.vue'
|
|
|
|
const props = defineProps({
|
|
visible: { type: Boolean, default: false },
|
|
priceSetId: { type: [Number, String], default: null },
|
|
version: { type: Object, default: null }
|
|
})
|
|
const emit = defineEmits(['update:visible', 'changed'])
|
|
const { proxy } = getCurrentInstance()
|
|
|
|
const loading = ref(false)
|
|
const rows = ref([])
|
|
const keyword = ref('')
|
|
const selectedIds = ref([])
|
|
const detailVisible = ref(false)
|
|
const detailLoading = ref(false)
|
|
const detail = ref(null)
|
|
|
|
const title = computed(() => {
|
|
const v = props.version || {}
|
|
const label = v.versionLabel || (v.versionNo != null ? `V${v.versionNo}` : '')
|
|
return label ? `版本明细 · ${label}` : '版本明细'
|
|
})
|
|
|
|
const detailTitle = computed(() => {
|
|
if (!detail.value) return '产品明细'
|
|
const no = detail.value.versionNo ? `第 ${detail.value.versionNo} 版` : ''
|
|
return `${detail.value.productName || '产品'} ${no}`.trim()
|
|
})
|
|
|
|
const filteredRows = computed(() => {
|
|
const kw = keyword.value.trim().toLowerCase()
|
|
if (!kw) return rows.value
|
|
return rows.value.filter(row => {
|
|
const text = [row.productName, row.sheetName, row.countryScope, row.supplierName].join(' ').toLowerCase()
|
|
return text.includes(kw)
|
|
})
|
|
})
|
|
|
|
function formatHour(val) {
|
|
if (!val) return ''
|
|
const text = String(val).replace('T', ' ')
|
|
if (text.length >= 16) return text.slice(0, 13) + ':00'
|
|
if (text.length >= 10) return text.slice(0, 10) + ' 00:00'
|
|
return text
|
|
}
|
|
|
|
function termText(row) {
|
|
const start = formatHour(row.termStart || row.effectiveDate || '')
|
|
const end = row.termEnd ? formatHour(row.termEnd) : '不限'
|
|
if (!start) return '未设置'
|
|
return start + ' ~ ' + end
|
|
}
|
|
|
|
function termStatusText(status) {
|
|
const map = { '0': '待生效', '1': '生效', '2': '已失效' }
|
|
return map[String(status)] || '-'
|
|
}
|
|
|
|
function termStatusTag(status) {
|
|
const map = { '0': 'warning', '1': 'success', '2': 'danger' }
|
|
return map[String(status)] || 'info'
|
|
}
|
|
|
|
function onSelect(selection) {
|
|
selectedIds.value = (selection || []).map(item => item.productId).filter(Boolean)
|
|
}
|
|
|
|
async function load() {
|
|
if (!props.priceSetId || props.version?.versionNo == null) {
|
|
rows.value = []
|
|
return
|
|
}
|
|
loading.value = true
|
|
try {
|
|
const res = await listLabelProducts(props.priceSetId, props.version.versionNo)
|
|
rows.value = res.data || []
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function openProduct(row) {
|
|
detailVisible.value = true
|
|
detailLoading.value = true
|
|
detail.value = null
|
|
try {
|
|
const res = await getLabelProduct(row.productId, row.termId)
|
|
detail.value = res.data || null
|
|
} finally {
|
|
detailLoading.value = false
|
|
}
|
|
}
|
|
|
|
function handleRemove(ids) {
|
|
const list = (Array.isArray(ids) ? ids : selectedIds.value).filter(Boolean)
|
|
if (!list.length || !props.priceSetId) return
|
|
proxy.$modal.confirm(`确认从本套餐移除选中的 ${list.length} 个产品?`).then(() => {
|
|
return removeLabelProducts(props.priceSetId, list.join(','))
|
|
}).then(() => {
|
|
proxy.$modal.msgSuccess('已移除')
|
|
load()
|
|
emit('changed')
|
|
}).catch(() => {})
|
|
}
|
|
|
|
watch(() => [props.visible, props.priceSetId, props.version?.versionNo], ([vis]) => {
|
|
if (vis) load()
|
|
}, { immediate: true })
|
|
</script>
|
|
|
|
<style scoped>
|
|
.toolbar {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-bottom: 12px;
|
|
align-items: center;
|
|
}
|
|
</style>
|