修改飞书记录问题

This commit is contained in:
tangxinyue 2026-04-17 11:16:04 +08:00
parent e01f4865e6
commit 2ea96ae0fa
18 changed files with 409 additions and 252 deletions

58
App.vue
View File

@ -78,37 +78,41 @@ export default {
this.globalData.NativeEvent = false
console.log('开始监听宿主消息')
uni.onNativeEventReceive((event, data) => {
if (event) {
console.log('接收到宿主消息:', event, data)
if (typeof uni.onNativeEventReceive === 'function') {
uni.onNativeEventReceive((event, data) => {
if (event) {
console.log('接收到宿主消息:', event, data)
if (event == "token") {
let header = uni.getStorageSync('header') || {}
header["x-token"] = data
uni.setStorageSync('header', header)
console.log('已更新 token')
if (event == "token") {
let header = uni.getStorageSync('header') || {}
header["x-token"] = data
uni.setStorageSync('header', header)
console.log('已更新 token')
//宿
try {
this.$getUserInfo()
} catch (error) {
console.error('获取用户信息失败:', error)
//宿
try {
this.$getUserInfo()
} catch (error) {
console.error('获取用户信息失败:', error)
}
} else if (event == "jump") {
if (data) {
console.log('接收到跳转指令,已缓存目标地址:', data);
uni.setStorageSync('jumpTarget_url', data);
// onShow
uni.reLaunch({
url: '/pages/index/index'
});
}
} else if (event == 'wx_pay_result' || event == 'ios_pay_result') {
this.globalData.recentNativeEvent = event
this.globalData.recentNativeData = data
}
} else if (event == "jump") {
if (data) {
console.log('接收到跳转指令,已缓存目标地址:', data);
uni.setStorageSync('jumpTarget_url', data);
// onShow
uni.reLaunch({
url: '/pages/index/index'
});
}
} else if (event == 'wx_pay_result' || event == 'ios_pay_result') {
this.globalData.recentNativeEvent = event
this.globalData.recentNativeData = data
}
}
})
})
} else {
console.log('uni.onNativeEventReceive 不可用,跳过监听')
}
}
},

View File

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

View File

@ -7,12 +7,21 @@
<!-- 输入层 -->
<template v-if="type !== 'textarea'">
<input class="auto-input" :type="type" :value="modelValue" :placeholder="placeholder" :placeholder-style="placeholderStyle"
:style="[inputStyle, { width: finalInputWidth }]" @input="onInput" :maxlength="maxlength" :focus="isFocus" @blur="onBlur" />
<input v-if="!disabled" class="auto-input" :type="type" :value="modelValue" :placeholder="placeholder"
: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 v-else>
<textarea class="auto-textarea" :value="modelValue" :placeholder="placeholder" :placeholder-style="placeholderStyle"
:style="[inputStyle]" @input="onInput" :maxlength="maxlength" auto-height :focus="isFocus" @blur="onBlur" />
<textarea v-if="!disabled" class="auto-textarea" :value="modelValue" :placeholder="placeholder"
: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>
<!-- 编辑图标 -->
@ -67,6 +76,14 @@ const props = defineProps({
showEdit: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
}
});
@ -86,6 +103,20 @@ const finalInputWidth = computed(() => {
});
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(() => ({
fontSize: props.fontSize,
fontWeight: props.fontWeight,

View File

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

View File

@ -62,13 +62,6 @@
</template>
<template v-else-if="item.products && item.products.length === 1">
<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 v-else-if="item.images && item.images.length > 0">
<scroll-view class="product-images-scroll" scroll-x :show-scrollbar="false">
@ -86,19 +79,32 @@
</view>
</view>
</template>
<view class="product-price-box">
<view class="price-wrap wx-font-regular">
<text class="price-symbol"></text>
<text class="price-num">{{ item.shopType === 'waimai' ?
(item.totalPrice ? Number(item.totalPrice).toFixed(2) : '0.00')
:
safeFormatPrice(item)
}}</text>
<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="price-wrap wx-font-regular">
<text class="price-symbol"></text>
<text class="price-num">{{ item.shopType === 'waimai' ?
(item.totalPrice ? Number(item.totalPrice).toFixed(2) : '0.00')
:
safeFormatPrice(item)
}}</text>
</view>
<text class="product-count"
v-if="item.count || (item.products && item.products[0] && item.products[0].count)">{{
item.count || (item.products && item.products[0] && item.products[0].count) }}</text>
</view>
<text class="product-count"
v-if="item.count || (item.products && item.products[0] && item.products[0].count)">{{
item.count || (item.products && item.products[0] && item.products[0].count) }}</text>
</view>
</view>
<!-- Promo -->
@ -518,15 +524,15 @@ const getButtons = (shopType, status, item) => {
.product-info {
flex: 1;
width: 100px;
display: flex;
flex-direction: column;
width: 20rpx;
.product-title {
font-size: 26rpx;
color: #1A1A1A;
line-height: 36rpx;
white-space: nowrap;
// white-space: nowrap;
text-overflow: hidden;
overflow: hidden;
}
@ -567,6 +573,7 @@ const getButtons = (shopType, status, item) => {
color: #1A1A1A;
font-size: 30rpx;
margin-bottom: 4rpx;
line-height: 36rpx;
display: flex;
align-items: baseline;
@ -711,6 +718,7 @@ const getButtons = (shopType, status, item) => {
align-items: center;
flex-wrap: wrap;
justify-content: flex-end;
position: relative;
.btn {
position: relative;

View File

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

View File

@ -27,7 +27,7 @@ export function createApp() {
const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
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.use(globalMethods);
return {

View File

@ -1,21 +1,22 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<watermark :dark="data.dark" source="uni_alipay_huabei" />
<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>
</liu-drag-button>
</view>
<view class="page-container">
<view class="main-container">
<NavBar v-if="!selectedImage" title="花呗" :bgColor="data.navBar.bgColor" tipLayerType="huabei-tip" isTipLayer
tipLayerText="修改花呗信息" :buttonGroup="buttonGroup" @button-click="clickTitlePopupButton">
<NavBar ref="navBarRef" v-if="!selectedImage" title="花呗" :bgColor="data.navBar.bgColor"
tipLayerType="huabei-tip" isTipLayer tipLayerText="修改花呗信息" :buttonGroup="buttonGroup"
@button-click="clickTitlePopupButton">
<!-- 使用作用域插槽自定义按钮渲染特别是switch的checked绑定 -->
<template #button="{ button }">
<view class="button flex-align-center flex-justify-center">
{{ button.name }}
<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>
</view>
</view>
@ -44,11 +45,13 @@
<view v-if="huabeiInfo.styleType == 1" class="current-month">{{ huabeiInfo.mouth }}月应还()</view>
<view v-else class="current-month">{{ huabeiInfo.mouth }}月账单累计中()</view>
<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>
</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 v-if="!huabeiInfo.isInstallment" class="button-item primary-button"
:class="{ 'ios-button': $system == 'iOS' }">
@ -58,17 +61,20 @@
</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="arrow"></view>
<text class="text">{{ huabeiInfo.descText }}</text>
</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="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>
</text>
</view>
@ -81,7 +87,8 @@
<view class="info-item">
<view class="label">总计额度</view>
<view class="value">{{
numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount) - Number(huabeiInfo.money))
huabeiInfo.isPayOff ? numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount)) :
numberUtil.formatMoneyWithThousand(Number(huabeiInfo.totalAmount) - Number(huabeiInfo.money))
}}可用
</view>
</view>
@ -201,6 +208,8 @@ import {
const instance = getCurrentInstance();
const { proxy } = instance;
const navBarRef = ref(null)
const buttonGroup = [{
name: "编辑花呗数据",
@ -221,6 +230,7 @@ const buttonGroup = [{
}, {
name: "花呗逾期",
isSwitch: true,
key: 'isOverdue',
click: () => {
data.huabeiInfo.isOverdue = !data.huabeiInfo.isOverdue
uni.setStorageSync(data.huabeiInfoStorageKey, data.huabeiInfo)
@ -229,6 +239,20 @@ const buttonGroup = [{
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;
.text {
color: #ffffff;
color: #B9D6FF;
font-size: 26rpx;
line-height: 1.2;
}
@ -738,7 +762,7 @@ const goBack = () => {
}
.value {
color: #ffffff;
color: #B9D6FF;
font-size: 26rpx;
line-height: 36rpx;
}

View File

@ -206,8 +206,8 @@
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<watermark :dark="data.dark" source="uni_alipay_huabei" />
<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>
</liu-drag-button>
</view>

View File

@ -1,8 +1,8 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<watermark :dark="data.dark" source="uni_alipay_balance" />
<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>
</liu-drag-button>
</view>

View File

@ -1,8 +1,8 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<watermark :dark="data.dark" source="uni_alipay_bill_details" />
<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>
</liu-drag-button>
</view>

View File

@ -1,8 +1,8 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<watermark :dark="data.dark" source="uni_alipay_bill" />
<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>
</liu-drag-button>
</view>

View File

@ -4,7 +4,7 @@
<view>
<image :src="data.banner" style="width: 100%;height: 244px;"></image>
</view>
<exchange/>
<exchange />
<!-- <view style="margin-top:-90px;position: relative;">
<customTab :isHuise="shouldBeTrue(data.goods)" />
</view> -->
@ -35,13 +35,14 @@
<image src="/static/image/recharge/vipContentTopBgImg.png" mode="widthFix"></image>
</view>
<view class="vipList">
<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)">
<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)">
<image :src="item.url"></image>
<text>{{ item.name }}</text>
</view>
</template>
</view>
</view>
@ -131,7 +132,8 @@
合计
<text></text>
<countUp :num="$toFiexd(data.price, 2)" height="24" style="margin-top: -6px;" color="red"
fontSize='24'></countUp>
fontSize='24'>
</countUp>
已优惠{{ $toFiexd(data.coupon, 0) }}
</view>
<view class="button" @click="activateVip">
@ -369,65 +371,65 @@ const data = reactive({
}],
//
benefitList: [{
name: "无广告",
url: "/static/image/recharge/icon1.png"
},
{
name: "无水印",
url: "/static/image/recharge/icon2.png"
},
{
name: "微信模拟",
url: "/static/image/recharge/icon3.png"
},
{
name: "小宝模拟",
url: "/static/image/recharge/icon4.png"
},
{
name: "豪车模拟",
url: "/static/image/recharge/icon5.png"
},
{
name: "模拟来电",
url: "/static/image/recharge/icon6.png"
},
{
name: "视频群聊",
url: "/static/image/recharge/icon7.png"
},
{
name: "工资单",
url: "/static/image/recharge/icon8.png"
},
{
name: "身份证",
url: "/static/image/recharge/icon9.png"
},
{
name: "发圈素材",
url: "/static/image/recharge/icon10.png"
},
{
name: "机票",
url: "/static/image/recharge/icon11.png"
},
{
name: "高铁表",
url: "/static/image/recharge/icon12.png"
},
{
name: "短信模拟",
url: "/static/image/recharge/icon13.png"
},
{
name: "通话模拟",
url: "/static/image/recharge/icon14.png"
},
{
name: "多设备",
url: "/static/image/recharge/icon15.png"
}
name: "无广告",
url: "/static/image/recharge/icon1.png"
},
{
name: "无水印",
url: "/static/image/recharge/icon2.png"
},
{
name: "微信模拟",
url: "/static/image/recharge/icon3.png"
},
{
name: "小宝模拟",
url: "/static/image/recharge/icon4.png"
},
{
name: "豪车模拟",
url: "/static/image/recharge/icon5.png"
},
{
name: "模拟来电",
url: "/static/image/recharge/icon6.png"
},
{
name: "视频群聊",
url: "/static/image/recharge/icon7.png"
},
{
name: "工资单",
url: "/static/image/recharge/icon8.png"
},
{
name: "身份证",
url: "/static/image/recharge/icon9.png"
},
{
name: "发圈素材",
url: "/static/image/recharge/icon10.png"
},
{
name: "机票",
url: "/static/image/recharge/icon11.png"
},
{
name: "高铁表",
url: "/static/image/recharge/icon12.png"
},
{
name: "短信模拟",
url: "/static/image/recharge/icon13.png"
},
{
name: "通话模拟",
url: "/static/image/recharge/icon14.png"
},
{
name: "多设备",
url: "/static/image/recharge/icon15.png"
}
],
goodsList: [],
myActivity: [],
@ -462,6 +464,7 @@ const data = reactive({
isProcessingClick: false,
banner: '/static/image/recharge/banner1.png',
isCombo: false,
source: "uni_alipay_other"
})
let {
@ -470,7 +473,8 @@ let {
benefitList,
noticeList,
commentList,
paymentMethod
paymentMethod,
source
} = toRefs(data)
/**
@ -485,6 +489,9 @@ onBackPress((e) => {
onLoad(async () => {
if (option.source) {
data.source = option.source
}
const config = uni.getStorageSync('config').config
const themeConfig = config?.['client.uniapp.theme']
if (themeConfig?.enable) {
@ -493,12 +500,12 @@ onLoad(async () => {
// })
} else if (themeConfig?.theme == '0217') {
data.banner = '/static/image/recharge/chunjie/bannar.png'
}else if (themeConfig?.theme == '0405') {
} else if (themeConfig?.theme == '0405') {
data.banner = '/static/image/recharge/qmj/bannar.png'
data.benefitList.forEach(item=>{
item.url=item.url.replace('/static/image/recharge/','/static/image/recharge/qmj/')
data.benefitList.forEach(item => {
item.url = item.url.replace('/static/image/recharge/', '/static/image/recharge/qmj/')
})
}else if (themeConfig?.theme == '0401') {
} else if (themeConfig?.theme == '0401') {
data.banner = '/static/image/recharge/yrj/bannar.png'
}
}
@ -526,8 +533,8 @@ onLoad(async () => {
})
console.log(goods)
if (goods.code == 0) {
data.goodsList.forEach(item=>{
item['features']=item['features']||''
data.goodsList.forEach(item => {
item['features'] = item['features'] || ''
})
data.goodsList = goods.data
@ -1167,7 +1174,8 @@ async function activateVip(type = '') {
coupon: data.active_id ? data.active_id : '',
pay_type: paymentMethod.value == "wxpay" ? (data.goods.weixinMpOriId && isComBo ? 'combo' : 'weixin') : "alipay",
"pay_source": "app",
source: "uni_alipay",
// source: "uni_alipay",
source: data.source,
})
@ -1678,13 +1686,14 @@ function shouldBeTrue(obj) {
background-color: #F7F7F7;
border-radius: 16px 16px 0 0;
width: 100vw;
margin-top:-70px;
margin-top: -70px;
// background: linear-gradient(to bottom, #FFFFFF, #F7F7F7);
}
.package-items-container {
display: flex;
padding: 40rpx 32rpx 40rpx 32rpx;
padding: 40rpx 32rpx 40rpx 32rpx;
.active-package-item-tips {
position: absolute;
content: '限时优惠';
@ -2239,7 +2248,7 @@ function shouldBeTrue(obj) {
}
.myCouponList {
margin:20rpx 32rpx;
margin: 20rpx 32rpx;
padding: 17px 13px;
height: 18px;
background-color: #FFFFFF;
@ -2500,7 +2509,7 @@ function shouldBeTrue(obj) {
.vipList {
display: flex;
flex-wrap: wrap;
padding:0 10px 10px 10px;
padding: 0 10px 10px 10px;
.item {
width: 20%;
@ -2525,10 +2534,12 @@ function shouldBeTrue(obj) {
}
}
}
@font-face {
font-family: 'AlipayNumber'; //
src: url('/static/font/AlipayNumber.ttf');
}
.wx-font-regular {
font-family: 'AlipayNumber' !important;
}

View File

@ -380,7 +380,8 @@
<view class="flex-1 flex-align-center"
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"
: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>
@ -392,7 +393,8 @@
<view class="flex-1 flex-align-center"
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"
: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 File

@ -193,9 +193,9 @@
placeholder="商品描述" color="#87868E" show-edit />
</view>
<view class="flex flex-align-center animate-scale">
<auto-width-input class="desc" v-model="product.count" type="textarea" fontSize="22rpx"
placeholder="请输入数量" color="#8D8D8D" show-edit />
<view class="flex flex-align-center animate-scale desc">
<auto-width-input style="width: calc(100% - 18px);" v-model="product.count" type="number"
fontSize="22rpx" placeholder="请输入数量" color="#8D8D8D" show-edit minWidth="100%" />
</view>
<view class="flex flex-align-center animate-scale wx-font-medium"
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"
fontSize="36rpx" placeholder="0.00" color="#1A1A1A" fontWeight="500" show-edit />
</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 v-if="pIndex < order.products.length - 1" class="product-divider"></view>
@ -346,7 +353,7 @@
<view class="flex-1 flex-align-center"
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"
type="text" color="#1A1A1A" show-edit />
type="text" color="#1A1A1A" show-edit :disabled="true" />
</view>
</view>
<view class="item flex-justify-between">
@ -373,7 +380,8 @@
<view class="flex-1 flex-align-center"
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"
: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>
@ -616,6 +624,7 @@ const addProduct = () => {
desc: "",
service: "不支持7天无理由退货",
price: "0.00",
discount: "0.00",
count: 1
});
};
@ -1070,6 +1079,26 @@ watch(() => order.value.products, (newProducts) => {
}
}, { 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-size: 28rpx;
color: #1A1A1A;
line-height: 28rpx;
.price {
font-weight: 500;
@ -1745,6 +1775,7 @@ const onConfirm = () => {
background-color: #FFFFFF;
border-radius: 24rpx;
padding: 28rpx 22rpx;
align-items: flex-start;
&.product-info-box {
padding: 0;

View File

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

View File

@ -204,41 +204,61 @@
</view>
<uni-icons class="right-icon" size="14" color="#1A1A1A" type="right"></uni-icons>
</view>
<view class="product-info">
<view class="image-box">
<image v-if="order.products && order.products[0]" class="w100 h100" :src="order.products[0].image"
mode="widthFix">
<view class="product-info flex-align-center" v-for="(item, i) in order.products" :key="i">
<view class="image-box shrink-0">
<image v-if="item" class="w100 h100" :src="item.image" mode="widthFix">
</image>
</view>
<view class="info-box">
<view class="name">{{ order.products && order.products[0]?.title }}</view>
<view class="desc">{{ order.products && order.products[0]?.desc }}</view>
<view class="tag">数量x{{ order.products && order.products[0]?.count }}</view>
</view>
<view class="price-box">
<view v-if="(order.status != '等待付款' && order.status != '已取消') && order.discount > 0" class="flex-center"
style="display: inline-block;">
<image style="width: 22rpx;height: 22rpx;margin-right: 4rpx;"
src="/static/image/shopping/jingdong/detail/help.png">
</image>
<text
style="font-size: 22rpx;height: 22rpx;color: #87868E;font-weight: 300;line-height: 22rpx;margin-right: 2rpx;">到手价</text>
<view class="flex-1 flex" style="width:100px">
<view class="info-box">
<view class="name">{{ item.title }}</view>
<view v-if="item.desc" class="desc">{{ item.desc }}</view>
<view v-if="item.count" class="tag">数量x{{ item.count }}</view>
</view>
<text class="price wx-font-medium">{{
order.status == '等待付款' || order.status == '已取消' ?
Number(order.products && order.products[0]?.price || 0).toFixed(2) :
Number((order.products && order.products[0]?.price || 0) - (order.discount || 0)).toFixed(2)
}}</text>
<view v-if="(order.status != '等待付款' && order.status != '已取消') && (order.discount || 0) > 0"
class="wx-font-medium" style="margin-top: 2rpx;text-align: right;color: #87868E;font-weight: 500;">
<text style="font-size: 24rpx;">{{ Number(order.products && order.products[0]?.price ||
0).toFixed(2)
}}</text>
<view class="price-box">
<view v-if="(order.status != '等待付款' && order.status != '已取消') && order.discount > 0"
class="flex-center" style="display: inline-flex;">
<image style="width: 22rpx;height: 22rpx;margin-right: 4rpx;"
src="/static/image/shopping/jingdong/detail/help.png">
</image>
<text
style="font-size: 22rpx;height: 22rpx;color: #1A1A1A;line-height: 22rpx;margin-right: 2rpx;">到手</text>
</view>
<text class="price wx-font-medium">
<text style="font-size: 28rpx;"></text>
<text style="font-size: 32rpx;">
{{ 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 style="font-size: 24rpx;">.</text>
<text style="font-size: 20rpx;">{{ Number(item.discount || 0).toFixed(2).split('.')[1]
}}</text>
</text>
</view>
</view>
</view>
</view>
<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">
<text class="label shrink-0">餐具数量</text>
<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">共减{{
Number(order.discount) + Number(order.discountCarriage)
}}</text>
<text class="wx-font-medium money"><text style="font-size: 36rpx;">{{ order.amountTo
}}</text></text>
<text class="wx-font-medium money">
<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>
@ -439,6 +462,14 @@
</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>
<script setup>
@ -1025,6 +1056,7 @@ page {
.product-info {
display: flex;
margin-top: 14rpx;
margin-bottom: 36rpx;
.image-box {
width: 152rpx;
@ -1072,6 +1104,7 @@ page {
font-weight: 500;
font-size: 28rpx;
color: #1A1A1A;
line-height: 28rpx;
.price {
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 currentPage = pages[pages.length - 1];
let currentUrl = currentPage.route;
@ -80,7 +80,7 @@ export default {
}
})
uni.navigateTo({
url: '/pages/common/recharge/index'
url: '/pages/common/recharge/index?source=' + source
});
}
@ -172,12 +172,12 @@ export default {
const sortedKeys = Object.keys(data.data).sort();
let str = ''
for (const key of sortedKeys) {
if(!(data.url=='api/image/segment/base64'&&key=='file')){
if (!(data.url == 'api/image/segment/base64' && key == 'file')) {
str += '&' + key + '=' + encodeURIComponent(data.data[key]);
}
}
str = str.replace('&', '?')
host=host+str
host = host + str
console.log(host)
console.log(data)
const response = await new Promise((resolve, reject) => {
@ -187,7 +187,7 @@ export default {
data: data.data,
header,
success: res => {
console.log(res)
console.log(res)
try {
if (isCode) {
res.data = deCode(res.data.data)
@ -232,12 +232,12 @@ export default {
//请求地址
let host = uni.getStorageSync('host') + 'api/image/segment'
header['content-type'] = "multipart/form-data"
// // 排序
let data={
method:'POST',
data:{},
url:'api/image/segment'
let data = {
method: 'POST',
data: {},
url: 'api/image/segment'
}
data = sign(data)
const sortedKeys = Object.keys(data.data).sort();
@ -245,41 +245,41 @@ export default {
for (const key of sortedKeys) {
str += '&' + key + '=' + encodeURIComponent(data.data[key]);
}
str = str.replace('&', '?')
// 拼接URL
host = host + str
console.log(host);
console.log(data);
uni.uploadFile({
url: host, // 完整URL
filePath: filePath,
name: 'file',
method:"POST",
header: header,
formData:{
url: host, // 完整URL
filePath: filePath,
name: 'file',
method: "POST",
header: header,
formData: {
...data.data
},
success: (res) => {
console.log('1.上传成功:',JSON.stringify(res));
},
fail: (err) => {
console.error('2. 错误详情:', JSON.stringify(err));
},
complete: (res) => {
console.log('3. 上传完成');
}
});
success: (res) => {
console.log('1.上传成功:', JSON.stringify(res));
},
fail: (err) => {
console.error('2. 错误详情:', JSON.stringify(err));
},
complete: (res) => {
console.log('3. 上传完成');
}
});
};
app.config.globalProperties.$imageUpload = async (imagePath) => {
return new Promise((resolve, reject) => {
postJson('a', 'api/image/segment/base64', {
file:imagePath
}).then(res=>{
file: imagePath
}).then(res => {
resolve(res)
}).catch(err=>{
}).catch(err => {
reject(err)
})
})