|
|
@@ -12,15 +12,15 @@
|
|
|
<view class="card min-card">
|
|
|
<view class="min-head">
|
|
|
<text class="label">自定义充值最低金额</text>
|
|
|
- <text class="min-tip">默认最低金额为100</text>
|
|
|
+ <text class="min-tip">默认为固定档位中的最低金额</text>
|
|
|
</view>
|
|
|
<view class="min-input-wrap">
|
|
|
<text class="currency">¥</text>
|
|
|
<input
|
|
|
class="min-input"
|
|
|
- type="digit"
|
|
|
+ type="number"
|
|
|
v-model="form.minAmount"
|
|
|
- placeholder="100"
|
|
|
+ :placeholder="String(lowestTierAmount || '')"
|
|
|
placeholder-class="placeholder"
|
|
|
@input="onMinAmountInput"
|
|
|
/>
|
|
|
@@ -94,27 +94,29 @@
|
|
|
<text class="form-label">充值金额</text>
|
|
|
<input
|
|
|
class="form-input"
|
|
|
- type="digit"
|
|
|
+ type="number"
|
|
|
v-model="tierForm.amount"
|
|
|
- placeholder="请点击输入"
|
|
|
+ placeholder="请输入正整数"
|
|
|
placeholder-class="form-placeholder"
|
|
|
+ @input="onTierAmountInput('amount', $event)"
|
|
|
/>
|
|
|
</view>
|
|
|
<view class="form-row">
|
|
|
<text class="form-label">赠送金额</text>
|
|
|
<input
|
|
|
class="form-input"
|
|
|
- type="digit"
|
|
|
+ type="number"
|
|
|
v-model="tierForm.giftAmount"
|
|
|
- placeholder="请点击输入"
|
|
|
+ placeholder="选填,默认0"
|
|
|
placeholder-class="form-placeholder"
|
|
|
+ @input="onTierAmountInput('giftAmount', $event)"
|
|
|
/>
|
|
|
</view>
|
|
|
<view class="form-row link-row" @click="openCouponSelect">
|
|
|
<text class="form-label">赠送优惠券</text>
|
|
|
<view class="link-right">
|
|
|
<text class="link-text" :class="{ active: couponSelectedCount > 0 }">
|
|
|
- {{ couponSelectedCount > 0 ? '已选择' : '请选择' }}
|
|
|
+ {{ couponSelectedCount > 0 ? `已选 ${couponSelectedCount} 张` : '去选择' }}
|
|
|
</text>
|
|
|
<u-icon name="arrow-right" color="#c0c4cc" size="14"></u-icon>
|
|
|
</view>
|
|
|
@@ -214,12 +216,8 @@
|
|
|
</view>
|
|
|
|
|
|
<view class="footer coupon-footer">
|
|
|
- <view
|
|
|
- class="save-btn"
|
|
|
- :class="{ disabled: tempCouponCount <= 0 }"
|
|
|
- @click="confirmCouponSelect"
|
|
|
- >
|
|
|
- {{ tempCouponCount > 0 ? `确定添加${tempCouponCount}张` : '确认添加' }}
|
|
|
+ <view class="save-btn" @click="confirmCouponSelect">
|
|
|
+ {{ tempCouponCount > 0 ? `确定选择(已选 ${tempCouponCount} 张)` : '确定选择' }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -237,6 +235,14 @@
|
|
|
return `t_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
|
|
|
}
|
|
|
|
|
|
+ /** 默认固定档位:档位1金额100、档位2金额200,赠送与优惠券均为0 */
|
|
|
+ function createDefaultTiers() {
|
|
|
+ return [
|
|
|
+ { id: createId(), amount: 100, giftAmount: 0, coupons: [] },
|
|
|
+ { id: createId(), amount: 200, giftAmount: 0, coupons: [] }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
function formatValidText(beginTime, endTime) {
|
|
|
if (!beginTime && !endTime) return '长期有效';
|
|
|
const begin = beginTime ? String(beginTime).slice(0, 10) : '';
|
|
|
@@ -245,6 +251,51 @@
|
|
|
return begin || end || '长期有效';
|
|
|
}
|
|
|
|
|
|
+ function isPlainAmount(val) {
|
|
|
+ return /^[\d.]+$/.test(String(val || '').trim());
|
|
|
+ }
|
|
|
+
|
|
|
+ function pickAmount(val) {
|
|
|
+ const matched = String(val || '').match(/[\d.]+/);
|
|
|
+ return matched ? matched[0] : '';
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 折扣券 / 满减券左侧面额与使用条件文案(接口多为纯数字,需补「元」「折」) */
|
|
|
+ function formatCouponTexts(item) {
|
|
|
+ const isDiscount = String(item.couponType) === '2';
|
|
|
+ const info = String(item.contentInfo || '').trim();
|
|
|
+ const cond = String(item.contentConditions || '').trim();
|
|
|
+ const infoNum = isPlainAmount(info) ? info : pickAmount(info);
|
|
|
+ const condNum = isPlainAmount(cond) ? cond : pickAmount(cond);
|
|
|
+ const noThreshold = !condNum || condNum === '0';
|
|
|
+
|
|
|
+ if (isDiscount) {
|
|
|
+ const display = infoNum ? `${infoNum}折` : info || '折扣';
|
|
|
+ const condition = noThreshold
|
|
|
+ ? '不限制条件使用'
|
|
|
+ : `满${condNum}元可使用`;
|
|
|
+ return { display, condition };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 满减:左侧「满X元 / 减Y元」
|
|
|
+ let display = '';
|
|
|
+ if (infoNum && condNum) {
|
|
|
+ display = `满${condNum}元\n减${infoNum}元`;
|
|
|
+ } else if (infoNum) {
|
|
|
+ display = `${infoNum}元`;
|
|
|
+ } else if (info) {
|
|
|
+ display = info
|
|
|
+ .replace(/满\s*([\d.]+)\s*元?/g, '满$1元')
|
|
|
+ .replace(/减\s*([\d.]+)\s*元?/g, '减$1元');
|
|
|
+ } else {
|
|
|
+ display = '优惠';
|
|
|
+ }
|
|
|
+ const condition = noThreshold
|
|
|
+ ? '不限制条件使用'
|
|
|
+ : `满${condNum}元可抵扣`;
|
|
|
+ return { display, condition };
|
|
|
+ }
|
|
|
+
|
|
|
export default {
|
|
|
components: {
|
|
|
ListScrollView
|
|
|
@@ -257,7 +308,7 @@
|
|
|
form: {
|
|
|
acceptShare: true,
|
|
|
minAmount: '100',
|
|
|
- tiers: []
|
|
|
+ tiers: createDefaultTiers()
|
|
|
},
|
|
|
tierVisible: false,
|
|
|
tierEditIndex: -1,
|
|
|
@@ -284,9 +335,17 @@
|
|
|
return gift > 0 || couponQty > 0;
|
|
|
});
|
|
|
},
|
|
|
+ /** 固定档位中的最低充值金额,用作自定义最低金额默认值 */
|
|
|
+ lowestTierAmount() {
|
|
|
+ const amounts = (this.form.tiers || [])
|
|
|
+ .map((t) => Number(t.amount))
|
|
|
+ .filter((n) => !Number.isNaN(n) && n > 0);
|
|
|
+ if (!amounts.length) return 0;
|
|
|
+ return Math.min(...amounts);
|
|
|
+ },
|
|
|
canSubmitTier() {
|
|
|
const amount = String(this.tierForm.amount || '').trim();
|
|
|
- return !!amount && Number(amount) > 0;
|
|
|
+ return !!amount && /^\d+$/.test(amount) && Number(amount) > 0;
|
|
|
},
|
|
|
tierFormTitle() {
|
|
|
if (this.tierEditIndex === -1) {
|
|
|
@@ -319,6 +378,13 @@
|
|
|
this.form.minAmount = val;
|
|
|
});
|
|
|
},
|
|
|
+ onTierAmountInput(field, e) {
|
|
|
+ const val = String((e && e.detail && e.detail.value) || this.tierForm[field] || '')
|
|
|
+ .replace(/[^\d]/g, '');
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$set(this.tierForm, field, val);
|
|
|
+ });
|
|
|
+ },
|
|
|
loadSettings() {
|
|
|
this.loading = true;
|
|
|
prepaidApi
|
|
|
@@ -331,21 +397,30 @@
|
|
|
const data = res.data.result;
|
|
|
this.configVersion = data.version;
|
|
|
const tiers = Array.isArray(data.tiers) ? data.tiers : [];
|
|
|
+ const mappedTiers = tiers.length
|
|
|
+ ? tiers.map((tier) => ({
|
|
|
+ id: tier.tierId || createId(),
|
|
|
+ amount: Number(tier.rechargeAmount) || 0,
|
|
|
+ giftAmount: Number(tier.giftAmount) || 0,
|
|
|
+ coupons: (tier.coupons || []).map((c) => ({
|
|
|
+ id: c.couponId,
|
|
|
+ name: c.couponName || '',
|
|
|
+ type: String(c.couponType) === '2' ? 'discount' : 'reduce',
|
|
|
+ qty: Number(c.quantity) || 1
|
|
|
+ }))
|
|
|
+ }))
|
|
|
+ : createDefaultTiers();
|
|
|
+ const lowest = mappedTiers
|
|
|
+ .map((t) => Number(t.amount))
|
|
|
+ .filter((n) => n > 0);
|
|
|
+ const defaultMin = lowest.length ? Math.min(...lowest) : 100;
|
|
|
this.form = {
|
|
|
acceptShare: data.acceptSharedPrepaid !== false,
|
|
|
minAmount:
|
|
|
- data.customMinAmount != null ? String(data.customMinAmount) : '100',
|
|
|
- tiers: tiers.map((tier) => ({
|
|
|
- id: tier.tierId || createId(),
|
|
|
- amount: Number(tier.rechargeAmount) || 0,
|
|
|
- giftAmount: Number(tier.giftAmount) || 0,
|
|
|
- coupons: (tier.coupons || []).map((c) => ({
|
|
|
- id: c.couponId,
|
|
|
- name: c.couponName || '',
|
|
|
- type: String(c.couponType) === '2' ? 'discount' : 'reduce',
|
|
|
- qty: Number(c.quantity) || 1
|
|
|
- }))
|
|
|
- }))
|
|
|
+ data.customMinAmount != null && data.customMinAmount !== ''
|
|
|
+ ? String(Math.floor(Number(data.customMinAmount)) || '')
|
|
|
+ : String(defaultMin),
|
|
|
+ tiers: mappedTiers
|
|
|
};
|
|
|
})
|
|
|
.catch(() => {
|
|
|
@@ -367,8 +442,9 @@
|
|
|
const item = this.form.tiers[index];
|
|
|
this.tierEditIndex = index;
|
|
|
this.tierForm = {
|
|
|
- amount: item.amount != null ? String(item.amount) : '',
|
|
|
- giftAmount: item.giftAmount != null ? String(item.giftAmount) : '',
|
|
|
+ amount: item.amount != null ? String(Math.floor(Number(item.amount)) || '') : '',
|
|
|
+ giftAmount:
|
|
|
+ item.giftAmount != null ? String(Math.floor(Number(item.giftAmount)) || 0) : '',
|
|
|
coupons: JSON.parse(JSON.stringify(item.coupons || []))
|
|
|
};
|
|
|
this.tierVisible = true;
|
|
|
@@ -377,6 +453,10 @@
|
|
|
this.tierVisible = false;
|
|
|
},
|
|
|
removeTier(index) {
|
|
|
+ if ((this.form.tiers || []).length <= 2) {
|
|
|
+ uni.showToast({ title: '至少保留2个固定充值档位', icon: 'none' });
|
|
|
+ return;
|
|
|
+ }
|
|
|
uni.showModal({
|
|
|
title: '提示',
|
|
|
content: '确认删除该充值档位吗?',
|
|
|
@@ -391,17 +471,17 @@
|
|
|
submitTier() {
|
|
|
if (!this.canSubmitTier) return;
|
|
|
const amountStr = String(this.tierForm.amount || '').trim();
|
|
|
- if (!/^\d+(\.\d{1,2})?$/.test(amountStr) || Number(amountStr) <= 0) {
|
|
|
- uni.showToast({ title: '充值金额须大于0', icon: 'none' });
|
|
|
+ if (!/^\d+$/.test(amountStr) || Number(amountStr) <= 0) {
|
|
|
+ uni.showToast({ title: '充值金额须为正整数', icon: 'none' });
|
|
|
return;
|
|
|
}
|
|
|
const amount = Number(amountStr);
|
|
|
const giftRaw = String(this.tierForm.giftAmount || '').trim();
|
|
|
- const giftAmount = giftRaw === '' ? 0 : Number(giftRaw);
|
|
|
- if (Number.isNaN(giftAmount) || giftAmount < 0) {
|
|
|
- uni.showToast({ title: '赠送金额格式不正确', icon: 'none' });
|
|
|
+ if (giftRaw !== '' && !/^\d+$/.test(giftRaw)) {
|
|
|
+ uni.showToast({ title: '赠送金额须为非负整数', icon: 'none' });
|
|
|
return;
|
|
|
}
|
|
|
+ const giftAmount = giftRaw === '' ? 0 : Number(giftRaw);
|
|
|
const payload = {
|
|
|
id: this.tierEditIndex === -1 ? createId() : this.form.tiers[this.tierEditIndex].id,
|
|
|
amount,
|
|
|
@@ -416,13 +496,12 @@
|
|
|
this.tierVisible = false;
|
|
|
},
|
|
|
mapCouponItem(item) {
|
|
|
- const type = String(item.couponType);
|
|
|
- const isDiscount = type === '2';
|
|
|
+ const { display, condition } = formatCouponTexts(item);
|
|
|
return {
|
|
|
id: item.couponId,
|
|
|
name: item.couponName || '',
|
|
|
- display: item.contentInfo || (isDiscount ? '折扣' : '优惠'),
|
|
|
- condition: item.contentConditions || '',
|
|
|
+ display,
|
|
|
+ condition,
|
|
|
validText: formatValidText(item.beginTime, item.endTime),
|
|
|
remainingQuantity: Number(item.remainingQuantity) || 0
|
|
|
};
|
|
|
@@ -517,6 +596,12 @@
|
|
|
return;
|
|
|
}
|
|
|
const amounts = this.form.tiers.map((t) => Number(t.amount) || 0);
|
|
|
+ for (let i = 0; i < amounts.length; i++) {
|
|
|
+ if (!Number.isInteger(amounts[i]) || amounts[i] <= 0) {
|
|
|
+ uni.showToast({ title: '档位充值金额须为正整数', icon: 'none' });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
for (let i = 1; i < amounts.length; i++) {
|
|
|
if (amounts[i] <= amounts[i - 1]) {
|
|
|
uni.showToast({ title: '档位充值金额须严格递增', icon: 'none' });
|
|
|
@@ -526,13 +611,24 @@
|
|
|
// 有赠送余额/优惠券时接口要求关闭自定义充值
|
|
|
const customAmountEnabled = !this.hasGiftConfig;
|
|
|
const minRaw = String(this.form.minAmount || '').trim();
|
|
|
- let customMinAmount = 100;
|
|
|
+ const lowest = this.lowestTierAmount;
|
|
|
+ let customMinAmount = lowest || 0;
|
|
|
if (minRaw !== '') {
|
|
|
+ if (!/^\d+$/.test(minRaw) || Number(minRaw) <= 0) {
|
|
|
+ uni.showToast({ title: '自定义最低金额须为正整数', icon: 'none' });
|
|
|
+ return;
|
|
|
+ }
|
|
|
customMinAmount = Number(minRaw);
|
|
|
- if (!customMinAmount || customMinAmount < 100) {
|
|
|
- uni.showToast({ title: '自定义最低金额不得低于100', icon: 'none' });
|
|
|
+ if (lowest && customMinAmount < lowest) {
|
|
|
+ uni.showToast({
|
|
|
+ title: `自定义最低金额不能低于最低档位(${lowest})`,
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
return;
|
|
|
}
|
|
|
+ } else if (!lowest) {
|
|
|
+ uni.showToast({ title: '请配置固定充值档位', icon: 'none' });
|
|
|
+ return;
|
|
|
}
|
|
|
const payload = {
|
|
|
acceptSharedPrepaid: !!this.form.acceptShare,
|
|
|
@@ -1046,7 +1142,8 @@
|
|
|
|
|
|
&.multi {
|
|
|
font-size: 26rpx;
|
|
|
- line-height: 1.35;
|
|
|
+ line-height: 1.45;
|
|
|
+ white-space: pre-line;
|
|
|
}
|
|
|
}
|
|
|
|