Merge branch 'Branch_1' of https://git.u8t.cn/tangxinyue/alipay-emulator into Branch_1

This commit is contained in:
小李 2026-04-17 18:05:55 +08:00
commit 2b46401bd8
18 changed files with 409 additions and 252 deletions

View File

@ -78,6 +78,7 @@ export default {
this.globalData.NativeEvent = false this.globalData.NativeEvent = false
console.log('开始监听宿主消息') console.log('开始监听宿主消息')
if (typeof uni.onNativeEventReceive === 'function') {
uni.onNativeEventReceive((event, data) => { uni.onNativeEventReceive((event, data) => {
if (event) { if (event) {
console.log('接收到宿主消息:', event, data) console.log('接收到宿主消息:', event, data)
@ -109,6 +110,9 @@ export default {
} }
} }
}) })
} else {
console.log('uni.onNativeEventReceive 不可用,跳过监听')
}
} }
}, },

View File

@ -98,7 +98,7 @@ const handleTouchStart = (e, item) => {
event: e, event: e,
item item
}) })
}, 1500) }, 1000)
} }
const handleTouchMove = (e) => { const handleTouchMove = (e) => {

View File

@ -7,12 +7,21 @@
<!-- 输入层 --> <!-- 输入层 -->
<template v-if="type !== 'textarea'"> <template v-if="type !== 'textarea'">
<input class="auto-input" :type="type" :value="modelValue" :placeholder="placeholder" :placeholder-style="placeholderStyle" <input v-if="!disabled" class="auto-input" :type="type" :value="modelValue" :placeholder="placeholder"
:style="[inputStyle, { width: finalInputWidth }]" @input="onInput" :maxlength="maxlength" :focus="isFocus" @blur="onBlur" /> :placeholder-style="placeholderStyle" :style="[inputStyle, { width: finalInputWidth }]" @input="onInput"
:maxlength="maxlength" :focus="isFocus" @blur="onBlur" :readonly="readonly" />
<view v-else class="auto-input flex-align-center"
:style="[inputStyle, { width: finalInputWidth }, !modelValue ? placeholderStyleObject : {}]">
{{ modelValue || placeholder }}
</view>
</template> </template>
<template v-else> <template v-else>
<textarea class="auto-textarea" :value="modelValue" :placeholder="placeholder" :placeholder-style="placeholderStyle" <textarea v-if="!disabled" class="auto-textarea" :value="modelValue" :placeholder="placeholder"
:style="[inputStyle]" @input="onInput" :maxlength="maxlength" auto-height :focus="isFocus" @blur="onBlur" /> :placeholder-style="placeholderStyle" :style="[inputStyle]" @input="onInput" :maxlength="maxlength"
auto-height :focus="isFocus" @blur="onBlur" :readonly="readonly" />
<view v-else class="auto-textarea" :style="[inputStyle, !modelValue ? placeholderStyleObject : {}]">
{{ modelValue || placeholder }}
</view>
</template> </template>
<!-- 编辑图标 --> <!-- 编辑图标 -->
@ -67,6 +76,14 @@ const props = defineProps({
showEdit: { showEdit: {
type: Boolean, type: Boolean,
default: false default: false
},
readonly: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
} }
}); });
@ -86,6 +103,20 @@ const finalInputWidth = computed(() => {
}); });
const isFocus = ref(false); const isFocus = ref(false);
const placeholderStyleObject = computed(() => {
const style = {};
if (!props.placeholderStyle) return style;
const parts = props.placeholderStyle.split(';');
parts.forEach(part => {
const [key, value] = part.split(':');
if (key && value) {
const camelKey = key.trim().replace(/-([a-z])/g, (g) => g[1].toUpperCase());
style[camelKey] = value.trim();
}
});
return style;
});
const inputStyle = computed(() => ({ const inputStyle = computed(() => ({
fontSize: props.fontSize, fontSize: props.fontSize,
fontWeight: props.fontWeight, fontWeight: props.fontWeight,

View File

@ -203,11 +203,21 @@ const onRightClick = () => {
emit('right-click') emit('right-click')
} }
const closeTopPopup = () => {
topPopup.value.close()
}
const buttonClick = (button) => { const buttonClick = (button) => {
topPopup.value.close() closeTopPopup()
emit('button-click', button) emit('button-click', button)
} }
//
defineExpose({
openPopup,
closeTopPopup
})
</script> </script>
<style scoped> <style scoped>

View File

@ -62,13 +62,6 @@
</template> </template>
<template v-else-if="item.products && item.products.length === 1"> <template v-else-if="item.products && item.products.length === 1">
<image class="product-img" :src="item.products[0].image" mode="aspectFill"></image> <image class="product-img" :src="item.products[0].image" mode="aspectFill"></image>
<view class="product-info">
<text class="product-title">{{ item.products[0].title }}</text>
<text class="product-desc" v-if="item.products[0].desc">{{ item.products[0].desc }}</text>
<view class="product-tags" v-if="item.products[0].service">
<text class="tag">{{ item.products[0].service }}</text>
</view>
</view>
</template> </template>
<template v-else-if="item.images && item.images.length > 0"> <template v-else-if="item.images && item.images.length > 0">
<scroll-view class="product-images-scroll" scroll-x :show-scrollbar="false"> <scroll-view class="product-images-scroll" scroll-x :show-scrollbar="false">
@ -86,6 +79,17 @@
</view> </view>
</view> </view>
</template> </template>
<view class='flex flex-justify-between flex-align-center'
:class="{ 'flex-1': item.products && item.products.length === 1 }">
<view class="product-info flex-1">
<template v-if="item.products && item.products.length === 1">
<text class="product-title">{{ item.products[0].title }}</text>
<text class="product-desc" v-if="item.products[0].desc">{{ item.products[0].desc }}</text>
<view class="product-tags" v-if="item.products[0].service">
<text class="tag">{{ item.products[0].service }}</text>
</view>
</template>
</view>
<view class="product-price-box"> <view class="product-price-box">
<view class="price-wrap wx-font-regular"> <view class="price-wrap wx-font-regular">
<text class="price-symbol"></text> <text class="price-symbol"></text>
@ -101,6 +105,8 @@
</view> </view>
</view> </view>
</view>
<!-- Promo --> <!-- Promo -->
<view class="promo-box" <view class="promo-box"
:class="{ 'plus-promo': item.promoType === 'plus', 'cashback-promo': item.shopType == 'waimai' && (item.status == '骑手到店取餐中' || item.status == '商家备餐中'), 'coupon-promo': item.promoType === 'coupon' }"> :class="{ 'plus-promo': item.promoType === 'plus', 'cashback-promo': item.shopType == 'waimai' && (item.status == '骑手到店取餐中' || item.status == '商家备餐中'), 'coupon-promo': item.promoType === 'coupon' }">
@ -518,15 +524,15 @@ const getButtons = (shopType, status, item) => {
.product-info { .product-info {
flex: 1; flex: 1;
width: 100px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 20rpx;
.product-title { .product-title {
font-size: 26rpx; font-size: 26rpx;
color: #1A1A1A; color: #1A1A1A;
line-height: 36rpx; line-height: 36rpx;
white-space: nowrap; // white-space: nowrap;
text-overflow: hidden; text-overflow: hidden;
overflow: hidden; overflow: hidden;
} }
@ -567,6 +573,7 @@ const getButtons = (shopType, status, item) => {
color: #1A1A1A; color: #1A1A1A;
font-size: 30rpx; font-size: 30rpx;
margin-bottom: 4rpx; margin-bottom: 4rpx;
line-height: 36rpx;
display: flex; display: flex;
align-items: baseline; align-items: baseline;
@ -711,6 +718,7 @@ const getButtons = (shopType, status, item) => {
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: flex-end; justify-content: flex-end;
position: relative;
.btn { .btn {
position: relative; position: relative;

View File

@ -7,7 +7,7 @@
<image v-else class="colse" src="/static/image/watermarkColseDark.png" mode=""></image> --> <image v-else class="colse" src="/static/image/watermarkColseDark.png" mode=""></image> -->
<image class="watermarkImg" src="/static/image/watermark.png" mode=""></image> <image class="watermarkImg" src="/static/image/watermark.png" mode=""></image>
<image class="colse" src="/static/image/watermarkColse.png" mode="" <image class="colse" src="/static/image/watermarkColse.png" mode=""
@click="$goRechargePage('watermark_close')"></image> @click="$goRechargePage('watermark_close', source)"></image>
</view> </view>
</view> </view>
@ -19,6 +19,10 @@ export default {
dark: { dark: {
type: String, type: String,
default: 'light' default: 'light'
},
source: {
type: String,
default: 'uni_alipay_other'
} }
}, },
name: "watermark", name: "watermark",

View File

@ -27,7 +27,7 @@ export function createApp() {
const systemInfo = uni.getStorageSync('systemInfo') || {} const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android' app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
app.config.globalProperties.$systemInfo = systemInfo app.config.globalProperties.$systemInfo = systemInfo
uni.setStorageSync('version', '1.0.4.sp5') uni.setStorageSync('version', '1.0.4.sp8')
app.config.globalProperties.$version = uni.getStorageSync('version') app.config.globalProperties.$version = uni.getStorageSync('version')
app.use(globalMethods); app.use(globalMethods);
return { return {

View File

@ -1,21 +1,22 @@
<template> <template>
<!-- 水印 --> <!-- 水印 -->
<view v-if="$isVip()"> <view v-if="$isVip()">
<watermark :dark="data.dark" /> <watermark :dark="data.dark" source="uni_alipay_huabei" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')"> <liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_huabei')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie> <c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button> </liu-drag-button>
</view> </view>
<view class="page-container"> <view class="page-container">
<view class="main-container"> <view class="main-container">
<NavBar v-if="!selectedImage" title="花呗" :bgColor="data.navBar.bgColor" tipLayerType="huabei-tip" isTipLayer <NavBar ref="navBarRef" v-if="!selectedImage" title="花呗" :bgColor="data.navBar.bgColor"
tipLayerText="修改花呗信息" :buttonGroup="buttonGroup" @button-click="clickTitlePopupButton"> tipLayerType="huabei-tip" isTipLayer tipLayerText="修改花呗信息" :buttonGroup="buttonGroup"
@button-click="clickTitlePopupButton">
<!-- 使用作用域插槽自定义按钮渲染特别是switch的checked绑定 --> <!-- 使用作用域插槽自定义按钮渲染特别是switch的checked绑定 -->
<template #button="{ button }"> <template #button="{ button }">
<view class="button flex-align-center flex-justify-center"> <view class="button flex-align-center flex-justify-center">
{{ button.name }} {{ button.name }}
<view @tap.stop> <view @tap.stop>
<switch v-if="button.isSwitch" :checked="data.huabeiInfo.isOverdue" @change="button.click" <switch v-if="button.isSwitch" :checked="data.huabeiInfo[button.key]" @change="button.click"
style="transform: scale(0.7);"></switch> style="transform: scale(0.7);"></switch>
</view> </view>
</view> </view>
@ -44,11 +45,13 @@
<view v-if="huabeiInfo.styleType == 1" class="current-month">{{ huabeiInfo.mouth }}月应还()</view> <view v-if="huabeiInfo.styleType == 1" class="current-month">{{ huabeiInfo.mouth }}月应还()</view>
<view v-else class="current-month">{{ huabeiInfo.mouth }}月账单累计中()</view> <view v-else class="current-month">{{ huabeiInfo.mouth }}月账单累计中()</view>
<view class="money-box flex-align-center"> <view class="money-box flex-align-center">
<text class="money alipay-font">{{ numberUtil.formatMoneyWithThousand(huabeiInfo.money) }}</text> <text class="money alipay-font" style="font-size: 48rpx;" v-if="data.huabeiInfo.isPayOff">已还清</text>
<text class="money alipay-font" v-else>{{ numberUtil.formatMoneyWithThousand(huabeiInfo.money) }}</text>
<uni-icons type="right" size="18" color="#B9D6FF"></uni-icons> <uni-icons type="right" size="18" color="#B9D6FF"></uni-icons>
</view> </view>
<!-- 样式一 按钮样式 --> <!-- 样式一 按钮样式 -->
<view v-if="huabeiInfo.styleType == 1 || !huabeiInfo.styleType" class="style-1 button-group"> <view v-if="(huabeiInfo.styleType == 1 || !huabeiInfo.styleType) && !huabeiInfo.isPayOff"
class="style-1 button-group">
<view class="button-item second-button" :class="{ 'ios-button': $system == 'iOS' }">立即还款</view> <view class="button-item second-button" :class="{ 'ios-button': $system == 'iOS' }">立即还款</view>
<view v-if="!huabeiInfo.isInstallment" class="button-item primary-button" <view v-if="!huabeiInfo.isInstallment" class="button-item primary-button"
:class="{ 'ios-button': $system == 'iOS' }"> :class="{ 'ios-button': $system == 'iOS' }">
@ -58,17 +61,20 @@
</view> </view>
</view> </view>
<!-- 样式二 纯气泡样式 --> <!-- 样式二 纯气泡样式 -->
<view v-if="huabeiInfo.styleType == 2" class="style-2 bubble-container"> <view v-if="(huabeiInfo.styleType == 2) && !huabeiInfo.isPayOff" class="style-2 bubble-container">
<view class="bubble-box"> <view class="bubble-box">
<view class="arrow"></view> <view class="arrow"></view>
<text class="text">{{ huabeiInfo.descText }}</text> <text class="text">{{ huabeiInfo.descText }}</text>
</view> </view>
</view> </view>
<!-- 样式三 气泡带箭头样式 --> <!-- 样式三 气泡带箭头样式 -->
<view v-if="huabeiInfo.styleType == 3" class="style-3 bubble-container"> <view v-if="huabeiInfo.styleType == 3 || huabeiInfo.isPayOff" class="style-3 bubble-container">
<view class="bubble-box"> <view class="bubble-box">
<view class="arrow"></view> <view class="arrow"></view>
<text class="text flex-align-center">{{ huabeiInfo.descText }} <text class="text flex-align-center">
<text style="line-height: 18px;">{{ huabeiInfo.isPayOff ? huabeiInfo.showDescText :
huabeiInfo.descText
}}</text>
<uni-icons type="right" size="18" color="#B9D6FF"></uni-icons> <uni-icons type="right" size="18" color="#B9D6FF"></uni-icons>
</text> </text>
</view> </view>
@ -81,6 +87,7 @@
<view class="info-item"> <view class="info-item">
<view class="label">总计额度</view> <view class="label">总计额度</view>
<view class="value">{{ <view class="value">{{
huabeiInfo.isPayOff ? numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount)) :
numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount) - Number(huabeiInfo.money)) numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount) - Number(huabeiInfo.money))
}}可用 }}可用
</view> </view>
@ -201,6 +208,8 @@ import {
const instance = getCurrentInstance(); const instance = getCurrentInstance();
const { proxy } = instance; const { proxy } = instance;
const navBarRef = ref(null)
const buttonGroup = [{ const buttonGroup = [{
name: "编辑花呗数据", name: "编辑花呗数据",
@ -221,6 +230,7 @@ const buttonGroup = [{
}, { }, {
name: "花呗逾期", name: "花呗逾期",
isSwitch: true, isSwitch: true,
key: 'isOverdue',
click: () => { click: () => {
data.huabeiInfo.isOverdue = !data.huabeiInfo.isOverdue data.huabeiInfo.isOverdue = !data.huabeiInfo.isOverdue
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo) uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
@ -229,6 +239,20 @@ const buttonGroup = [{
url: '/pages/ant-credit-pay/overdue-payment/overdue-payment' url: '/pages/ant-credit-pay/overdue-payment/overdue-payment'
}) })
} }
navBarRef.value.closeTopPopup()
}
}, {
name: "还清花呗",
isSwitch: true,
key: 'isPayOff',
click: () => {
data.huabeiInfo.isPayOff = !data.huabeiInfo.isPayOff
// uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
if (data.huabeiInfo.isPayOff) {
data.huabeiInfo.showDescText = `${Number(data.huabeiInfo.mouth) + 1}月已累计0.00,查看消费详情报告`
}
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
navBarRef.value.closeTopPopup()
} }
}] }]
@ -704,7 +728,7 @@ const goBack = () => {
justify-content: center; justify-content: center;
.text { .text {
color: #ffffff; color: #B9D6FF;
font-size: 26rpx; font-size: 26rpx;
line-height: 1.2; line-height: 1.2;
} }
@ -738,7 +762,7 @@ const goBack = () => {
} }
.value { .value {
color: #ffffff; color: #B9D6FF;
font-size: 26rpx; font-size: 26rpx;
line-height: 36rpx; line-height: 36rpx;
} }

View File

@ -206,8 +206,8 @@
<!-- 水印 --> <!-- 水印 -->
<view v-if="$isVip()"> <view v-if="$isVip()">
<watermark :dark="data.dark" /> <watermark :dark="data.dark" source="uni_alipay_huabei" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')"> <liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_huabei')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie> <c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button> </liu-drag-button>
</view> </view>

View File

@ -1,8 +1,8 @@
<template> <template>
<!-- 水印 --> <!-- 水印 -->
<view v-if="$isVip()"> <view v-if="$isVip()">
<watermark :dark="data.dark" /> <watermark :dark="data.dark" source="uni_alipay_balance" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')"> <liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_balance')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie> <c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button> </liu-drag-button>
</view> </view>

View File

@ -1,8 +1,8 @@
<template> <template>
<!-- 水印 --> <!-- 水印 -->
<view v-if="$isVip()"> <view v-if="$isVip()">
<watermark :dark="data.dark" /> <watermark :dark="data.dark" source="uni_alipay_bill_details" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')"> <liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_bill_details')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie> <c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button> </liu-drag-button>
</view> </view>

View File

@ -1,8 +1,8 @@
<template> <template>
<!-- 水印 --> <!-- 水印 -->
<view v-if="$isVip()"> <view v-if="$isVip()">
<watermark :dark="data.dark" /> <watermark :dark="data.dark" source="uni_alipay_bill" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')"> <liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark', 'uni_alipay_bill')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie> <c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button> </liu-drag-button>
</view> </view>

View File

@ -36,7 +36,8 @@
</view> </view>
<view class="vipList"> <view class="vipList">
<template v-for="(item, index) in data.benefitList" :key="index"> <template v-for="(item, index) in data.benefitList" :key="index">
<view class="item" v-if="data.goods.features=='common'||(data.goods.features!='common'&&index<10)"> <view class="item"
v-if="data.goods.features == 'common' || (data.goods.features != 'common' && index < 10)">
<image :src="item.url"></image> <image :src="item.url"></image>
<text>{{ item.name }}</text> <text>{{ item.name }}</text>
</view> </view>
@ -131,7 +132,8 @@
合计 合计
<text></text> <text></text>
<countUp :num="$toFiexd(data.price, 2)" height="24" style="margin-top: -6px;" color="red" <countUp :num="$toFiexd(data.price, 2)" height="24" style="margin-top: -6px;" color="red"
fontSize='24'></countUp> fontSize='24'>
</countUp>
已优惠{{ $toFiexd(data.coupon, 0) }} 已优惠{{ $toFiexd(data.coupon, 0) }}
</view> </view>
<view class="button" @click="activateVip"> <view class="button" @click="activateVip">
@ -462,6 +464,7 @@ const data = reactive({
isProcessingClick: false, isProcessingClick: false,
banner: '/static/image/recharge/banner1.png', banner: '/static/image/recharge/banner1.png',
isCombo: false, isCombo: false,
source: "uni_alipay_other"
}) })
let { let {
@ -470,7 +473,8 @@ let {
benefitList, benefitList,
noticeList, noticeList,
commentList, commentList,
paymentMethod paymentMethod,
source
} = toRefs(data) } = toRefs(data)
/** /**
@ -485,6 +489,9 @@ onBackPress((e) => {
onLoad(async () => { onLoad(async () => {
if (option.source) {
data.source = option.source
}
const config = uni.getStorageSync('config').config const config = uni.getStorageSync('config').config
const themeConfig = config?.['client.uniapp.theme'] const themeConfig = config?.['client.uniapp.theme']
if (themeConfig?.enable) { if (themeConfig?.enable) {
@ -1167,7 +1174,8 @@ async function activateVip(type = '') {
coupon: data.active_id ? data.active_id : '', coupon: data.active_id ? data.active_id : '',
pay_type: paymentMethod.value == "wxpay" ? (data.goods.weixinMpOriId && isComBo ? 'combo' : 'weixin') : "alipay", pay_type: paymentMethod.value == "wxpay" ? (data.goods.weixinMpOriId && isComBo ? 'combo' : 'weixin') : "alipay",
"pay_source": "app", "pay_source": "app",
source: "uni_alipay", // source: "uni_alipay",
source: data.source,
}) })
@ -1685,6 +1693,7 @@ function shouldBeTrue(obj) {
.package-items-container { .package-items-container {
display: flex; display: flex;
padding: 40rpx 32rpx 40rpx 32rpx; padding: 40rpx 32rpx 40rpx 32rpx;
.active-package-item-tips { .active-package-item-tips {
position: absolute; position: absolute;
content: '限时优惠'; content: '限时优惠';
@ -2525,10 +2534,12 @@ function shouldBeTrue(obj) {
} }
} }
} }
@font-face { @font-face {
font-family: 'AlipayNumber'; // font-family: 'AlipayNumber'; //
src: url('/static/font/AlipayNumber.ttf'); src: url('/static/font/AlipayNumber.ttf');
} }
.wx-font-regular { .wx-font-regular {
font-family: 'AlipayNumber' !important; font-family: 'AlipayNumber' !important;
} }

View File

@ -380,7 +380,8 @@
<view class="flex-1 flex-align-center" <view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;"> style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A" <auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A"
:type="item.type ? item.type : 'text'" show-edit /> :type="item.type ? item.type : 'text'" show-edit
:disabled="item.type == 'time' || item.type == 'timeRange'" />
</view> </view>
</view> </view>
@ -392,7 +393,8 @@
<view class="flex-1 flex-align-center" <view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;"> style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A" <auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A"
:type="item.type ? item.type : 'text'" show-edit /> :type="item.type ? item.type : 'text'" show-edit
:disabled="item.type == 'time' || item.type == 'timeRange'" />
</view> </view>
</view> </view>

View File

@ -193,9 +193,9 @@
placeholder="商品描述" color="#87868E" show-edit /> placeholder="商品描述" color="#87868E" show-edit />
</view> </view>
<view class="flex flex-align-center animate-scale"> <view class="flex flex-align-center animate-scale desc">
<auto-width-input class="desc" v-model="product.count" type="textarea" fontSize="22rpx" <auto-width-input style="width: calc(100% - 18px);" v-model="product.count" type="number"
placeholder="请输入数量" color="#8D8D8D" show-edit /> fontSize="22rpx" placeholder="请输入数量" color="#8D8D8D" show-edit minWidth="100%" />
</view> </view>
<view class="flex flex-align-center animate-scale wx-font-medium" <view class="flex flex-align-center animate-scale wx-font-medium"
style="align-items: baseline;margin-top: 10rpx;"> style="align-items: baseline;margin-top: 10rpx;">
@ -203,6 +203,13 @@
<auto-width-input class="flex-1 wx-font-medium" v-model="product.price" type="digit" <auto-width-input class="flex-1 wx-font-medium" v-model="product.price" type="digit"
fontSize="36rpx" placeholder="0.00" color="#1A1A1A" fontWeight="500" show-edit /> fontSize="36rpx" placeholder="0.00" color="#1A1A1A" fontWeight="500" show-edit />
</view> </view>
<!-- 新增商品单项优惠额度 -->
<view class="flex flex-align-center animate-scale wx-font-medium"
style="align-items: baseline;margin-top: 4rpx; color: #F10F1A;">
<text style="font-size: 22rpx;font-weight: 500;">优惠 </text>
<auto-width-input class="flex-1 wx-font-medium" v-model="product.discount" type="digit"
fontSize="28rpx" placeholder="0.00" color="#F10F1A" fontWeight="500" show-edit />
</view>
</view> </view>
</view> </view>
<view v-if="pIndex < order.products.length - 1" class="product-divider"></view> <view v-if="pIndex < order.products.length - 1" class="product-divider"></view>
@ -346,7 +353,7 @@
<view class="flex-1 flex-align-center" <view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;"> style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<auto-width-input class="value" v-model="order.productsInfo.deliveryTime" fontSize="26rpx" <auto-width-input class="value" v-model="order.productsInfo.deliveryTime" fontSize="26rpx"
type="text" color="#1A1A1A" show-edit /> type="text" color="#1A1A1A" show-edit :disabled="true" />
</view> </view>
</view> </view>
<view class="item flex-justify-between"> <view class="item flex-justify-between">
@ -373,7 +380,8 @@
<view class="flex-1 flex-align-center" <view class="flex-1 flex-align-center"
style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;"> style="justify-content: flex-end;width: 300rpx;overflow-x: auto;margin-left: 20rpx;">
<auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A" <auto-width-input class="value" v-model="item.value" fontSize="26rpx" color="#1A1A1A"
:type="item.type ? item.type : 'text'" show-edit /> :type="item.type ? item.type : 'text'" show-edit
:disabled="item.type == 'time' || item.type == 'timeRange'" />
</view> </view>
</view> </view>
</view> </view>
@ -616,6 +624,7 @@ const addProduct = () => {
desc: "", desc: "",
service: "不支持7天无理由退货", service: "不支持7天无理由退货",
price: "0.00", price: "0.00",
discount: "0.00",
count: 1 count: 1
}); });
}; };
@ -1070,6 +1079,26 @@ watch(() => order.value.products, (newProducts) => {
} }
}, { deep: true, immediate: true }); }, { deep: true, immediate: true });
/**
* 自动计算总优惠 (order.discount)
* 逻辑所有商品优惠记录之和 + 运费优惠 (discountCarriage)
*/
watch([
() => order.value.products,
() => order.value.discountCarriage
], () => {
if (!order.value) return;
const productsDiscount = order.value.products ? order.value.products.reduce((sum, p) => {
const disc = parseMoney(p.discount || '0');
const countStr = String(p.count || '1');
const count = parseInt(countStr.replace(/[^\d]/g, '')) || 0;
return sum + (disc * count);
}, 0) : 0;
const shippingDiscount = parseMoney(order.value.discountCarriage || '0');
const totalDiscount = productsDiscount + shippingDiscount;
order.value.discount = totalDiscount > 0 ? totalDiscount.toFixed(2) : '0.00';
}, { deep: true, immediate: true });
/** /**
* 安全转换数值 * 安全转换数值
*/ */
@ -1582,6 +1611,7 @@ const onConfirm = () => {
font-weight: 500; font-weight: 500;
font-size: 28rpx; font-size: 28rpx;
color: #1A1A1A; color: #1A1A1A;
line-height: 28rpx;
.price { .price {
font-weight: 500; font-weight: 500;
@ -1745,6 +1775,7 @@ const onConfirm = () => {
background-color: #FFFFFF; background-color: #FFFFFF;
border-radius: 24rpx; border-radius: 24rpx;
padding: 28rpx 22rpx; padding: 28rpx 22rpx;
align-items: flex-start;
&.product-info-box { &.product-info-box {
padding: 0; padding: 0;

View File

@ -398,7 +398,7 @@
], ],
"waimaiClassfiy": { "waimaiClassfiy": {
"weizhifu": { "weizhifu": {
"id": "123211111", "id": "",
"type": "weizhifu", "type": "weizhifu",
"shopType": "waimai", "shopType": "waimai",
"shopName": "", "shopName": "",
@ -420,7 +420,8 @@
"title": "", "title": "",
"desc": "一人份", "desc": "一人份",
"price": "", "price": "",
"count": "1" "count": "1",
"discount": "0.00"
} }
], ],
"productsInfo": { "productsInfo": {
@ -457,7 +458,7 @@
"promoHighlight": "近90天600+人回购" "promoHighlight": "近90天600+人回购"
}, },
"beicanzhong": { "beicanzhong": {
"id": 9632554, "id": "",
"shopType": "waimai", "shopType": "waimai",
"type": "beicanzhong", "type": "beicanzhong",
"statusColor": "red", "statusColor": "red",
@ -479,7 +480,8 @@
"title": "", "title": "",
"desc": "一人份", "desc": "一人份",
"price": "", "price": "",
"count": "1" "count": "1",
"discount": "0.00"
} }
], ],
"productsInfo": { "productsInfo": {
@ -526,14 +528,14 @@
] ]
}, },
"qvcanzhong": { "qvcanzhong": {
"id": "63254112", "id": "",
"shopType": "waimai", "shopType": "waimai",
"type": "qvcanzhong", "type": "qvcanzhong",
"shopName": "安野屋 (AARYE) 京...", "shopName": "",
"status": "骑手到店取餐中", "status": "骑手到店取餐中",
"statusColor": "red", "statusColor": "red",
"trackingTitle": "10: 22-10: 55", "trackingTitle": "10: 22-10: 55",
"trackingDesc": "骑手已到店,大王", "trackingDesc": "骑手已到店",
"trackingTime": "2026-03-10 15: 14: 30", "trackingTime": "2026-03-10 15: 14: 30",
"recommendImg": "/static/image/shopping/jingdong/waimai/shop-recoomend/style-1.png", "recommendImg": "/static/image/shopping/jingdong/waimai/shop-recoomend/style-1.png",
"deliveryImages": "", "deliveryImages": "",
@ -544,13 +546,12 @@
"amountTo": "", "amountTo": "",
"products": [ "products": [
{ {
"image": "/static/image/shopping/jingdong/product1.png", "image": "",
"title": "超值哈哈哈哈哈哈哈哈哈哈哈哈哈哈好热 少糖", "title": "",
"desc": "不支持7天无理由退货", "desc": "一人份",
"service": "", "price": "",
"tags": [], "count": "1",
"price": "69.00", "discount": "0.00"
"count": "1"
} }
], ],
"productsInfo": { "productsInfo": {
@ -597,10 +598,10 @@
] ]
}, },
"yiwancheng": { "yiwancheng": {
"id": 78456211, "id": "",
"shopType": "waimai", "shopType": "waimai",
"type": "yiwancheng", "type": "yiwancheng",
"shopName": "瑞幸咖啡", "shopName": "",
"status": "完成", "status": "完成",
"statusColor": "gray", "statusColor": "gray",
"recommendImg": "/static/image/shopping/jingdong/waimai/shop-recoomend/style-1.png", "recommendImg": "/static/image/shopping/jingdong/waimai/shop-recoomend/style-1.png",
@ -611,13 +612,12 @@
"amountTo": "", "amountTo": "",
"products": [ "products": [
{ {
"image": "/static/image/shopping/jingdong/product1.png", "image": "",
"title": "多肉桃桃哈哈哈哈哈哈哈哈哈哈好和和好", "title": "",
"desc": "不支持7天无理由退货", "desc": "一人份",
"service": "", "price": "",
"tags": [], "count": "1",
"price": "69.00", "discount": "0.00"
"count": "1"
} }
], ],
"productsInfo": { "productsInfo": {
@ -667,10 +667,10 @@
"promoAction": "去领券" "promoAction": "去领券"
}, },
"yiquxiao": { "yiquxiao": {
"id": "52322221", "id": "",
"shopType": "waimai", "shopType": "waimai",
"type": "yiquxiao", "type": "yiquxiao",
"shopName": "瑞幸咖啡", "shopName": "",
"status": "已取消", "status": "已取消",
"statusColor": "gray", "statusColor": "gray",
"recommendImg": "/static/image/shopping/jingdong/waimai/shop-recoomend/style-1.png", "recommendImg": "/static/image/shopping/jingdong/waimai/shop-recoomend/style-1.png",
@ -681,13 +681,12 @@
"amountTo": "", "amountTo": "",
"products": [ "products": [
{ {
"image": "/static/image/shopping/jingdong/product1.png", "image": "",
"title": "多肉桃桃哈哈哈哈哈哈哈哈哈哈好和和好", "title": "",
"desc": "不支持7天无理由退货", "desc": "一人份",
"tags": [], "price": "",
"service": "", "count": "1",
"price": "69.00", "discount": "0.00"
"count": "1"
} }
], ],
"productsInfo": { "productsInfo": {

View File

@ -204,41 +204,61 @@
</view> </view>
<uni-icons class="right-icon" size="14" color="#1A1A1A" type="right"></uni-icons> <uni-icons class="right-icon" size="14" color="#1A1A1A" type="right"></uni-icons>
</view> </view>
<view class="product-info"> <view class="product-info flex-align-center" v-for="(item, i) in order.products" :key="i">
<view class="image-box"> <view class="image-box shrink-0">
<image v-if="order.products && order.products[0]" class="w100 h100" :src="order.products[0].image" <image v-if="item" class="w100 h100" :src="item.image" mode="widthFix">
mode="widthFix">
</image> </image>
</view> </view>
<view class="flex-1 flex" style="width:100px">
<view class="info-box"> <view class="info-box">
<view class="name">{{ order.products && order.products[0]?.title }}</view> <view class="name">{{ item.title }}</view>
<view class="desc">{{ order.products && order.products[0]?.desc }}</view> <view v-if="item.desc" class="desc">{{ item.desc }}</view>
<view class="tag">数量x{{ order.products && order.products[0]?.count }}</view> <view v-if="item.count" class="tag">数量x{{ item.count }}</view>
</view> </view>
<view class="price-box"> <view class="price-box">
<view v-if="(order.status != '等待付款' && order.status != '已取消') && order.discount > 0" class="flex-center" <view v-if="(order.status != '等待付款' && order.status != '已取消') && order.discount > 0"
style="display: inline-block;"> class="flex-center" style="display: inline-flex;">
<image style="width: 22rpx;height: 22rpx;margin-right: 4rpx;" <image style="width: 22rpx;height: 22rpx;margin-right: 4rpx;"
src="/static/image/shopping/jingdong/detail/help.png"> src="/static/image/shopping/jingdong/detail/help.png">
</image> </image>
<text <text
style="font-size: 22rpx;height: 22rpx;color: #87868E;font-weight: 300;line-height: 22rpx;margin-right: 2rpx;">到手</text> style="font-size: 22rpx;height: 22rpx;color: #1A1A1A;line-height: 22rpx;margin-right: 2rpx;">到手</text>
</view> </view>
<text class="price wx-font-medium">{{ <text class="price wx-font-medium">
order.status == '等待付款' || order.status == '已取消' ? <text style="font-size: 28rpx;"></text>
Number(order.products && order.products[0]?.price || 0).toFixed(2) : <text style="font-size: 32rpx;">
Number((order.products && order.products[0]?.price || 0) - (order.discount || 0)).toFixed(2) {{ order.status == '等待付款' ||
order.status == '已取消' ?
Number(item.price || 0).toFixed(2).split('.')[0] :
Number((item.price || 0) - (item.discount || 0)).toFixed(2).split('.')[0] }}
</text>
<text style="font-size: 36rpx;">.</text>
<text style="font-size: 24rpx;">
{{ order.status == '等待付款' ||
order.status == '已取消' ?
Number(item.price || 0).toFixed(2).split('.')[1] :
Number((item.price || 0) - (item.discount || 0)).toFixed(2).split('.')[1] }}
</text>
</text>
<view v-if="(order.status != '等待付款' && order.status != '已取消') && (item.discount || 0) > 0"
class="wx-font-medium"
style="margin-top: 2rpx;text-align: right;color: #87868E;font-weight: 500;">
<text style="font-size: 24rpx;">
<text style="font-size: 20rpx;"></text>
<text style="font-size: 24rpx;">{{ Number(item.discount || 0).toFixed(2).split('.')[0]
}}</text> }}</text>
<view v-if="(order.status != '等待付款' && order.status != '已取消') && (order.discount || 0) > 0" <text style="font-size: 24rpx;">.</text>
class="wx-font-medium" style="margin-top: 2rpx;text-align: right;color: #87868E;font-weight: 500;"> <text style="font-size: 20rpx;">{{ Number(item.discount || 0).toFixed(2).split('.')[1]
<text style="font-size: 24rpx;">{{ Number(order.products && order.products[0]?.price ||
0).toFixed(2)
}}</text> }}</text>
</text>
</view> </view>
</view> </view>
</view> </view>
</view>
<view v-if="order.activeTab == 'weizhifu' || order.activeTab == 'yiquxiao'" class="order-info" <view v-if="order.activeTab == 'weizhifu' || order.activeTab == 'yiquxiao'" class="order-info"
style="margin-top: 50rpx;"> style="margin-top: 36rpx;">
<view class="item flex-justify-between"> <view class="item flex-justify-between">
<text class="label shrink-0">餐具数量</text> <text class="label shrink-0">餐具数量</text>
<view class="flex-1 flex-align-center" style="justify-content: flex-end; margin-left: 20rpx;"> <view class="flex-1 flex-align-center" style="justify-content: flex-end; margin-left: 20rpx;">
@ -298,8 +318,11 @@
<text v-if="order.discount > 0 && order.discount" class=" red">共减{{ <text v-if="order.discount > 0 && order.discount" class=" red">共减{{
Number(order.discount) + Number(order.discountCarriage) Number(order.discount) + Number(order.discountCarriage)
}}</text> }}</text>
<text class="wx-font-medium money"><text style="font-size: 36rpx;">{{ order.amountTo <text class="wx-font-medium money">
}}</text></text> <text style="font-size: 28rpx;"></text>
<text style="font-size: 36rpx;">{{ Number(order.amountTo).toFixed(2).split('.')[0] }}.</text>
<text style="font-size: 24rpx;">{{ Number(order.amountTo).toFixed(2).split('.')[1] }}</text>
</text>
</view> </view>
</view> </view>
</view> </view>
@ -439,6 +462,14 @@
</view> </view>
<view v-if="order.status == '等待付款'" class="placeholder"></view> <view v-if="order.status == '等待付款'" class="placeholder"></view>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark dark="light" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
</template> </template>
<script setup> <script setup>
@ -1025,6 +1056,7 @@ page {
.product-info { .product-info {
display: flex; display: flex;
margin-top: 14rpx; margin-top: 14rpx;
margin-bottom: 36rpx;
.image-box { .image-box {
width: 152rpx; width: 152rpx;
@ -1072,6 +1104,7 @@ page {
font-weight: 500; font-weight: 500;
font-size: 28rpx; font-size: 28rpx;
color: #1A1A1A; color: #1A1A1A;
line-height: 28rpx;
.price { .price {
font-size: 700; font-size: 700;

View File

@ -44,7 +44,7 @@ export default {
} }
// 跳转页面方法 // 跳转页面方法
app.config.globalProperties.$goRechargePage = (type) => { //保留小数 app.config.globalProperties.$goRechargePage = (type, source = 'uni_alipay_other') => { //保留小数
let pages = getCurrentPages(); let pages = getCurrentPages();
let currentPage = pages[pages.length - 1]; let currentPage = pages[pages.length - 1];
let currentUrl = currentPage.route; let currentUrl = currentPage.route;
@ -80,7 +80,7 @@ export default {
} }
}) })
uni.navigateTo({ uni.navigateTo({
url: '/pages/common/recharge/index' url: '/pages/common/recharge/index?source=' + source
}); });
} }