diff --git a/src/sku/README.md b/src/sku/README.md
index 29ac44055..338ae6218 100644
--- a/src/sku/README.md
+++ b/src/sku/README.md
@@ -141,6 +141,7 @@ export default {
| message-config | Message related config | *object* | `{}` | - |
| get-container | Return the mount node for sku | *string \| () => Element* | - | - |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `false` | 2.2.1 |
+| start-sale-num | Minimum quantity | *number* | `1` | 2.2.15 |
### Events
@@ -258,10 +259,10 @@ customStepperConfig: {
quotaText: 'only 5 can buy',
// custom callback when over limit
handleOverLimit: (data) => {
- const { action, limitType, quota, quotaUsed } = data;
+ const { action, limitType, quota, quotaUsed, startSaleNum } = data;
if (action === 'minus') {
- Toast('at least select one');
+ Toast(`at least select ${startSaleNum > 1 ? startSaleNum : 'one'}`);
} else if (action === 'plus') {
// const { LIMIT_TYPE } = Sku.skuConstants;
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
diff --git a/src/sku/README.zh-CN.md b/src/sku/README.zh-CN.md
index 6b1c13a30..c1c23b0a8 100644
--- a/src/sku/README.zh-CN.md
+++ b/src/sku/README.zh-CN.md
@@ -145,6 +145,7 @@ export default {
| initial-sku | 默认选中的 sku,具体参考高级用法 | *object* | `{}` | - |
| show-soldout-sku | 是否展示售罄的 sku,默认展示并置灰 | *boolean* | `true` | - |
| safe-area-inset-bottom | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `false` | 2.2.1 |
+| start-sale-num | 起售数量 | *number* | `1` | 2.2.15 |
### Events
@@ -270,10 +271,10 @@ customStepperConfig: {
quotaText: '每次限购xxx件',
// 自定义步进器超过限制时的回调
handleOverLimit: (data) => {
- const { action, limitType, quota, quotaUsed } = data;
+ const { action, limitType, quota, quotaUsed, startSaleNum } = data;
if (action === 'minus') {
- Toast('至少选择一件商品');
+ Toast(startSaleNum > 1 ? `${startSaleNum}件起售` : '至少选择一件商品');
} else if (action === 'plus') {
// const { LIMIT_TYPE } = Sku.skuConstants;
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
diff --git a/src/sku/Sku.js b/src/sku/Sku.js
index de78d83cc..14bd49804 100644
--- a/src/sku/Sku.js
+++ b/src/sku/Sku.js
@@ -45,6 +45,10 @@ export default createComponent({
type: Number,
default: 0
},
+ startSaleNum: {
+ type: Number,
+ default: 1
+ },
initialSku: {
type: Object,
default: () => ({})
@@ -236,22 +240,6 @@ export default createComponent({
];
},
- quotaText() {
- const { quotaText, hideQuotaText } = this.customStepperConfig;
-
- if (hideQuotaText) return '';
-
- let text = '';
-
- if (quotaText) {
- text = quotaText;
- } else if (this.quota > 0) {
- text = t('quotaLimit', this.quota);
- }
-
- return text;
- },
-
selectedText() {
if (this.selectedSkuComb) {
return `${t('selected')} ${this.selectedSkuValues.map(item => item.name).join(';')}`;
@@ -274,6 +262,7 @@ export default createComponent({
skuEventBus.$on('sku:numChange', this.onNumChange);
skuEventBus.$on('sku:previewImage', this.onPreviewImage);
skuEventBus.$on('sku:overLimit', this.onOverLimit);
+ skuEventBus.$on('sku:stepperState', this.onStepperState);
skuEventBus.$on('sku:addCart', this.onAddCart);
skuEventBus.$on('sku:buy', this.onBuy);
@@ -289,6 +278,8 @@ export default createComponent({
const { skuStepper } = this.$refs;
const { selectedNum } = this.initialSku;
const num = isDef(selectedNum) ? selectedNum : 1;
+ // 用来缓存不合法的情况
+ this.stepperError = null;
if (skuStepper) {
skuStepper.setCurrentNum(num);
@@ -409,18 +400,35 @@ export default createComponent({
}
if (action === 'minus') {
- Toast(t('minusTip'));
+ if (this.startSaleNum > 1) {
+ Toast(t('minusStartTip', this.startSaleNum));
+ } else {
+ Toast(t('minusTip'));
+ }
} else if (action === 'plus') {
if (limitType === QUOTA_LIMIT) {
- let msg = t('quotaLimit', quota);
- if (quotaUsed > 0) msg += `,${t('quotaCount', quotaUsed)}`;
- Toast(msg);
+ if (quotaUsed > 0) {
+ Toast(t('quotaUsedTip', quota, quotaUsed));
+ } else {
+ Toast(t('quotaTip', quota));
+ }
} else {
Toast(t('soldout'));
}
}
},
+ onStepperState(data) {
+ if (data.valid) {
+ this.stepperError = null;
+ } else {
+ this.stepperError = {
+ ...data,
+ action: 'plus',
+ };
+ }
+ },
+
onAddCart() {
this.onBuyOrAddCart('add-cart');
},
@@ -430,6 +438,10 @@ export default createComponent({
},
onBuyOrAddCart(type) {
+ // 有信息表示该sku根本不符合购买条件
+ if (this.stepperError) {
+ return this.onOverLimit(this.stepperError);
+ }
const error = this.validateSku();
if (error) {
Toast(error);
@@ -463,7 +475,6 @@ export default createComponent({
selectedSku,
selectedNum,
stepperTitle,
- hideQuotaText,
selectedSkuComb
} = this;
@@ -494,7 +505,6 @@ export default createComponent({
{!this.hideStock && (
{this.stockText}
- {!hideQuotaText && this.quotaText && ({this.quotaText})}
)}
{this.hasSku && !this.hideSelectedText && (
@@ -530,6 +540,7 @@ export default createComponent({
stock={this.stock}
quota={this.quota}
quotaUsed={this.quotaUsed}
+ startSaleNum={this.startSaleNum}
skuEventBus={skuEventBus}
selectedNum={selectedNum}
selectedSku={selectedSku}
@@ -537,6 +548,7 @@ export default createComponent({
skuStockNum={sku.stock_num}
disableStepperInput={this.disableStepperInput}
customStepperConfig={this.customStepperConfig}
+ hideQuotaText={this.hideQuotaText}
onChange={event => {
this.$emit('stepper-change', event);
}}
diff --git a/src/sku/components/SkuStepper.js b/src/sku/components/SkuStepper.js
index 28eca7c38..dcaa9de55 100644
--- a/src/sku/components/SkuStepper.js
+++ b/src/sku/components/SkuStepper.js
@@ -16,6 +16,7 @@ export default createComponent({
stepperTitle: String,
disableStepperInput: Boolean,
customStepperConfig: Object,
+ hideQuotaText: Boolean,
quota: {
type: Number,
default: 0
@@ -23,7 +24,11 @@ export default createComponent({
quotaUsed: {
type: Number,
default: 0
- }
+ },
+ startSaleNum: {
+ type: Number,
+ default: 1,
+ },
},
data() {
@@ -40,9 +45,17 @@ export default createComponent({
},
stepperLimit(limit) {
- if (limit < this.currentNum) {
+ if (limit < this.currentNum && this.stepperMinLimit <= limit) {
this.currentNum = limit;
}
+ this.checkState(this.stepperMinLimit, limit);
+ },
+
+ stepperMinLimit(start) {
+ if (start > this.currentNum || start > this.stepperLimit) {
+ this.currentNum = start;
+ }
+ this.checkState(start, this.stepperLimit);
}
},
@@ -62,7 +75,35 @@ export default createComponent({
}
return limit;
- }
+ },
+ stepperMinLimit() {
+ return this.startSaleNum < 1 ? 1 : this.startSaleNum;
+ },
+ quotaText() {
+ const { quotaText, hideQuotaText } = this.customStepperConfig;
+ if (hideQuotaText) return '';
+
+ let text = '';
+
+ if (quotaText) {
+ text = quotaText;
+ } else {
+ const textArr = [];
+ if (this.startSaleNum > 1) {
+ textArr.push(t('quotaStart', this.startSaleNum));
+ }
+ if (this.quota > 0) {
+ textArr.push(t('quotaLimit', this.quota));
+ }
+ text = textArr.join(t('comma'));
+ }
+
+ return text;
+ },
+ },
+
+ created() {
+ this.checkState(this.stepperMinLimit, this.stepperLimit);
},
methods: {
@@ -75,7 +116,8 @@ export default createComponent({
action,
limitType: this.limitType,
quota: this.quota,
- quotaUsed: this.quotaUsed
+ quotaUsed: this.quotaUsed,
+ startSaleNum: this.startSaleNum,
});
},
@@ -83,7 +125,27 @@ export default createComponent({
const { handleStepperChange } = this.customStepperConfig;
handleStepperChange && handleStepperChange(currentValue);
this.$emit('change', currentValue);
- }
+ },
+
+ checkState(min, max) {
+ // 如果选择小于起售,则强制变为起售
+ if (this.currentNum < min || min > max) {
+ this.currentNum = min;
+ } else if (this.currentNum > max) {
+ // 当前选择数量大于最大可选时,需要重置已选数量
+ this.currentNum = max;
+ }
+
+ this.skuEventBus.$emit('sku:stepperState', {
+ valid: min <= max,
+ min,
+ max,
+ limitType: this.limitType,
+ quota: this.quota,
+ quotaUsed: this.quotaUsed,
+ startSaleNum: this.startSaleNum,
+ });
+ },
},
render() {
@@ -94,11 +156,13 @@ export default createComponent({
+ {!this.hideQuotaText && this.quotaText && ({this.quotaText})}
);
diff --git a/src/sku/demo/data.js b/src/sku/demo/data.js
index 37df50828..c7674f10b 100644
--- a/src/sku/demo/data.js
+++ b/src/sku/demo/data.js
@@ -2,6 +2,7 @@ export default {
goods_id: '946755',
quota: 15,
quota_used: 0,
+ start_sale_num: 10,
goods_info: {
title: '测试商品',
picture:
diff --git a/src/sku/demo/index.vue b/src/sku/demo/index.vue
index 7e91966d1..b64802f40 100644
--- a/src/sku/demo/index.vue
+++ b/src/sku/demo/index.vue
@@ -11,6 +11,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
+ :start-sale-num="skuData.start_sale_num"
:close-on-click-overlay="closeOnClickOverlay"
:message-config="messageConfig"
:custom-sku-validator="customSkuValidator"
@@ -42,6 +43,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
+ :start-sale-num="skuData.start_sale_num"
:custom-stepper-config="customStepperConfig"
:message-config="messageConfig"
hide-quota-text
@@ -70,6 +72,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
+ :start-sale-num="skuData.start_sale_num"
:custom-stepper-config="customStepperConfig"
:message-config="messageConfig"
:show-soldout-sku="false"
@@ -99,6 +102,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
+ :start-sale-num="skuData.start_sale_num"
show-add-cart-btn
reset-stepper-on-hide
safe-area-inset-bottom
@@ -126,7 +130,7 @@
square
size="large"
type="danger"
- @click="props.skuEventBus.$emit('sku:buy')"
+ @click="skuEventBus.$emit('sku:buy')"
>
{{ $t('button2') }}
@@ -185,10 +189,10 @@ export default {
quotaText: '单次限购100件',
stockFormatter: (stock) => `剩余${stock}件`,
handleOverLimit: (data) => {
- const { action, limitType, quota } = data;
+ const { action, limitType, quota, startSaleNum = 1 } = data;
if (action === 'minus') {
- this.$toast('至少选择一件商品');
+ this.$toast(startSaleNum > 1 ? `${startSaleNum}件起售` : '至少选择一件商品');
} else if (action === 'plus') {
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
this.$toast(`限购${quota}件`);
diff --git a/src/sku/index.less b/src/sku/index.less
index 3ea21726d..beb8b2318 100644
--- a/src/sku/index.less
+++ b/src/sku/index.less
@@ -198,6 +198,7 @@
&-container {
height: 30px;
margin-right: 20px;
+ overflow: hidden;
}
}
@@ -208,6 +209,14 @@
float: left;
line-height: 30px;
}
+
+ &-quota {
+ display: inline-block;
+ float: right;
+ color: @red;
+ font-size: @font-size-sm;
+ line-height: 30px;
+ }
}
&__stock {
@@ -221,12 +230,6 @@
}
}
- &__quota {
- display: inline-block;
- color: @red;
- font-size: @font-size-sm;
- }
-
&-messages {
padding-bottom: @padding-xl;
diff --git a/src/sku/lang.ts b/src/sku/lang.ts
index 216c1dd06..90b5c1c1a 100644
--- a/src/sku/lang.ts
+++ b/src/sku/lang.ts
@@ -11,11 +11,12 @@ export default {
soldout: '库存不足',
originPrice: '原价',
minusTip: '至少选择一件',
+ minusStartTip: (start: number) => `${start}件起售`,
unavailable: '商品已经无法购买啦',
stock: '剩余',
stockUnit: '件',
- quotaLimit: (quota: number) => `每人限购${quota}件`,
- quotaCount: (count: number) => `你已购买${count}件`
+ quotaTip: (quota: number) => `每人限购${quota}件`,
+ quotaUsedTip: (quota: number, count: number) => `每人限购${quota}件,你已购买${count}件`
},
vanSkuActions: {
buy: '立即购买',
@@ -26,6 +27,9 @@ export default {
fail: '上传失败
重新上传'
},
vanSkuStepper: {
+ quotaLimit: (quota: number) => `限购${quota}件`,
+ quotaStart: (start: number) => `${start}件起售`,
+ comma: ',',
num: '购买数量'
},
vanSkuMessages: {