fix(mall): 修复商品 SKU 编辑回显被重置
- 修复 SPU 编辑页详情回填时误触发规格/分销类型变更,导致 SKU 价格库存被重置为 0 的问题 - 三端同步处理 web-antd、web-ele、web-antdv-next - SKU 金额回填保持 number 类型,避免影响 InputNumber 双向绑定 - 详情页金额展示补齐两位小数,避免 0.50 显示成 0.5 - 补充浏览器自动化验证详情展示与编辑页直接保存 payload
This commit is contained in:
@@ -70,6 +70,11 @@ function createEmptySku(): MallSpuApi.Sku {
|
||||
};
|
||||
}
|
||||
|
||||
function formatDetailMoney(value: null | number | string | undefined) {
|
||||
const amount = Number(value ?? 0);
|
||||
return Number.isFinite(amount) ? amount.toFixed(2) : '0.00';
|
||||
}
|
||||
|
||||
const skuList = ref<MallSpuApi.Sku[]>([createEmptySku()]);
|
||||
|
||||
/** 批量添加 */
|
||||
@@ -501,17 +506,17 @@ defineExpose({
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="销售价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.price }}
|
||||
{{ formatDetailMoney(row.price) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="市场价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.marketPrice }}
|
||||
{{ formatDetailMoney(row.marketPrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="成本价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.costPrice }}
|
||||
{{ formatDetailMoney(row.costPrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="库存" width="80">
|
||||
@@ -532,12 +537,12 @@ defineExpose({
|
||||
<template v-if="formData?.subCommissionType">
|
||||
<VxeColumn align="center" title="一级返佣(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.firstBrokeragePrice }}
|
||||
{{ formatDetailMoney(row.firstBrokeragePrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="二级返佣(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.secondBrokeragePrice }}
|
||||
{{ formatDetailMoney(row.secondBrokeragePrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {
|
||||
RuleConfig,
|
||||
} from '#/views/mall/product/spu/components';
|
||||
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
@@ -34,6 +34,7 @@ const { closeCurrentTab } = useTabs();
|
||||
const activeTabName = ref('info');
|
||||
const formLoading = ref(false); // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const isDetail = ref(name === 'ProductSpuDetail'); // 是否查看详情
|
||||
const initializingForm = ref(false); // 详情回填时不触发 SKU 重置逻辑
|
||||
const skuListRef = ref(); // 商品属性列表 Ref
|
||||
|
||||
const formData = ref<MallSpuApi.Spu>({
|
||||
@@ -113,11 +114,20 @@ const [SkuForm, skuFormApi] = useVbenForm({
|
||||
schema: useSkuFormSchema(propertyList.value, isDetail.value),
|
||||
showDefaultActions: false,
|
||||
handleValuesChange: (values, fieldsChanged) => {
|
||||
if (fieldsChanged.includes('subCommissionType')) {
|
||||
if (initializingForm.value) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
fieldsChanged.includes('subCommissionType') &&
|
||||
values.subCommissionType !== formData.value.subCommissionType
|
||||
) {
|
||||
formData.value.subCommissionType = values.subCommissionType;
|
||||
handleChangeSubCommissionType();
|
||||
}
|
||||
if (fieldsChanged.includes('specType')) {
|
||||
if (
|
||||
fieldsChanged.includes('specType') &&
|
||||
values.specType !== formData.value.specType
|
||||
) {
|
||||
formData.value.specType = values.specType;
|
||||
handleChangeSpec();
|
||||
}
|
||||
@@ -235,22 +245,28 @@ async function getDetail() {
|
||||
// 金额转换:分转元
|
||||
res.skus = res.skus?.map((item) => ({
|
||||
...item,
|
||||
price: formatToFraction(item.price),
|
||||
marketPrice: formatToFraction(item.marketPrice),
|
||||
costPrice: formatToFraction(item.costPrice),
|
||||
firstBrokeragePrice: formatToFraction(item.firstBrokeragePrice),
|
||||
secondBrokeragePrice: formatToFraction(item.secondBrokeragePrice),
|
||||
price: Number(formatToFraction(item.price)),
|
||||
marketPrice: Number(formatToFraction(item.marketPrice)),
|
||||
costPrice: Number(formatToFraction(item.costPrice)),
|
||||
firstBrokeragePrice: Number(formatToFraction(item.firstBrokeragePrice)),
|
||||
secondBrokeragePrice: Number(
|
||||
formatToFraction(item.secondBrokeragePrice),
|
||||
),
|
||||
}));
|
||||
initializingForm.value = true;
|
||||
formData.value = res;
|
||||
// 初始化各表单值
|
||||
infoFormApi.setValues(res).then();
|
||||
skuFormApi.setValues(res).then();
|
||||
deliveryFormApi.setValues(res).then();
|
||||
descriptionFormApi.setValues(res).then();
|
||||
otherFormApi.setValues(res).then();
|
||||
// 将 SKU 的属性,整理成 PropertyAndValues 数组
|
||||
propertyList.value = getPropertyList(formData.value);
|
||||
// 初始化各表单值
|
||||
void infoFormApi.setValues(res);
|
||||
void skuFormApi.setValues(res);
|
||||
void deliveryFormApi.setValues(res);
|
||||
void descriptionFormApi.setValues(res);
|
||||
void otherFormApi.setValues(res);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
} finally {
|
||||
initializingForm.value = false;
|
||||
formLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,11 @@ function createEmptySku(): MallSpuApi.Sku {
|
||||
};
|
||||
}
|
||||
|
||||
function formatDetailMoney(value: null | number | string | undefined) {
|
||||
const amount = Number(value ?? 0);
|
||||
return Number.isFinite(amount) ? amount.toFixed(2) : '0.00';
|
||||
}
|
||||
|
||||
const skuList = ref<MallSpuApi.Sku[]>([createEmptySku()]);
|
||||
|
||||
/** 批量添加 */
|
||||
@@ -501,17 +506,17 @@ defineExpose({
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="销售价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.price }}
|
||||
{{ formatDetailMoney(row.price) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="市场价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.marketPrice }}
|
||||
{{ formatDetailMoney(row.marketPrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="成本价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.costPrice }}
|
||||
{{ formatDetailMoney(row.costPrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="库存" width="80">
|
||||
@@ -532,12 +537,12 @@ defineExpose({
|
||||
<template v-if="formData?.subCommissionType">
|
||||
<VxeColumn align="center" title="一级返佣(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.firstBrokeragePrice }}
|
||||
{{ formatDetailMoney(row.firstBrokeragePrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="二级返佣(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.secondBrokeragePrice }}
|
||||
{{ formatDetailMoney(row.secondBrokeragePrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {
|
||||
RuleConfig,
|
||||
} from '#/views/mall/product/spu/components';
|
||||
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
@@ -34,6 +34,7 @@ const { closeCurrentTab } = useTabs();
|
||||
const activeTabName = ref('info');
|
||||
const formLoading = ref(false); // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const isDetail = ref(name === 'ProductSpuDetail'); // 是否查看详情
|
||||
const initializingForm = ref(false); // 详情回填时不触发 SKU 重置逻辑
|
||||
const skuListRef = ref(); // 商品属性列表 Ref
|
||||
|
||||
const formData = ref<MallSpuApi.Spu>({
|
||||
@@ -113,11 +114,20 @@ const [SkuForm, skuFormApi] = useVbenForm({
|
||||
schema: useSkuFormSchema(propertyList.value, isDetail.value),
|
||||
showDefaultActions: false,
|
||||
handleValuesChange: (values, fieldsChanged) => {
|
||||
if (fieldsChanged.includes('subCommissionType')) {
|
||||
if (initializingForm.value) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
fieldsChanged.includes('subCommissionType') &&
|
||||
values.subCommissionType !== formData.value.subCommissionType
|
||||
) {
|
||||
formData.value.subCommissionType = values.subCommissionType;
|
||||
handleChangeSubCommissionType();
|
||||
}
|
||||
if (fieldsChanged.includes('specType')) {
|
||||
if (
|
||||
fieldsChanged.includes('specType') &&
|
||||
values.specType !== formData.value.specType
|
||||
) {
|
||||
formData.value.specType = values.specType;
|
||||
handleChangeSpec();
|
||||
}
|
||||
@@ -235,22 +245,28 @@ async function getDetail() {
|
||||
// 金额转换:分转元
|
||||
res.skus = res.skus?.map((item) => ({
|
||||
...item,
|
||||
price: formatToFraction(item.price),
|
||||
marketPrice: formatToFraction(item.marketPrice),
|
||||
costPrice: formatToFraction(item.costPrice),
|
||||
firstBrokeragePrice: formatToFraction(item.firstBrokeragePrice),
|
||||
secondBrokeragePrice: formatToFraction(item.secondBrokeragePrice),
|
||||
price: Number(formatToFraction(item.price)),
|
||||
marketPrice: Number(formatToFraction(item.marketPrice)),
|
||||
costPrice: Number(formatToFraction(item.costPrice)),
|
||||
firstBrokeragePrice: Number(formatToFraction(item.firstBrokeragePrice)),
|
||||
secondBrokeragePrice: Number(
|
||||
formatToFraction(item.secondBrokeragePrice),
|
||||
),
|
||||
}));
|
||||
initializingForm.value = true;
|
||||
formData.value = res;
|
||||
// 初始化各表单值
|
||||
infoFormApi.setValues(res).then();
|
||||
skuFormApi.setValues(res).then();
|
||||
deliveryFormApi.setValues(res).then();
|
||||
descriptionFormApi.setValues(res).then();
|
||||
otherFormApi.setValues(res).then();
|
||||
// 将 SKU 的属性,整理成 PropertyAndValues 数组
|
||||
propertyList.value = getPropertyList(formData.value);
|
||||
// 初始化各表单值
|
||||
void infoFormApi.setValues(res);
|
||||
void skuFormApi.setValues(res);
|
||||
void deliveryFormApi.setValues(res);
|
||||
void descriptionFormApi.setValues(res);
|
||||
void otherFormApi.setValues(res);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
} finally {
|
||||
initializingForm.value = false;
|
||||
formLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,11 @@ function createEmptySku(): MallSpuApi.Sku {
|
||||
};
|
||||
}
|
||||
|
||||
function formatDetailMoney(value: null | number | string | undefined) {
|
||||
const amount = Number(value ?? 0);
|
||||
return Number.isFinite(amount) ? amount.toFixed(2) : '0.00';
|
||||
}
|
||||
|
||||
const skuList = ref<MallSpuApi.Sku[]>([createEmptySku()]);
|
||||
|
||||
/** 批量添加 */
|
||||
@@ -536,17 +541,17 @@ defineExpose({
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="销售价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.price }}
|
||||
{{ formatDetailMoney(row.price) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="市场价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.marketPrice }}
|
||||
{{ formatDetailMoney(row.marketPrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="成本价(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.costPrice }}
|
||||
{{ formatDetailMoney(row.costPrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="库存" width="80">
|
||||
@@ -567,12 +572,12 @@ defineExpose({
|
||||
<template v-if="formData?.subCommissionType">
|
||||
<VxeColumn align="center" title="一级返佣(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.firstBrokeragePrice }}
|
||||
{{ formatDetailMoney(row.firstBrokeragePrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
<VxeColumn align="center" title="二级返佣(元)" width="80">
|
||||
<template #default="{ row }">
|
||||
{{ row.secondBrokeragePrice }}
|
||||
{{ formatDetailMoney(row.secondBrokeragePrice) }}
|
||||
</template>
|
||||
</VxeColumn>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {
|
||||
RuleConfig,
|
||||
} from '#/views/mall/product/spu/components';
|
||||
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
@@ -34,6 +34,7 @@ const { closeCurrentTab } = useTabs();
|
||||
const activeTabName = ref('info');
|
||||
const formLoading = ref(false); // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const isDetail = ref(name === 'ProductSpuDetail'); // 是否查看详情
|
||||
const initializingForm = ref(false); // 详情回填时不触发 SKU 重置逻辑
|
||||
const skuListRef = ref(); // 商品属性列表 Ref
|
||||
|
||||
const formData = ref<MallSpuApi.Spu>({
|
||||
@@ -113,11 +114,20 @@ const [SkuForm, skuFormApi] = useVbenForm({
|
||||
schema: useSkuFormSchema(propertyList.value, isDetail.value),
|
||||
showDefaultActions: false,
|
||||
handleValuesChange: (values, fieldsChanged) => {
|
||||
if (fieldsChanged.includes('subCommissionType')) {
|
||||
if (initializingForm.value) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
fieldsChanged.includes('subCommissionType') &&
|
||||
values.subCommissionType !== formData.value.subCommissionType
|
||||
) {
|
||||
formData.value.subCommissionType = values.subCommissionType;
|
||||
handleChangeSubCommissionType();
|
||||
}
|
||||
if (fieldsChanged.includes('specType')) {
|
||||
if (
|
||||
fieldsChanged.includes('specType') &&
|
||||
values.specType !== formData.value.specType
|
||||
) {
|
||||
formData.value.specType = values.specType;
|
||||
handleChangeSpec();
|
||||
}
|
||||
@@ -235,22 +245,28 @@ async function getDetail() {
|
||||
// 金额转换:分转元
|
||||
res.skus = res.skus?.map((item) => ({
|
||||
...item,
|
||||
price: formatToFraction(item.price),
|
||||
marketPrice: formatToFraction(item.marketPrice),
|
||||
costPrice: formatToFraction(item.costPrice),
|
||||
firstBrokeragePrice: formatToFraction(item.firstBrokeragePrice),
|
||||
secondBrokeragePrice: formatToFraction(item.secondBrokeragePrice),
|
||||
price: Number(formatToFraction(item.price)),
|
||||
marketPrice: Number(formatToFraction(item.marketPrice)),
|
||||
costPrice: Number(formatToFraction(item.costPrice)),
|
||||
firstBrokeragePrice: Number(formatToFraction(item.firstBrokeragePrice)),
|
||||
secondBrokeragePrice: Number(
|
||||
formatToFraction(item.secondBrokeragePrice),
|
||||
),
|
||||
}));
|
||||
initializingForm.value = true;
|
||||
formData.value = res;
|
||||
// 初始化各表单值
|
||||
infoFormApi.setValues(res).then();
|
||||
skuFormApi.setValues(res).then();
|
||||
deliveryFormApi.setValues(res).then();
|
||||
descriptionFormApi.setValues(res).then();
|
||||
otherFormApi.setValues(res).then();
|
||||
// 将 SKU 的属性,整理成 PropertyAndValues 数组
|
||||
propertyList.value = getPropertyList(formData.value);
|
||||
// 初始化各表单值
|
||||
void infoFormApi.setValues(res);
|
||||
void skuFormApi.setValues(res);
|
||||
void deliveryFormApi.setValues(res);
|
||||
void descriptionFormApi.setValues(res);
|
||||
void otherFormApi.setValues(res);
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
} finally {
|
||||
initializingForm.value = false;
|
||||
formLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user