feat(支付): 重构支付方式逻辑以支持店铺模式配置

新增支付方式映射文件,支持根据店铺模式显示不同支付选项
重构结算组件,动态显示支持的支付方式并处理支付逻辑
在商品列表选择店铺时保存选中店铺信息
This commit is contained in:
dzq 2025-06-21 16:33:17 +08:00
parent 39820a036d
commit 6e49347de2
4 changed files with 99 additions and 68 deletions

View File

@ -0,0 +1,14 @@
export const paymentMethodOptions = [
{ label: '微信支付', value: 0, type: 'primary' },
{ label: '借呗支付', value: 1, type: 'success' },
{ label: '要呗支付', value: 2, type: 'info' },
{ label: '余额支付', value: 3, type: 'warning' },
];
export const modeToPaymentMethodMap: Record<number, number[]> = {
0: [0],
1: [0, 1],
2: [0, 1],
3: [0],
4: [2],
};

View File

@ -61,6 +61,7 @@ const showAb98BindPopup = ref(false);
function handleShopSelect(selectedShopId: number) {
shopId.value = selectedShopId;
showShopList.value = false;
productStore.setSelectedShop(shopList.value.find(shop => shop.shopId === selectedShopId)!);
productStore.getGoods(selectedShopId);
cartStore.clearCart();
activeCategory.value = 0;

View File

@ -1,25 +1,42 @@
<script setup lang="ts">
import { useCartStore } from "@/pinia/stores/cart"
import { useWxStore } from "@/pinia/stores/wx"
import { useAb98UserStore } from '@/pinia/stores/ab98-user'
import { storeToRefs } from "pinia"
import { showConfirmDialog } from "vant"
import { submitOrderApi } from "@/common/apis/shop"
import type { SubmitOrderRequestData, WxJsApiPreCreateResponse } from "@/common/apis/shop/type"
import { useRouter } from 'vue-router'
import { useCartStore } from "@/pinia/stores/cart";
import { useWxStore } from "@/pinia/stores/wx";
import { useAb98UserStore } from '@/pinia/stores/ab98-user';
import { storeToRefs } from "pinia";
import { showConfirmDialog } from "vant";
import { submitOrderApi } from "@/common/apis/shop";
import type { SubmitOrderRequestData, WxJsApiPreCreateResponse } from "@/common/apis/shop/type";
import { useRouter } from 'vue-router';
import { useProductStore } from "@/pinia/stores/product";
//
import { paymentMethodOptions, modeToPaymentMethodMap } from "@/common/utils/maps/payment";
const router = useRouter()
const router = useRouter();
const cartStore = useCartStore()
const { cartItems, totalPrice } = storeToRefs(cartStore)
const cartStore = useCartStore();
const { cartItems, totalPrice } = storeToRefs(cartStore);
const wxStore = useWxStore()
const { openid, balance, corpidLogin, userid: qyUserid, name: qyName } = storeToRefs(wxStore)
const wxStore = useWxStore();
const { openid, balance, corpidLogin, userid: qyUserid, name: qyName } = storeToRefs(wxStore);
const ab98UserStore = useAb98UserStore()
const { tel, userid: ab98Userid, name } = storeToRefs(ab98UserStore)
const ab98UserStore = useAb98UserStore();
const { tel, userid: ab98Userid, name } = storeToRefs(ab98UserStore);
const selectedPayment = ref<'wechat' | 'balance' | 'approval'>('wechat');
const productStore = useProductStore();
//
const supportedPayments = computed(() => {
const shopMode = productStore.selectedShop?.mode || 0;
const allowedValues = modeToPaymentMethodMap[shopMode] || [];
//
// 1.
// 2. (0)
return paymentMethodOptions.filter(option => allowedValues.includes(option.value)
&& (option.value !== 0 || !corpidLogin.value));
});
//
const selectedPayment = ref<string>(supportedPayments.value[0]?.value.toString() || '0');
const contact = ref("");
const applyRemark = ref("");
const submitting = ref(false);
@ -28,28 +45,13 @@ const isApproval = computed(() => {
return cartItems.value.some(item => item.product.belongType == 1);
});
watch(corpidLogin, (newValue) => {
if (isApproval.value) {
selectedPayment.value = 'approval';
} else {
if (newValue) {
selectedPayment.value = 'balance';
} else {
selectedPayment.value = 'wechat';
}
}
}, { immediate: true });
watch(isApproval, (newValue) => {
if (newValue) {
selectedPayment.value = 'approval';
} else {
if (corpidLogin.value) {
selectedPayment.value = 'balance';
} else {
selectedPayment.value = 'wechat';
}
}
})
// value
const paymentValueToType: Record<string, 'wechat' | 'balance' | 'approval'> = {
'0': 'wechat',
'1': 'balance',
'2': 'approval',
'3': 'balance'
};
function callWxJsApi(paymentInfo: WxJsApiPreCreateResponse) {
return new Promise((resolve, reject) => {
@ -127,7 +129,8 @@ async function handleSubmit() {
quantity: item.quantity,
cellId: item.product.cellId,
})),
paymentType: selectedPayment.value,
// value
paymentType: paymentValueToType[selectedPayment.value] || 'wechat',
mobile: tel.value,
name: isInternal === 2 ? qyName.value : name.value,
applyRemark: applyRemark.value,
@ -141,28 +144,35 @@ async function handleSubmit() {
throw new Error("订单提交失败")
}
if (selectedPayment.value === 'wechat') {
if (selectedPayment.value == '0') { //
if (data.paymentInfo) {
await callWxJsApi(data.paymentInfo);
}
} else if (selectedPayment.value === 'balance') {
//
} else if (selectedPayment.value == '1') { //
wxStore.setBalance(data.newBalance || 0);
try {
await showConfirmDialog({
title: "支付成功",
message: `借呗支付成功,剩余余额:¥${data.newBalance?.toFixed(2)}`
})
} catch (error) {}
} else if (selectedPayment.value == '2') { //
try {
await showConfirmDialog({
title: "提交领用申请成功",
message: `请等待管理员审批`
})
} catch (error) {}
} else if (selectedPayment.value == '3') { //
wxStore.setBalance(data.newBalance || 0);
try {
await showConfirmDialog({
title: "支付成功",
message: `余额支付成功,剩余余额:¥${data.newBalance?.toFixed(2)}`
})
} catch (error) {
}
} else if (selectedPayment.value === 'approval') {
//
try {
await showConfirmDialog({
title: "提交领用申请成功",
message: `请等待管理员审批`
})
} catch (error) { }
} catch (error) {}
} else { //
//
}
router.push({
@ -225,25 +235,24 @@ async function handleSubmit() {
<van-field v-model="applyRemark" label="领用说明" type="textarea" rows="2" autosize />
</van-cell-group> -->
<!-- 支付方式 -->
<van-cell-group v-if="!isApproval" class="contact-form">
<van-cell v-if="!corpidLogin" :class="['payment-option', { selected: selectedPayment === 'wechat' }]"
@click="selectedPayment = 'wechat'">
<van-icon name="wechat" class="method-icon" />
<span class="method-label">微信支付</span>
<div class="empty"></div>
<van-icon v-if="selectedPayment === 'wechat'" name="success" class="check-icon" />
</van-cell>
<van-cell v-if="balance && balance > 0"
:class="['payment-option', { selected: selectedPayment === 'balance', disabled: balance < totalPrice }]"
@click="selectedPayment = 'balance'">
<van-icon name="balance-o" class="method-icon" />
<van-cell
v-for="method in supportedPayments"
:key="method.value"
:class="['payment-option', { selected: selectedPayment === method.value.toString(), disabled: method.value === 1 && (balance < totalPrice) }]"
@click="selectedPayment = method.value.toString()"
>
<van-icon
:name="method.value === 0 ? 'wechat' : method.value === 1 ? 'balance-o' : method.value === 2 ? 'credit-card' : 'wallet'"
class="method-icon"
/>
<span class="method-label">
借呗支付
<span class="balance-amount">当前¥{{ balance.toFixed(2) }}</span>
{{ method.label }}
<span v-if="method.value === 1" class="balance-amount">当前¥{{ balance.toFixed(2) }}</span>
</span>
<div class="empty"></div>
<van-icon v-if="selectedPayment === 'balance'" name="success" class="check-icon" />
<van-icon v-if="selectedPayment === method.value.toString()" name="success" class="check-icon" />
</van-cell>
</van-cell-group>

View File

@ -1,3 +1,4 @@
import { ShopEntity } from "@/common/apis/shop/type"
import { pinia } from "@/pinia"
import { getShopGoodsApi } from "@@/apis/shop"
@ -19,6 +20,11 @@ export const useProductStore = defineStore("product", () => {
const labels = ref<{ id: number, name: string }[]>([]);
const categories = ref<Product[]>([]);
const shopId = ref<number|null>(null);
const selectedShop = ref<ShopEntity|null>(null);
const setSelectedShop = (shop: ShopEntity) => {
selectedShop.value = shop;
}
const getGoods = async (shopId_?: number) => {
if (shopId_ && shopId_ > 0) {
@ -58,7 +64,8 @@ export const useProductStore = defineStore("product", () => {
console.error("获取商品数据失败:", error)
}
}
return { labels, categories, shopId, getGoods }
return { labels, categories, shopId, selectedShop,
getGoods, setSelectedShop }
})
/**