Refactor billing options retrieval to include data permissions and add effective date handling for product imports
This commit is contained in:
@@ -63,13 +63,13 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生效日期" prop="effectiveDate">
|
||||
<el-date-picker v-model="editForm.effectiveDate" type="date" value-format="YYYY-MM-DD" placeholder="选择日期" style="width: 100%" />
|
||||
<el-form-item label="生效时间" prop="effectiveDate">
|
||||
<el-date-picker v-model="editForm.effectiveDate" type="datetime" format="YYYY-MM-DD HH:00" value-format="YYYY-MM-DD HH:00:00" placeholder="选择时间" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="失效日期" prop="expireDate">
|
||||
<el-date-picker v-model="editForm.expireDate" type="date" value-format="YYYY-MM-DD" placeholder="留空为长期" style="width: 100%" />
|
||||
<el-form-item label="失效时间" prop="expireDate">
|
||||
<el-date-picker v-model="editForm.expireDate" type="datetime" format="YYYY-MM-DD HH:00" value-format="YYYY-MM-DD HH:00:00" placeholder="留空为长期" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
@@ -112,8 +112,8 @@ const columns = [
|
||||
{ prop: 'sizeLimit', label: '尺寸限制', minWidth: 140 },
|
||||
{ prop: 'lastMile', label: '尾程', minWidth: 110 },
|
||||
{ prop: 'leadTime', label: '时效', width: 100, showOverflowTooltip: true },
|
||||
{ prop: 'effectiveDate', label: '生效日期', width: 110, align: 'center' },
|
||||
{ prop: 'expireDate', label: '失效日期', width: 110, align: 'center', formatter: (row) => row.expireDate || '长期' },
|
||||
{ prop: 'effectiveDate', label: '生效时间', width: 160, align: 'center' },
|
||||
{ prop: 'expireDate', label: '失效时间', width: 110, align: 'center', formatter: (row) => row.expireDate || '长期' },
|
||||
{ prop: 'status', label: '状态', width: 90, align: 'center', dict: 'bms_product_effect_status' },
|
||||
// { prop: 'action', label: '操作', width: 70, fixed: 'right', slot: 'action' }
|
||||
]
|
||||
@@ -176,6 +176,15 @@ const editTitle = ref('编辑国家明细')
|
||||
const editFormRef = ref()
|
||||
const saving = ref(false)
|
||||
const editRow = ref({})
|
||||
function normalizeDrawerHour(val) {
|
||||
if (val == null || val === '') return ''
|
||||
const s = String(val).trim().replace('T', ' ')
|
||||
const m = s.match(/^(\d{4}-\d{2}-\d{2})[ ](\d{2})/)
|
||||
if (m) return m[1] + ' ' + m[2] + ':00:00'
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s + ' 00:00:00'
|
||||
return s
|
||||
}
|
||||
|
||||
const editForm = reactive({
|
||||
detailId: null,
|
||||
weightMin: null,
|
||||
@@ -202,7 +211,7 @@ const editRules = {
|
||||
trigger: 'blur'
|
||||
}],
|
||||
freightPrice: [{ required: true, message: '运费不能为空', trigger: 'blur' }],
|
||||
effectiveDate: [{ required: true, message: '生效日期不能为空', trigger: 'change' }]
|
||||
effectiveDate: [{ required: true, message: '生效时间不能为空', trigger: 'change' }]
|
||||
}
|
||||
|
||||
function openEdit(row) {
|
||||
@@ -217,8 +226,8 @@ function openEdit(row) {
|
||||
sizeLimit: row.sizeLimit || '',
|
||||
lastMile: row.lastMile || '',
|
||||
leadTime: row.leadTime || '',
|
||||
effectiveDate: row.effectiveDate ? String(row.effectiveDate).slice(0, 10) : '',
|
||||
expireDate: row.expireDate ? String(row.expireDate).slice(0, 10) : ''
|
||||
effectiveDate: row.effectiveDate ? normalizeDrawerHour(row.effectiveDate) : '',
|
||||
expireDate: row.expireDate ? normalizeDrawerHour(row.expireDate) : '',
|
||||
})
|
||||
editVisible.value = true
|
||||
nextTick(() => editFormRef.value?.clearValidate())
|
||||
|
||||
@@ -80,19 +80,19 @@ const schemas = computed(() => [
|
||||
// rules: [{ required: true, message: '请选择税模式', trigger: 'change' }]
|
||||
// },
|
||||
{
|
||||
label: '生效日期',
|
||||
label: '生效时间',
|
||||
prop: 'effectiveDate',
|
||||
component: 'date',
|
||||
placeholder: '选择日期',
|
||||
component: 'datetime',
|
||||
placeholder: '选择时间',
|
||||
span: 12,
|
||||
width: '100%',
|
||||
rules: [{ required: true, message: '生效日期不能为空', trigger: 'change' }]
|
||||
rules: [{ required: true, message: '生效时间不能为空', trigger: 'change' }]
|
||||
},
|
||||
{
|
||||
label: '失效日期',
|
||||
label: '失效时间',
|
||||
prop: 'expireDate',
|
||||
component: 'date',
|
||||
placeholder: '选择日期',
|
||||
component: 'datetime',
|
||||
placeholder: '选择时间',
|
||||
span: 12,
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb16"
|
||||
title="多国家价表用「全部导入」。单国专线成本价用「按国家导入」:先选目的国家,目录里的产品都记到该国。相同产品代码+生效日期不覆盖主数据。两种导入均可在弹窗内下载对应模板。"
|
||||
title="导入前须先选择生效时间;产品与国家明细均按此时间落库,上一版产品/明细失效时间设为该时间。多国家价表用「全部导入」,单国专线成本价用「按国家导入」。相同产品代码+生效日期不覆盖主数据。"
|
||||
/>
|
||||
|
||||
<basic-table
|
||||
@@ -65,9 +65,27 @@
|
||||
template-url="/templates/product/product-import-all-template.xlsx"
|
||||
template-file-name="产品多国家价表导入模板"
|
||||
:import-desc="allImportDesc"
|
||||
:before-submit="validateImportEffectiveDate"
|
||||
:submit-handler="runImportAllAsync"
|
||||
@success="() => tableRef.refresh()"
|
||||
/>
|
||||
>
|
||||
<template #extra>
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="生效时间" required>
|
||||
<el-date-picker
|
||||
v-model="importEffectiveDate"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:00"
|
||||
value-format="YYYY-MM-DD HH:00:00"
|
||||
popper-class="product-import-hour-picker"
|
||||
placeholder="请选择生效时间"
|
||||
style="width: 100%"
|
||||
@change="onImportEffectiveTimeChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</excel-import-dialog>
|
||||
<excel-import-dialog
|
||||
ref="countryImportRef"
|
||||
title="按国家导入"
|
||||
@@ -82,6 +100,18 @@
|
||||
>
|
||||
<template #extra>
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="生效时间" required>
|
||||
<el-date-picker
|
||||
v-model="importEffectiveDate"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:00"
|
||||
value-format="YYYY-MM-DD HH:00:00"
|
||||
popper-class="product-import-hour-picker"
|
||||
placeholder="请选择生效时间"
|
||||
style="width: 100%"
|
||||
@change="onImportEffectiveTimeChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="目的国家" required>
|
||||
<el-select v-model="importCountryCode" filterable clearable placeholder="请选择国家" style="width: 100%">
|
||||
<el-option
|
||||
@@ -133,6 +163,31 @@ const expiredRef = ref()
|
||||
const importRef = ref()
|
||||
const countryImportRef = ref()
|
||||
const importCountryCode = ref('')
|
||||
const importEffectiveDate = ref('')
|
||||
|
||||
function pad2(n) {
|
||||
return String(n).padStart(2, '0')
|
||||
}
|
||||
|
||||
function formatImportHour(d) {
|
||||
if (!d || Number.isNaN(d.getTime())) return undefined
|
||||
return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate())
|
||||
+ ' ' + pad2(d.getHours()) + ':00:00'
|
||||
}
|
||||
|
||||
function normalizeImportToHour(val) {
|
||||
if (val == null || val === '') return val
|
||||
if (val instanceof Date) return formatImportHour(val)
|
||||
const s = String(val).trim().replace('T', ' ')
|
||||
const m = s.match(/^(\d{4}-\d{2}-\d{2})[ ](\d{2})/)
|
||||
if (m) return m[1] + ' ' + m[2] + ':00:00'
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s + ' 00:00:00'
|
||||
return formatImportHour(new Date(s.replace(/-/g, '/'))) || val
|
||||
}
|
||||
|
||||
function onImportEffectiveTimeChange(val) {
|
||||
importEffectiveDate.value = normalizeImportToHour(val) || ''
|
||||
}
|
||||
const regionOptions = ref([])
|
||||
const importProgressVisible = ref(false)
|
||||
const importProgressPercent = ref(0)
|
||||
@@ -140,12 +195,12 @@ const importProgressMessage = ref('')
|
||||
const importProgressStatus = ref(undefined)
|
||||
const allImportDesc = [
|
||||
'适用多国家价表(B2C 小包价表等),按目录 sheet 匹配国家导入。',
|
||||
'生效日期必填。产品+国家有新生效日时,先失效该国家下全部旧重量段,再插入 Excel 重量段。',
|
||||
'必选生效时间:产品与 product_country 明细均按此时间计费;上一版产品/明细失效时间设为该时间。',
|
||||
'请在弹窗底部下载模板,按模板格式整理后上传。相同产品代码+生效日期不覆盖主数据。'
|
||||
]
|
||||
const countryImportDesc = [
|
||||
'选择目的国家后上传专线成本价表,目录中的产品都会记到该国家。',
|
||||
'生效日期必填。产品+国家有新生效日时,先失效该国家下全部旧重量段,再插入 Excel 重量段。',
|
||||
'必选生效时间:产品与 product_country 明细均按此时间计费;上一版产品/明细失效时间设为该时间。',
|
||||
'邮编、赔偿标准等 sheet 不导入。可在弹窗底部下载模板。'
|
||||
]
|
||||
|
||||
@@ -155,8 +210,8 @@ const columns = [
|
||||
{ prop: 'serviceLevel', label: '时效等级', width: 90, align: 'center' },
|
||||
{ prop: 'cargoAttr', label: '走货属性', minWidth: 120, slot: 'cargoAttr' },
|
||||
{ prop: 'destRegion', label: '目的区域', width: 90, align: 'center' },
|
||||
{ prop: 'effectiveDate', label: '生效日期', width: 120, align: 'center' },
|
||||
{ prop: 'expireDate', label: '失效日期', width: 120, align: 'center' },
|
||||
{ prop: 'effectiveDate', label: '生效时间', width: 160, align: 'center' },
|
||||
{ prop: 'expireDate', label: '失效时间', width: 160, align: 'center' },
|
||||
{ prop: 'countryCount', label: '国家数', width: 80, align: 'center' },
|
||||
{ prop: 'surchargeCount', label: '附加费数', width: 90, align: 'center' },
|
||||
{ prop: 'status', label: '状态', width: 90, align: 'center', slot: 'status' },
|
||||
@@ -190,6 +245,7 @@ function handleImportCommand(command) {
|
||||
}
|
||||
|
||||
function handleImport() {
|
||||
importEffectiveDate.value = ''
|
||||
importRef.value.open()
|
||||
}
|
||||
|
||||
@@ -208,11 +264,21 @@ function loadRegionOptions() {
|
||||
|
||||
function handleCountryImport() {
|
||||
importCountryCode.value = ''
|
||||
importEffectiveDate.value = ''
|
||||
loadRegionOptions()
|
||||
countryImportRef.value.open()
|
||||
}
|
||||
|
||||
function validateImportEffectiveDate() {
|
||||
if (!importEffectiveDate.value) {
|
||||
return '请先选择生效时间'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function validateCountryImport() {
|
||||
const effErr = validateImportEffectiveDate()
|
||||
if (effErr) return effErr
|
||||
if (!importCountryCode.value) {
|
||||
return '请先选择目的国家'
|
||||
}
|
||||
@@ -266,7 +332,11 @@ async function runImportAllAsync(uploadFile) {
|
||||
if (!raw) {
|
||||
throw new Error('请先选择文件')
|
||||
}
|
||||
return runImportWithProgress((onProgress) => importProductExcelAsync(raw, onProgress))
|
||||
if (!importEffectiveDate.value) {
|
||||
throw new Error('请先选择生效时间')
|
||||
}
|
||||
const eff = importEffectiveDate.value
|
||||
return runImportWithProgress((onProgress) => importProductExcelAsync(raw, eff, onProgress))
|
||||
}
|
||||
|
||||
async function runImportCountryAsync(uploadFile) {
|
||||
@@ -274,11 +344,15 @@ async function runImportCountryAsync(uploadFile) {
|
||||
if (!raw) {
|
||||
throw new Error('请先选择文件')
|
||||
}
|
||||
if (!importEffectiveDate.value) {
|
||||
throw new Error('请先选择生效时间')
|
||||
}
|
||||
if (!importCountryCode.value) {
|
||||
throw new Error('请先选择目的国家')
|
||||
}
|
||||
const code = importCountryCode.value
|
||||
return runImportWithProgress((onProgress) => importProductCountryExcelAsync(raw, code, onProgress))
|
||||
const eff = importEffectiveDate.value
|
||||
return runImportWithProgress((onProgress) => importProductCountryExcelAsync(raw, code, eff, onProgress))
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user