增加产品导入功能
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb16"
|
||||
title="Excel 导入:上传威狮B2C小包价表.xlsx。仅入库产品目录 + 各产品 sheet 的国家尺寸/尾程/时效;不导入运费、挂号费、退件重派、申报说明、赔偿标准。"
|
||||
/>
|
||||
|
||||
<basic-table
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:query="queryList"
|
||||
row-key="productId"
|
||||
>
|
||||
<template #toolbar="{ selection, ids }">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['price:product:add']">新建产品</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="selection.length !== 1" @click="handleUpdate(selection[0])" v-hasPermi="['price:product:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="!selection.length" @click="handleDelete(ids)" v-hasPermi="['price:product:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['price:product:import']">导入 Excel</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<template #col-taxMode="{ row }">
|
||||
<el-tag :type="row.taxMode === 'TAX_INCLUDED' ? 'success' : 'warning'" size="small">
|
||||
{{ row.taxMode === 'TAX_INCLUDED' ? '包税' : '不包税' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<template #col-cargoAttr="{ row }">
|
||||
<el-tag type="primary" size="small" effect="plain">{{ row.cargoAttr || '-' }}</el-tag>
|
||||
</template>
|
||||
|
||||
<template #col-status="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'info'" size="small">
|
||||
{{ row.status === '0' ? '正常' : '停用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" icon="View" @click="openCountries(row)" v-hasPermi="['price:product:query']">国家明细</el-button>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(row)" v-hasPermi="['price:product:edit']">编辑</el-button>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(row.productId)" v-hasPermi="['price:product:remove']">删除</el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
|
||||
<el-dialog :title="title" v-model="open" width="640px" append-to-body>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品代码" prop="productCode">
|
||||
<el-input v-model="form.productCode" placeholder="如 WSP037" maxlength="20" :disabled="!!form.productId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="form.productName" placeholder="产品名称" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="时效等级" prop="serviceLevel">
|
||||
<el-input v-model="form.serviceLevel" placeholder="如 标准" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="走货属性" prop="cargoAttr">
|
||||
<el-input v-model="form.cargoAttr" placeholder="普货/带电等" maxlength="100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="目的区域" prop="destRegion">
|
||||
<el-input v-model="form.destRegion" placeholder="如 欧盟" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="税模式" prop="taxMode">
|
||||
<el-select v-model="form.taxMode" placeholder="请选择" style="width: 100%">
|
||||
<el-option label="包税" value="TAX_INCLUDED" />
|
||||
<el-option label="不包税" value="TAX_EXCLUDED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生效日期" prop="effectiveDate">
|
||||
<el-date-picker v-model="form.effectiveDate" type="date" value-format="YYYY-MM-DD" placeholder="选择日期" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio value="0">正常</el-radio>
|
||||
<el-radio value="1">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="更新内容" prop="updateNote">
|
||||
<el-input v-model="form.updateNote" type="textarea" :rows="2" maxlength="500" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="2" maxlength="500" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="open = false">取 消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-drawer v-model="countryOpen" size="720px" :title="countryTitle" append-to-body>
|
||||
<el-table v-loading="countryLoading" :data="countryList" border empty-text="暂无国家明细">
|
||||
<el-table-column label="国家" prop="countryName" width="90" show-overflow-tooltip />
|
||||
<el-table-column label="ISO2" prop="countryCode" width="60" align="center" />
|
||||
<el-table-column label="重量段(KG)" width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.weightMin != null || row.weightMax != null">{{ row.weightMin }} ~ {{ row.weightMax }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="尺寸限制" prop="sizeLimit" min-width="140">
|
||||
<template #default="{ row }">
|
||||
<span class="pre-wrap">{{ row.sizeLimit }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="尾程" prop="lastMile" min-width="110">
|
||||
<template #default="{ row }">
|
||||
<span class="pre-wrap">{{ row.lastMile }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时效" prop="leadTime" width="100" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</el-drawer>
|
||||
|
||||
<excel-import-dialog
|
||||
ref="importRef"
|
||||
title="产品 Excel 导入"
|
||||
action="/price/product/importData"
|
||||
update-support-label="是否更新已经存在的产品(含国家明细覆盖)"
|
||||
@success="() => tableRef.refresh()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PriceProduct">
|
||||
import ExcelImportDialog from '@/components/ExcelImportDialog'
|
||||
import { listProduct, getProduct, addProduct, updateProduct, delProduct, listProductCountries } from '@/api/price/product'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const tableRef = ref()
|
||||
const importRef = ref()
|
||||
const formRef = ref()
|
||||
const open = ref(false)
|
||||
const title = ref('')
|
||||
const countryOpen = ref(false)
|
||||
const countryTitle = ref('')
|
||||
const countryLoading = ref(false)
|
||||
const countryList = ref([])
|
||||
|
||||
const columns = [
|
||||
{ prop: 'productCode', label: '产品代码', minWidth: 110 },
|
||||
{ prop: 'productName', label: '产品名称', minWidth: 140, showOverflowTooltip: true },
|
||||
{ prop: 'serviceLevel', label: '时效等级', width: 90, align: 'center' },
|
||||
{ prop: 'cargoAttr', label: '走货属性', minWidth: 120, slot: 'cargoAttr' },
|
||||
{ prop: 'destRegion', label: '目的区域', width: 90, align: 'center' },
|
||||
{ prop: 'taxMode', label: '税模式', width: 90, align: 'center', slot: 'taxMode' },
|
||||
{ prop: 'effectiveDate', label: '生效日期', width: 120, align: 'center' },
|
||||
{ prop: 'countryCount', label: '国家数', width: 80, align: 'center' },
|
||||
{ prop: 'status', label: '状态', width: 80, align: 'center', slot: 'status' },
|
||||
{ prop: 'updateNote', label: '更新内容', minWidth: 160, showOverflowTooltip: true },
|
||||
{ prop: 'action', label: '操作', width: 240, fixed: 'right', slot: 'action' }
|
||||
]
|
||||
|
||||
const searchColumns = [
|
||||
{ prop: 'productCode', label: '产品代码' },
|
||||
{ prop: 'productName', label: '产品名称' },
|
||||
{
|
||||
prop: 'taxMode',
|
||||
label: '税模式',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '包税', value: 'TAX_INCLUDED' },
|
||||
{ label: '不包税', value: 'TAX_EXCLUDED' }
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '正常', value: '0' },
|
||||
{ label: '停用', value: '1' }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
rules: {
|
||||
productCode: [{ required: true, message: '产品代码不能为空', trigger: 'blur' }],
|
||||
productName: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
|
||||
taxMode: [{ required: true, message: '请选择税模式', trigger: 'change' }]
|
||||
}
|
||||
})
|
||||
const { form, rules } = toRefs(data)
|
||||
|
||||
function queryList(params) {
|
||||
return listProduct(params)
|
||||
}
|
||||
|
||||
function reset() {
|
||||
form.value = {
|
||||
productId: undefined,
|
||||
productCode: undefined,
|
||||
productName: undefined,
|
||||
serviceLevel: undefined,
|
||||
cargoAttr: undefined,
|
||||
destRegion: undefined,
|
||||
updateNote: undefined,
|
||||
taxMode: 'TAX_INCLUDED',
|
||||
effectiveDate: undefined,
|
||||
status: '0',
|
||||
remark: undefined
|
||||
}
|
||||
proxy.resetForm('formRef')
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
reset()
|
||||
open.value = true
|
||||
title.value = '新建产品'
|
||||
}
|
||||
|
||||
function handleUpdate(row) {
|
||||
reset()
|
||||
getProduct(row.productId).then(res => {
|
||||
form.value = res.data
|
||||
open.value = true
|
||||
title.value = '修改产品'
|
||||
})
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
proxy.$refs['formRef'].validate(valid => {
|
||||
if (!valid) return
|
||||
const req = form.value.productId ? updateProduct(form.value) : addProduct(form.value)
|
||||
req.then(() => {
|
||||
proxy.$modal.msgSuccess('操作成功')
|
||||
open.value = false
|
||||
tableRef.value.refresh()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleDelete(ids) {
|
||||
const idText = Array.isArray(ids) ? ids.join(',') : ids
|
||||
proxy.$modal.confirm('是否确认删除所选产品?国家明细将一并删除。').then(() => {
|
||||
return delProduct(idText)
|
||||
}).then(() => {
|
||||
proxy.$modal.msgSuccess('删除成功')
|
||||
tableRef.value.refresh()
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function handleImport() {
|
||||
importRef.value.open()
|
||||
}
|
||||
|
||||
function openCountries(row) {
|
||||
countryTitle.value = `${row.productCode} · ${row.productName} · 国家服务明细`
|
||||
countryOpen.value = true
|
||||
countryLoading.value = true
|
||||
countryList.value = []
|
||||
listProductCountries(row.productCode).then(res => {
|
||||
countryList.value = res.data || []
|
||||
}).finally(() => {
|
||||
countryLoading.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mb16 { margin-bottom: 16px; }
|
||||
.pre-wrap { white-space: pre-wrap; font-size: 12px; line-height: 1.4; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user