fix(会员价): SKU/详情透传 vip_price,网盘商品独立会员价组件

兼容 real_price 的 member_price 字段,避免会员价为 0 时开通条不展示。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
吴昊天 2026-10-26 12:04:39 +08:00
parent 9f476fd7c2
commit 300b1d8677
8 changed files with 294 additions and 209 deletions

View File

@ -558,15 +558,16 @@ class Handler extends BaseProductTypeHandler
$sukKey = implode(',', array_values($detail));
$productValue[$sukKey] = [
'suk' => $sukKey,
'price' => $sku['price'] ?? '0.00',
'stock' => $sku['stock'] ?? 0,
'image' => $sku['image'] ?? '',
'unique' => $sku['unique_code'] ?? '',
'cost' => $sku['cost'] ?? '0.00',
'ot_price' => $sku['original_price'] ?? '0.00',
'bar_code' => $sku['bar_code'] ?? '',
'is_show' => $sku['is_show'] ?? 1,
'suk' => $sukKey,
'price' => $sku['price'] ?? '0.00',
'vip_price' => $sku['vip_price'] ?? '0.00',
'stock' => $sku['stock'] ?? 0,
'image' => $sku['image'] ?? '',
'unique' => $sku['unique_code'] ?? '',
'cost' => $sku['cost'] ?? '0.00',
'ot_price' => $sku['original_price'] ?? '0.00',
'bar_code' => $sku['bar_code'] ?? '',
'is_show' => $sku['is_show'] ?? 1,
];
}
@ -588,12 +589,13 @@ class Handler extends BaseProductTypeHandler
?: $normalSkuDao->getOne(['product_id' => $productId, 'is_show' => 1]);
if (is_object($sku)) $sku = $sku->toArray();
$skuPrice = $sku['price'] ?? '0.00';
$skuStock = $sku['stock'] ?? 0;
$skuImage = $sku['image'] ?? '';
$skuUnique = $sku['unique_code'] ?? '';
$skuCost = $sku['cost'] ?? '0.00';
$skuOtPrice = $sku['original_price'] ?? '0.00';
$skuPrice = $sku['price'] ?? '0.00';
$skuVipPrice = $sku['vip_price'] ?? '0.00';
$skuStock = $sku['stock'] ?? 0;
$skuImage = $sku['image'] ?? '';
$skuUnique = $sku['unique_code'] ?? '';
$skuCost = $sku['cost'] ?? '0.00';
$skuOtPrice = $sku['original_price'] ?? '0.00';
$productAttr = [
[
@ -606,15 +608,16 @@ class Handler extends BaseProductTypeHandler
];
$productValue = [
'默认' => [
'suk' => '默认',
'price' => $skuPrice,
'stock' => $skuStock,
'image' => $skuImage,
'unique' => $skuUnique,
'cost' => $skuCost,
'ot_price' => $skuOtPrice,
'bar_code' => '',
'is_show' => 1,
'suk' => '默认',
'price' => $skuPrice,
'vip_price' => $skuVipPrice,
'stock' => $skuStock,
'image' => $skuImage,
'unique' => $skuUnique,
'cost' => $skuCost,
'ot_price' => $skuOtPrice,
'bar_code' => '',
'is_show' => 1,
],
];

View File

@ -443,12 +443,13 @@ class Handler extends BaseProductTypeHandler
} catch (\Throwable $e) {
$center = null;
}
$skuPrice = $center['price'] ?? '0.00';
$skuStock = $center['stock'] ?? 0;
$skuImage = $center['image'] ?? '';
$skuUnique = (string)$productId;
$skuCost = '0.00';
$skuOtPrice = $center['price'] ?? '0.00';
$skuPrice = $center['price'] ?? '0.00';
$skuVipPrice = $center['vip_price'] ?? '0.00';
$skuStock = $center['stock'] ?? 0;
$skuImage = $center['image'] ?? '';
$skuUnique = (string)$productId;
$skuCost = '0.00';
$skuOtPrice = $center['price'] ?? '0.00';
$productAttr = [
[
@ -463,6 +464,7 @@ class Handler extends BaseProductTypeHandler
'默认' => [
'suk' => '默认',
'price' => $skuPrice,
'vip_price' => $skuVipPrice,
'stock' => $skuStock,
'image' => $skuImage,
'unique' => $skuUnique,
@ -510,6 +512,7 @@ class Handler extends BaseProductTypeHandler
$productValue[$suk] = [
'suk' => $suk,
'price' => $sku['price'] ?? '0.00',
'vip_price' => $sku['vip_price'] ?? '0.00',
'stock' => $sku['stock'] ?? 0,
'image' => $skuImage,
'unique' => (string)($sku['id'] ?? ''),

View File

@ -70,18 +70,6 @@
:max="9999999999"
class="priceBox input-number-unit-class"
class-unit="元"
@change="changeVipPrice(0, 'oneFormValidate')"
></el-input-number>
</template>
<template v-else-if="item.slot === 'vip_proportion'">
<el-input-number
:controls="false"
v-model="oneFormValidate[0].vip_proportion"
:min="0"
:max="9999999999"
class="priceBox input-number-unit-class"
class-unit="%"
@change="changeDiscount(0, 'oneFormValidate')"
></el-input-number>
</template>
</template>
@ -100,20 +88,6 @@
class-unit="元"
:model-value="manyVipPrice"
@update:model-value="(val) => emit('update:manyVipPrice', val)"
@focus="emit('update:manyVipDiscount', undefined)"
></el-input-number>
</span>
<span class="brokerage" v-if="formValidate.is_vip == 1">
会员折扣:<el-input-number
:controls="false"
placeholder="请输入折扣比例"
:min="0"
:max="9999999999"
class="columnsBox input_width input-number-unit-class"
class-unit="%"
:model-value="manyVipDiscount"
@update:model-value="(val) => emit('update:manyVipDiscount', val)"
@focus="emit('update:manyVipPrice', undefined)"
></el-input-number>
</span>
<el-button type="primary" v-db-click @click="brokerageSetUp">批量设置</el-button>
@ -177,23 +151,6 @@
updateManyFormValue(scope.$index + 1, 'vip_price', val);
}
"
@change="changeVipPrice(scope.$index + 1)"
></el-input-number>
</template>
<template v-else-if="item.slot === 'vip_proportion'">
<el-input-number
:controls="false"
:model-value="manyFormValidate[scope.$index + 1].vip_proportion"
:min="0"
:max="9999999999"
class="priceBox input-number-unit-class"
class-unit="%"
@update:model-value="
(val) => {
updateManyFormValue(scope.$index + 1, 'vip_proportion', val);
}
"
@change="changeDiscount(scope.$index + 1)"
></el-input-number>
</template>
</template>
@ -233,19 +190,12 @@ const props = defineProps({
type: Number,
default: undefined,
},
manyVipDiscount: {
type: Number,
default: undefined,
},
});
const emit = defineEmits([
'checkAllGroupChange',
'changeVipPrice',
'changeDiscount',
'brokerageSetUp',
'update:manyVipPrice',
'update:manyVipDiscount',
'update:manyFormValidate',
]);
@ -255,12 +205,6 @@ function checkAllGroupChange(val) {
function onVipChange() {
emit('checkAllGroupChange');
}
function changeVipPrice(index, type) {
emit('changeVipPrice', index, type);
}
function changeDiscount(index, type) {
emit('changeDiscount', index, type);
}
function updateManyFormValue(index, key, value) {
const newData = props.manyFormValidate.map((item, itemIndex) =>
itemIndex === index ? { ...item, [key]: value } : item,

View File

@ -106,10 +106,7 @@
:columnsInstall="columnsInstall"
:columnsInstal2="columnsInstal2"
v-model:manyVipPrice="manyVipPrice"
v-model:manyVipDiscount="manyVipDiscount"
@checkAllGroupChange="checkAllGroupChange"
@changeVipPrice="changeVipPrice"
@changeDiscount="changeDiscount"
@brokerageSetUp="brokerageSetUp"
></price-commission>
@ -465,7 +462,6 @@ const picTit = ref('');
const tableIndex = ref(0);
const ruleValidate = RuleValidate;
const manyVipPrice = ref(undefined);
const manyVipDiscount = ref(undefined);
const upload = reactive({
videoIng: false, // 是否显示进度条;
});
@ -486,12 +482,6 @@ const member = [
align: 'center',
width: 95,
},
{
title: '会员折扣',
slot: 'vip_proportion',
align: 'center',
width: 95,
},
];
const columnsInstalM = ref([]);
const moveIndex = ref('');
@ -794,10 +784,6 @@ function infoData(data, isCopy) {
formValidate.value.cate_id = cate_id;
if (data.attr) {
oneFormValidate.value = [data.attr];
oneFormValidate.value[0].vip_proportion = (
(oneFormValidate.value[0].vip_price / oneFormValidate.value[0].price) *
100
).toFixed(2);
oneFormValidate.value[0].weight = data.weight ?? 0;
oneFormValidate.value[0].volume = data.volume ?? 0;
}
@ -887,19 +873,6 @@ function see(data, name, index) {
goodsCoupon.value.isTemplate = true;
goodsCoupon.value.tableList(3);
}
// 修改分佣比例
function changeDiscount(index, type = 'manyFormValidate') {
// 根据分佣比例 vip_proportion 修改会员价,写回数字(字符串会破坏 el-input-number 输入)
formTable(type)[index].vip_price = Number(
(formTable(type)[index].price * (formTable(type)[index].vip_proportion / 100)).toFixed(2),
);
}
// 修改会员价
function changeVipPrice(index, type = 'manyFormValidate') {
// 售价为 0 时无法反推折扣,置 0 防止 Infinity 被钳制成极大值写回
const row = formTable(type)[index];
row.vip_proportion = row.price > 0 ? Number(((row.vip_price / row.price) * 100).toFixed(2)) : 0;
}
// 添加优惠券
function addGoodsCoupon(index, name) {
tabIndex.value = index;
@ -1015,23 +988,13 @@ function userSearchs() {
function addRule() {
addattr.value.modal = true;
}
// 批量设置会员价/会员折扣(商品页已不再设置佣金)
// 批量设置会员价(商品页已不再设置佣金/会员折扣)
function brokerageSetUp() {
if (manyVipPrice.value == undefined && manyVipDiscount.value == undefined) {
return ElMessage.error('请填写会员价或会员折扣后进行批量添加');
}
if (manyVipPrice.value != undefined && manyVipDiscount.value != undefined) {
return ElMessage.error('会员价和会员折扣只能二选一添加');
if (!(manyVipPrice.value > 0)) {
return ElMessage.error('请填写会员价后进行批量添加');
}
for (let val of manyFormValidate.value) {
if (manyVipPrice.value != undefined) {
val['vip_price'] = manyVipPrice.value;
// 售价为 0 时无法反推折扣,置 0 防止 Infinity
val['vip_proportion'] = val.price > 0 ? Number(((val.vip_price / val.price) * 100).toFixed(2)) : 0;
} else {
val['vip_proportion'] = manyVipDiscount.value;
val['vip_price'] = Number((val.price * (manyVipDiscount.value / 100)).toFixed(2));
}
val.vip_price = manyVipPrice.value;
}
}
// 批量设置会员价

View File

@ -91,21 +91,16 @@
@getEditorContent="getEditorContent"
></product-detail>
<!-- 会员价/佣金 -->
<!-- 会员价 -->
<price-commission
v-show="currentTab === '4'"
:formValidate="formValidate"
:oneFormValidate="oneFormValidate"
:manyFormValidate="manyFormValidate"
v-model:manyFormValidate="manyFormValidate"
:columnsInstall="columnsInstall"
:columnsInstal2="columnsInstal2"
v-model:manyBrokerage="manyBrokerage"
v-model:manyBrokerageTwo="manyBrokerageTwo"
v-model:manyVipPrice="manyVipPrice"
v-model:manyVipDiscount="manyVipDiscount"
@checkAllGroupChange="checkAllGroupChange"
@changeVipPrice="changeVipPrice"
@changeDiscount="changeDiscount"
@brokerageSetUp="brokerageSetUp"
></price-commission>
@ -231,7 +226,7 @@ import goodsList from '@/components/goodsList/index';
import BasicInfo from '../../../../pages/product/productAdd/components/BasicInfo.vue';
import SpecStock from '../../../../pages/product/productAdd/components/SpecStock.vue';
import ProductDetail from '../../../../pages/product/productAdd/components/ProductDetail.vue';
import PriceCommission from '../../../../pages/product/productAdd/components/PriceCommission.vue';
import PriceCommission from './components/PriceCommission.vue';
import MarketingSetting from '../../../../pages/product/productAdd/components/MarketingSetting.vue';
import OtherSetting from '../../../../pages/product/productAdd/components/OtherSetting.vue';
import LogisticsSetting from '../../../../pages/product/productAdd/components/LogisticsSetting.vue';
@ -281,7 +276,7 @@ const headTab = ref([
{ tit: '基础信息', name: '1' },
{ tit: '规格库存', name: '2' },
{ tit: '商品详情', name: '3' },
{ tit: '会员价/佣金', name: '4' },
{ tit: '会员价', name: '4' },
{ tit: '营销设置', name: '5' },
{ tit: '其他设置', name: '6' },
]);
@ -429,21 +424,11 @@ const dataLabel = ref([]);
const labelShow = ref(false);
const tagShow = ref(false);
const activity = ref({ 默认: 'red', 秒杀: 'blue', 砍价: 'green', 拼团: 'yellow' });
// 会员/佣金
const manyBrokerage = ref(undefined);
const manyBrokerageTwo = ref(undefined);
// 会员价
const manyVipPrice = ref(undefined);
const manyVipDiscount = ref(undefined);
const columnsInstall = ref([]);
const columnsInstal2 = ref([]);
const rakeBack = [
{ title: '一级返佣(元)', slot: 'brokerage', align: 'center', width: 95 },
{ title: '二级返佣(元)', slot: 'brokerage_two', align: 'center', width: 95 },
];
const member = [
{ title: '会员价', slot: 'vip_price', align: 'center', width: 95 },
{ title: '会员折扣', slot: 'vip_proportion', align: 'center', width: 95 },
];
const member = [{ title: '会员价', slot: 'vip_price', align: 'center', width: 95 }];
const columnsInstalM = ref([]);
// 商品标签
const goods_modals = ref(false);
@ -541,9 +526,9 @@ async function loadProduct() {
}
// 商品详情回显
contents.value = data.description || '';
// 触发 checkAllGroup 构建会员价/佣金表格列
// 触发 checkAllGroup 构建会员价表格列
setTimeout(() => {
checkAllGroup(formValidate.value.is_sub);
checkAllGroup();
}, 500);
} catch (e) {
ElMessage.error('加载商品信息失败');
@ -1079,59 +1064,27 @@ function addGoodsCoupon(index, name) {}
function getEditorContent(data) {
content.value = data;
}
// ----- 会员价/佣金 -----
// ----- 会员价 -----
function checkAllGroupChange() {
checkAllGroup();
}
function checkAllGroup() {
let endLength = attrs.value.length + 3;
const hasCommission = formValidate.value.is_sub == 1;
const hasVip = formValidate.value.is_vip == 1;
if (formValidate.value.spec_type === 0) {
if (hasCommission && hasVip) columnsInstall.value = columns2.slice(0, endLength).concat(rakeBack).concat(member);
else if (hasVip) columnsInstall.value = columns2.slice(0, endLength).concat(member);
else if (hasCommission) columnsInstall.value = columns2.slice(0, endLength).concat(rakeBack);
else columnsInstall.value = columns2.slice(0, endLength);
columnsInstall.value = hasVip ? columns2.slice(0, endLength).concat(member) : columns2.slice(0, endLength);
} else {
if (hasCommission && hasVip)
columnsInstal2.value = columnsInstalM.value
.slice(0, endLength + 1)
.concat(rakeBack)
.concat(member);
else if (hasVip) columnsInstal2.value = columnsInstalM.value.slice(0, endLength).concat(member);
else if (hasCommission) columnsInstal2.value = columnsInstalM.value.slice(0, endLength).concat(rakeBack);
else columnsInstal2.value = columnsInstalM.value.slice(0, endLength);
columnsInstal2.value = hasVip
? columnsInstalM.value.slice(0, endLength).concat(member)
: columnsInstalM.value.slice(0, endLength);
}
}
function changeDiscount(index, type = 'manyFormValidate') {
const list = type === 'oneFormValidate' ? oneFormValidate.value : manyFormValidate.value;
list[index].vip_price = (list[index].price * (list[index].vip_proportion / 100)).toFixed(2);
}
function changeVipPrice(index, type = 'manyFormValidate') {
const list = type === 'oneFormValidate' ? oneFormValidate.value : manyFormValidate.value;
list[index].vip_proportion = ((list[index].vip_price / list[index].price) * 100).toFixed(2);
}
function brokerageSetUp() {
if (formValidate.value.is_sub == 1) {
if (manyBrokerage.value <= 0 || manyBrokerageTwo.value <= 0) return ElMessage.error('请填写返佣金额后进行批量添加');
}
if (formValidate.value.is_vip == 1) {
if (manyVipPrice.value <= 0) return ElMessage.error('请填写会员价后进行批量添加');
}
if (formValidate.value.is_sub == 1 && formValidate.value.is_vip == 1) {
if (manyBrokerage.value <= 0 || manyBrokerageTwo.value <= 0) return ElMessage.error('请填写完金额后进行批量添加');
if (manyVipPrice.value > 0 && manyVipDiscount.value > 0) return ElMessage.error('会员价和会员折扣只能二选一添加');
if (!(manyVipPrice.value > 0)) {
return ElMessage.error('请填写会员价后进行批量添加');
}
for (let val of manyFormValidate.value) {
manyBrokerage.value !== undefined && (val['brokerage'] = manyBrokerage.value);
manyBrokerageTwo.value !== undefined && (val['brokerage_two'] = manyBrokerageTwo.value);
if (manyVipPrice.value !== undefined) {
val['vip_price'] = manyVipPrice.value;
val['vip_proportion'] = ((val.vip_price / val.price) * 100).toFixed(2);
} else if (manyVipDiscount.value !== undefined) {
val['vip_proportion'] = manyVipDiscount.value;
val['vip_price'] = (val.price * (manyVipDiscount.value / 100)).toFixed(2);
}
val.vip_price = manyVipPrice.value;
}
}
// ----- 营销设置 -----
@ -1255,8 +1208,8 @@ function handleSubmit() {
if (!formValidate.value.cate_id.length) return ElMessage.warning('请选择商品分类');
if (!formValidate.value.slider_image.length) return ElMessage.warning('请上传商品图片');
// 会员价/佣金验证
if (formValidate.value.is_sub == 1 || formValidate.value.is_vip == 1) {
// 会员价验证
if (formValidate.value.is_vip == 1) {
let item;
if (formValidate.value.spec_type === 0) {
item = JSON.parse(JSON.stringify(oneFormValidate.value));
@ -1264,11 +1217,9 @@ function handleSubmit() {
item = JSON.parse(JSON.stringify(manyFormValidate.value));
item.shift();
}
if (formValidate.value.is_vip == 1) {
for (let i = 0; i < item.length; i++) {
if (item[i].vip_price === null || item[i].vip_price <= 0) {
return ElMessage.error('营销设置-会员价不能为空或0');
}
for (let i = 0; i < item.length; i++) {
if (item[i].vip_price === null || item[i].vip_price <= 0) {
return ElMessage.error('会员价不能为空或0');
}
}
}
@ -1328,9 +1279,10 @@ function handleSubmit() {
custom_form: formValidate.value.custom_form || [],
coupon_ids: formValidate.value.coupon_ids || [],
label_list: formValidate.value.label_list || [],
is_sub: formValidate.value.is_sub ?? 0,
// 网盘商品页不再设置分销,保存时统一关闭
is_sub: 0,
presale_time: formValidate.value.presale_time || [],
// VIP/佣金
// 会员价
oneFormValidate: oneFormValidate.value || [],
manyFormValidate: manyFormValidate.value || [],
min_qty: formValidate.value.min_qty || 1,

View File

@ -0,0 +1,213 @@
<template>
<!-- 网盘商品:仅会员价(无分销、无会员折扣) -->
<el-row>
<el-col :span="24">
<el-form-item label="付费会员专属:">
<el-radio-group v-model="formValidate.vip_product">
<el-radio :label="0" :value="0">不限制(所有人可见可买)</el-radio>
<el-radio :label="1" :value="1">仅会员可见可买</el-radio>
<el-radio :label="2" :value="2">所有人可见仅会员可买</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="会员价设置:">
<el-checkbox v-model="formValidate.is_vip" :true-value="1" :false-value="0" @change="checkAllGroupChange"
>付费会员价</el-checkbox
>
</el-form-item>
</el-col>
<el-col :span="24" v-if="formValidate.is_vip == 1">
<!-- 单规格会员价 -->
<el-form-item label="商品属性:" v-if="formValidate.spec_type === 0">
<el-table :data="oneFormValidate">
<el-table-column
:label="item.title"
:min-width="item.minWidth"
v-for="(item, index) in columnsInstall"
:key="index"
>
<template #default="scope">
<template v-if="item.key">
<div>
<span>{{ scope.row[item.key] }}</span>
</div>
</template>
<template v-else-if="item.slot === 'pic'">
<div class="pictrue pictrueTab">
<img v-lazy="oneFormValidate[0].pic" />
</div>
</template>
<template v-else-if="item.slot === 'price'">
<span>{{ oneFormValidate[0].price }}</span>
</template>
<template v-else-if="item.slot === 'cost'">
<span>{{ oneFormValidate[0].cost }}</span>
</template>
<template v-else-if="item.slot === 'ot_price'">
<span>{{ oneFormValidate[0].ot_price }}</span>
</template>
<template v-else-if="item.slot === 'stock'">
<span>{{ oneFormValidate[0].stock }}</span>
</template>
<template v-else-if="item.slot === 'bar_code'">
<span>{{ oneFormValidate[0].bar_code }}</span>
</template>
<template v-else-if="item.slot === 'bar_code_number'">
<span>{{ oneFormValidate[0].bar_code_number }}</span>
</template>
<template v-else-if="item.slot === 'weight'">
<span>{{ oneFormValidate[0].weight }}</span>
</template>
<template v-else-if="item.slot === 'vip_price'">
<el-input-number
:controls="false"
v-model="oneFormValidate[0].vip_price"
:min="0"
:max="9999999999"
class="priceBox input-number-unit-class"
class-unit="元"
></el-input-number>
</template>
</template>
</el-table-column>
</el-table>
</el-form-item>
<!-- 多规格批量设置会员价 -->
<el-form-item label="批量设置:" v-if="formValidate.spec_type === 1">
<span class="brokerage">
会员价:<el-input-number
:controls="false"
placeholder="请输入会员价"
:min="0"
:max="9999999999"
class="columnsBox input_width input-number-unit-class"
class-unit="元"
:model-value="manyVipPrice"
@update:model-value="(val) => emit('update:manyVipPrice', val)"
></el-input-number>
</span>
<el-button type="primary" v-db-click @click="brokerageSetUp">批量设置</el-button>
</el-form-item>
<el-form-item
label="商品属性:"
v-if="formValidate.spec_type == 1 && manyFormValidate.length && columnsInstal2"
>
<el-table :data="manyFormValidate.slice(1)">
<el-table-column
:label="item.title"
:min-width="item.minWidth"
v-for="(item, index) in columnsInstal2"
:key="index"
>
<template #default="scope">
<template v-if="item.key">
<div>
<span>{{ scope.row.detail[item.key] }}</span>
</div>
</template>
<template v-else-if="item.slot === 'pic'">
<div class="pictrue pictrueTab">
<img v-lazy="manyFormValidate[scope.$index + 1].pic" />
</div>
</template>
<template v-else-if="item.slot === 'price'">
<span>{{ manyFormValidate[scope.$index + 1].price }}</span>
</template>
<template v-else-if="item.slot === 'cost'">
<span>{{ manyFormValidate[scope.$index + 1].cost }}</span>
</template>
<template v-else-if="item.slot === 'ot_price'">
<span>{{ manyFormValidate[scope.$index + 1].ot_price }}</span>
</template>
<template v-else-if="item.slot === 'stock'">
<span>{{ manyFormValidate[scope.$index + 1].stock }}</span>
</template>
<template v-else-if="item.slot === 'bar_code'">
<span>{{ manyFormValidate[scope.$index + 1].bar_code }}</span>
</template>
<template v-else-if="item.slot === 'bar_code_number'">
<span>{{ manyFormValidate[scope.$index + 1].bar_code_number }}</span>
</template>
<template v-else-if="item.slot === 'weight'">
<span>{{ manyFormValidate[scope.$index + 1].weight }}</span>
</template>
<template v-else-if="item.slot === 'volume'">
<span>{{ manyFormValidate[scope.$index + 1].volume }}</span>
</template>
<template v-else-if="item.slot === 'vip_price'">
<el-input-number
:controls="false"
:model-value="manyFormValidate[scope.$index + 1].vip_price"
:min="0"
:max="9999999999"
class="priceBox input-number-unit-class"
class-unit="元"
@update:model-value="
(val) => {
updateManyFormValue(scope.$index + 1, 'vip_price', val);
}
"
></el-input-number>
</template>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
</el-row>
</template>
<script setup>
defineOptions({ name: 'VirtualPriceCommission' });
const props = defineProps({
formValidate: {
type: Object,
required: true,
},
oneFormValidate: {
type: Array,
required: true,
},
manyFormValidate: {
type: Array,
required: true,
},
columnsInstall: {
type: Array,
required: true,
},
columnsInstal2: {
type: Array,
required: true,
},
manyVipPrice: {
type: Number,
default: undefined,
},
});
const emit = defineEmits([
'checkAllGroupChange',
'brokerageSetUp',
'update:manyVipPrice',
'update:manyFormValidate',
]);
function checkAllGroupChange(val) {
emit('checkAllGroupChange', val);
}
function updateManyFormValue(index, key, value) {
const newData = props.manyFormValidate.map((item, itemIndex) =>
itemIndex === index ? { ...item, [key]: value } : item,
);
emit('update:manyFormValidate', newData);
}
function brokerageSetUp() {
emit('brokerageSetUp');
}
</script>
<style lang="scss" scoped>
@use '../../../../product/productAdd/productAdd.scss' as *;
</style>

View File

@ -659,11 +659,13 @@ const modalRefs = {
// ---------- computed ----------
const isShowPaidVip = computed(() => {
let s =
!is_money_level.value &&
storeInfo.value.vip_price &&
storeInfo.value.is_vip;
return !!s;
// 非付费会员才展示「开通 SVIP 预计省」;会员价来自 storeInfo 或 realPrice 的 member_price
const vipPrice =
Number(storeInfo.value.vip_price) ||
Number(realPriceData.value.member_price) ||
Number(realPriceData.value.vip_price) ||
0;
return !is_money_level.value && !!storeInfo.value.is_vip && vipPrice > 0;
});
/**
* 加购模式:cart(双按钮)| direct(单按钮直接下单)
@ -1106,7 +1108,11 @@ function ChangeAttr(res) {
}
function setRealPrice(productId, unique) {
realPrice(productId, unique).then((res) => {
realPriceData.value = res.data;
// 统一补齐 vip_price,供 DIY 价格区 / 开通会员条使用(接口字段名为 member_price)
realPriceData.value = {
...res.data,
vip_price: res.data.member_price || res.data.vip_price || 0,
};
attr.productSelect["price"] = res.data.real_price;
attr.productSelect["vip_price"] = res.data.member_price;
ot_price.value = res.data.ot_price;

View File

@ -414,7 +414,7 @@
</view>
</view>
<view
>{{ $t(`预售结束后`) }} {{ productData.presale_day }}
>{{ $t(`预售结束后`) }} {{ productData.presale_day || 1 }}
{{ $t(`天内发货`) }}</view
>
</view>
@ -470,7 +470,8 @@ const displayInfo = computed(() => {
let price = props.priceData.price || "0.00";
let real_price = props.priceData.real_price || "0.00";
let ot_price = props.priceData.ot_price || "0.00";
let vip_price = props.priceData.vip_price;
// real_price 接口字段为 member_price,详情 storeInfo/SKU 为 vip_price,两端兼容
let vip_price = props.priceData.vip_price || props.priceData.member_price || 0;
let stock = props.productData.stock || 0;
let fsales = props.productData.fsales || 0;
let unit_name = props.productData.unit_name || "";
@ -481,14 +482,14 @@ const displayInfo = computed(() => {
if (sku.price) price = sku.price;
if (sku.real_price) price = sku.real_price;
if (sku.ot_price) ot_price = sku.ot_price;
if (sku.vip_price) vip_price = sku.vip_price;
if (Number(sku.vip_price) > 0) vip_price = sku.vip_price;
if (sku.stock || sku.stock === 0) stock = sku.stock;
}
}
return {
price,
ot_price,
vip_price,
vip_price: Number(vip_price) > 0 ? vip_price : 0,
stock,
fsales,
unit_name,