This commit is contained in:
Austin 2026-07-12 22:43:47 +08:00
parent 7d2e30acef
commit a9132acd98
1 changed files with 88 additions and 37 deletions

View File

@ -41,10 +41,13 @@
<view v-else class="cursor"></view> <view v-else class="cursor"></view>
</view> </view>
<text v-if="!amount" class="amount-hint">请输入付款金额</text> <text v-if="!amount" class="amount-hint">请输入付款金额</text>
<view v-if="amount && showBenefitTip" class="benefit-tip"> <view v-if="amount && showBenefitTip" class="benefit-block">
<view class="benefit-tip">
{{ benefitTitle }} {{ benefitTitle }}
<text class="benefit-value">¥ {{ accumulationAmount }}</text> <text class="benefit-value">¥ {{ accumulationAmount }}</text>
</view> </view>
<text v-if="propertyName" class="benefit-property li-two-line">绑定物业{{ propertyName }}</text>
</view>
</view> </view>
<view class="extra-zone"> <view class="extra-zone">
@ -137,6 +140,7 @@ const remark = ref('');
const paying = ref(false); const paying = ref(false);
const activeMerchantUrl = ref(''); const activeMerchantUrl = ref('');
const scoreName = ref('物业公积金'); const scoreName = ref('物业公积金');
const propertyName = ref('');
const scanning = ref(false); const scanning = ref(false);
const numberKeys = ['1', '2', '3', '4', '5', '6', '7', '8', '9']; const numberKeys = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
@ -149,6 +153,20 @@ const accumulationAmount = computed(() => {
const showBenefitTip = computed(() => Number(merchant.value.accumulationRate) > 0); const showBenefitTip = computed(() => Number(merchant.value.accumulationRate) > 0);
const benefitTitle = computed(() => `预计获得${scoreName.value || '物业公积金'}`); const benefitTitle = computed(() => `预计获得${scoreName.value || '物业公积金'}`);
interface PropertyBindingCache {
merchant_id?: string;
merchant_name?: string;
score_name?: string;
fee_rate?: string | number;
}
interface SupplierCache {
supplier_id?: string | number;
supplier_name?: string;
logo?: string;
fee_rate?: string | number;
}
const parseFeeRate = (feeRate: unknown) => { const parseFeeRate = (feeRate: unknown) => {
if (feeRate === undefined || feeRate === null || feeRate === '') return 0; if (feeRate === undefined || feeRate === null || feeRate === '') return 0;
const rate = Number(feeRate); const rate = Number(feeRate);
@ -156,6 +174,42 @@ const parseFeeRate = (feeRate: unknown) => {
return rate / 100; return rate / 100;
}; };
const hasFeeRate = (feeRate: unknown) => feeRate !== undefined && feeRate !== null && feeRate !== '';
const resolveFeeRateFromPayload = (payload: Record<string, any> = {}) => {
const supplierData = payload.supplier || {};
return supplierData.fee_rate ?? payload.fee_rate;
};
const resolvePropertyFromPayload = (payload: Record<string, any> = {}) => {
const merchantData = payload.merchant || payload;
return {
merchant_id: merchantData.merchant_id,
merchant_name: merchantData.merchant_name,
score_name: merchantData.config?.score_name
};
};
const applyPropertyInfo = (property?: { merchant_name?: string; score_name?: string }) => {
if (!property) return;
if (property.merchant_name) {
propertyName.value = property.merchant_name;
}
if (property.score_name) {
scoreName.value = property.score_name;
}
};
const buildSupplierCache = (payload: Record<string, any> = {}, previous?: SupplierCache | null): SupplierCache => {
const supplierData = payload.supplier || {};
return {
supplier_id: supplierData.supplier_id ?? payload.supplier_id ?? previous?.supplier_id,
supplier_name: supplierData.supplier_name ?? payload.supplier_name ?? previous?.supplier_name,
logo: supplierData.logo ?? payload.logo ?? previous?.logo,
fee_rate: resolveFeeRateFromPayload(payload) ?? previous?.fee_rate
};
};
const applyMerchantInfo = (data: any = {}) => { const applyMerchantInfo = (data: any = {}) => {
const name = data.name || data.merchant_name || data.title; const name = data.name || data.merchant_name || data.title;
const background = data.background || data.banner || data.cover || data.bg; const background = data.background || data.banner || data.cover || data.bg;
@ -170,39 +224,29 @@ const applyMerchantInfo = (data: any = {}) => {
}; };
}; };
interface PropertyBindingCache {
merchant_id?: string;
merchant_name?: string;
score_name?: string;
fee_rate?: string | number;
}
interface SupplierCache {
supplier_id?: string | number;
supplier_name?: string;
logo?: string;
fee_rate?: string | number;
}
const applyBindingInfo = (binding?: PropertyBindingCache | null) => { const applyBindingInfo = (binding?: PropertyBindingCache | null) => {
if (!binding) return; if (!binding) return;
applyMerchantInfo({ const updates: Record<string, unknown> = {
merchant_id: binding.merchant_id, merchant_id: binding.merchant_id,
merchant_name: binding.merchant_name, merchant_name: binding.merchant_name
accumulationRate: parseFeeRate(binding.fee_rate) };
}); if (hasFeeRate(binding.fee_rate)) {
if (binding.score_name) { updates.accumulationRate = parseFeeRate(binding.fee_rate);
scoreName.value = binding.score_name;
} }
applyMerchantInfo(updates);
applyPropertyInfo(binding);
}; };
const applySupplierInfo = (supplier?: SupplierCache | null) => { const applySupplierInfo = (supplier?: SupplierCache | null) => {
if (!supplier) return; if (!supplier) return;
applyMerchantInfo({ const updates: Record<string, unknown> = {
name: supplier.supplier_name, name: supplier.supplier_name,
background: supplier.logo, background: supplier.logo
accumulationRate: parseFeeRate(supplier.fee_rate) };
}); if (hasFeeRate(supplier.fee_rate)) {
updates.accumulationRate = parseFeeRate(supplier.fee_rate);
}
applyMerchantInfo(updates);
}; };
const syncBindingCacheForUrl = (merchantUrl: string) => { const syncBindingCacheForUrl = (merchantUrl: string) => {
@ -218,6 +262,8 @@ const syncBindingCacheForUrl = (merchantUrl: string) => {
const initWithMerchantUrl = async (merchantUrl: string) => { const initWithMerchantUrl = async (merchantUrl: string) => {
hasMerchantUrl.value = true; hasMerchantUrl.value = true;
activeMerchantUrl.value = merchantUrl; activeMerchantUrl.value = merchantUrl;
propertyName.value = '';
scoreName.value = '物业公积金';
await loadPropertyBinding(merchantUrl); await loadPropertyBinding(merchantUrl);
await loadSupplier(merchantUrl); await loadSupplier(merchantUrl);
}; };
@ -286,12 +332,11 @@ const loadPropertyBinding = async (merchantUrl: string) => {
const payload = response.data || {}; const payload = response.data || {};
const merchantData = payload.merchant || payload; const merchantData = payload.merchant || payload;
const supplierData = payload.supplier || {};
const latestBinding: PropertyBindingCache = { const latestBinding: PropertyBindingCache = {
merchant_id: merchantData.merchant_id, merchant_id: merchantData.merchant_id,
merchant_name: merchantData.merchant_name, merchant_name: merchantData.merchant_name,
score_name: merchantData.config?.score_name, score_name: merchantData.config?.score_name,
fee_rate: supplierData.fee_rate ?? payload.fee_rate fee_rate: resolveFeeRateFromPayload(payload)
}; };
applyBindingInfo(latestBinding); applyBindingInfo(latestBinding);
encryptedStorage.set(cacheKey, latestBinding, PROPERTY_CACHE_TTL_SECONDS); encryptedStorage.set(cacheKey, latestBinding, PROPERTY_CACHE_TTL_SECONDS);
@ -312,13 +357,8 @@ const loadSupplier = async (merchantUrl: string) => {
if (Number(response?.code) !== 200 || !response?.data) return; if (Number(response?.code) !== 200 || !response?.data) return;
const payload = response.data || {}; const payload = response.data || {};
const supplierData = payload.supplier || payload; const latestSupplier = buildSupplierCache(payload, cached);
const latestSupplier: SupplierCache = { applyPropertyInfo(resolvePropertyFromPayload(payload));
supplier_id: supplierData.supplier_id,
supplier_name: supplierData.supplier_name,
logo: supplierData.logo,
fee_rate: supplierData.fee_rate
};
applySupplierInfo(latestSupplier); applySupplierInfo(latestSupplier);
encryptedStorage.set(cacheKey, latestSupplier, SUPPLIER_CACHE_TTL_SECONDS); encryptedStorage.set(cacheKey, latestSupplier, SUPPLIER_CACHE_TTL_SECONDS);
} catch (error) { } catch (error) {
@ -676,14 +716,25 @@ onLoad((options: any) => {
font-size: 26rpx; font-size: 26rpx;
} }
.benefit-tip { .benefit-block {
margin-top: 20rpx; margin-top: 20rpx;
padding-left: 4rpx; padding-left: 4rpx;
}
.benefit-tip {
color: #8B929E; color: #8B929E;
font-size: 26rpx; font-size: 26rpx;
line-height: 1.5; line-height: 1.5;
} }
.benefit-property {
display: block;
margin-top: 8rpx;
color: #AEB4BE;
font-size: 24rpx;
line-height: 1.5;
}
.benefit-value { .benefit-value {
margin-left: 8rpx; margin-left: 8rpx;
color: #4B6CB7; color: #4B6CB7;