shish 1 день назад
Родитель
Сommit
888cecb16f
2 измененных файлов с 479 добавлено и 667 удалено
  1. 476 664
      hdh5/admin/ghs/pay.vue
  2. 3 3
      mallh5/unpackage/dist/cache/.vite/deps/_metadata.json

+ 476 - 664
hdh5/admin/ghs/pay.vue

@@ -1,104 +1,104 @@
 <template>
-	<view class="pay-container">
-		<!-- 支付金额区域 -->
-		<view class="amount-section">
-			<view class="amount-label">支付金额</view>
-			<view class="amount-display">
-				<text class="currency">¥</text>
-				<text class="amount">{{ displayAmount }}</text>
+	<!--
+		H5 向供货商付款页(支付宝收款风格)
+		用途:扫码后输入金额并用支付宝支付;展示待结与余额入口
+	-->
+	<view class="pay-page">
+		<!-- 收款方信息 -->
+		<view class="pay-merchant">
+			<view class="pay-merchant__avatar">
+				<text class="pay-merchant__avatar-text">{{ merchantInitial }}</text>
+			</view>
+			<view class="pay-merchant__meta">
+				<text class="pay-merchant__label">付款给</text>
+				<text class="pay-merchant__name">{{ merchantName }}</text>
 			</view>
-			<button class="clear-amount-btn" @click="changeAmount(0)">清空金额</button>
 		</view>
 
-		<!-- 客户信息:金额独占;待结订单/余额明细沉底并排 -->
-		<view class="customer-info-card">
-			<view class="card-header">
-				<view class="customer-avatar">
-					<text class="avatar-text">{{ customInfo.name ? customInfo.name.charAt(0) : '客' }}</text>
-				</view>
-				<view class="customer-details">
-					<text class="customer-name">{{ displayCustomName }}</text>
-				</view>
+		<!-- 金额主视觉 -->
+		<view class="pay-amount-card">
+			<view class="pay-amount-card__head">
+				<text class="pay-amount-card__title">付款金额</text>
+				<text v-if="canPay" class="pay-amount-card__clear" @click="changeAmount(0)">清空</text>
 			</view>
-			<view class="debt-info" v-if="hasOutstanding">
-				<view class="debt-amount" @click="changeAmount(outstandingAmount)">
-					<text class="debt-label">待结金额</text>
-					<text class="debt-value">¥{{ outstandingAmount }}</text>
-				</view>
+			<view class="pay-amount-row">
+				<text class="pay-amount-row__currency">¥</text>
+				<text class="pay-amount-row__value" :class="{ 'pay-amount-row__value--placeholder': !canPay }">{{ amountText }}</text>
+				<view class="pay-amount-row__cursor"></view>
 			</view>
-			<!-- 次级入口:有待结双按钮等宽,无待结时单按钮半宽 -->
-			<view class="pay-entry-row" :class="{ 'pay-entry-row--single': !showGatheringBtn }">
-				<view
+
+			<!-- 待结提示:点按可填入金额 -->
+			<view
+				v-if="hasOutstanding"
+				class="pay-debt-tip"
+				@click="fillOutstanding">
+				<text class="pay-debt-tip__label">待结金额</text>
+				<text class="pay-debt-tip__value">¥{{ outstandingAmount }}</text>
+				<text class="pay-debt-tip__action">填入</text>
+			</view>
+
+			<!-- 次级文字入口,不抢金额视觉 -->
+			<view class="pay-links">
+				<text
 					v-if="showGatheringBtn"
-					class="pay-entry-btn pay-entry-btn--debt"
-					@click="goGathering">
-					<text class="pay-entry-btn__text">查看待结订单</text>
-				</view>
-				<view
-					class="pay-entry-btn"
-					:class="{ 'pay-entry-btn--disabled': !id }"
-					@click="goBalanceChange">
-					<text class="pay-entry-btn__text">查看余额明细</text>
-				</view>
+					class="pay-link pay-link--debt"
+					@click="goGathering">查看待结订单</text>
+				<text
+					v-if="showGatheringBtn"
+					class="pay-link__dot">|</text>
+				<text
+					class="pay-link"
+					:class="{ 'pay-link--disabled': !id }"
+					@click="goBalanceChange">查看余额明细</text>
 			</view>
 		</view>
 
-		<!-- 数字键盘 - 使用直接事件绑定,确保兼容性 -->
-		<view class="keyboard-section">
-			<view class="keyboard">
-				<view class="keyboard-row" v-for="(row, rowIndex) in keyboardKeys" :key="rowIndex">
-					<view 
-						class="key-item" 
-						v-for="(key, keyIndex) in row" 
-						:key="`${rowIndex}-${keyIndex}`"
-						:class="{ 
-							'key-number': key.type === 'number',
-							'key-delete': key.type === 'delete',
-							'key-dot': key.type === 'dot',
-							'key-confirm': key.type === 'confirm'
-						}"
-						@click="handleKeyPress(key)"
-						@touchstart="handleTouchStart"
-						@touchend="handleTouchEnd"
-					>
-						<text v-if="key.type === 'delete'" class="iconfont icon-delete"></text>
-						<text v-else-if="key.type === 'confirm'">确认</text>
-						<text v-else>{{ key.value }}</text>
+		<!-- 客户角标(谁在付) -->
+		<view v-if="displayCustomName" class="pay-payer">
+			<text class="pay-payer__text">付款账户:{{ displayCustomName }}</text>
+		</view>
+
+		<!-- 底部:支付宝式数字键盘 + 右侧付款键 -->
+		<view class="pay-keyboard-wrap">
+			<view class="pay-keyboard">
+				<view class="pay-keyboard__keys">
+					<view
+						v-for="(key, index) in flatKeys"
+						:key="index"
+						class="pay-key"
+						:class="{ 'pay-key--del': key.type === 'delete' }"
+						@click="handleKeyPress(key)">
+						<view class="pay-key__inner">
+							<text v-if="key.type === 'delete'" class="pay-key__del">⌫</text>
+							<text v-else class="pay-key__num">{{ key.value }}</text>
+						</view>
 					</view>
 				</view>
+				<view
+					class="pay-key-pay"
+					:class="{ 'pay-key-pay--disabled': !canPay }"
+					@click="handlePay">
+					<text class="pay-key-pay__text">付款</text>
+				</view>
 			</view>
+			<view class="pay-safe-area"></view>
 		</view>
-
-		<!-- 支付按钮 -->
-		<view class="pay-button-section">
-			<button 
-				class="pay-button" 
-				:class="{ disabled: !canPay }"
-				:disabled="!canPay"
-				@click="handlePay"
-			>
-				<text class="button-text">支付宝支付</text>
-			</button>
-		</view>
-
-
 	</view>
 </template>
 
 <script>
-import { getGhsData } from '@/api/ghs';
+import { getGhsData } from '@/api/ghs'
 import { rechargeFn } from '@/api/custom-recharge'
 
-// 优化:使用常量避免重复创建
 const KEY_TYPES = {
 	NUMBER: 'number',
 	DELETE: 'delete',
 	DOT: 'dot',
 	CONFIRM: 'confirm'
-};
+}
 
-const MAX_INTEGER_LENGTH = 8;
-const MAX_DECIMAL_LENGTH = 2;
+const MAX_INTEGER_LENGTH = 8
+const MAX_DECIMAL_LENGTH = 2
 
 export default {
 	name: 'pay',
@@ -106,7 +106,6 @@ export default {
 		return {
 			currentAmount: '0',
 			displayAmount: '0',
-			// 优化:使用静态数据,避免重复创建
 			keyboardKeys: [
 				[
 					{ type: KEY_TYPES.NUMBER, value: '1' },
@@ -129,33 +128,48 @@ export default {
 					{ type: KEY_TYPES.DELETE, value: '' }
 				]
 			],
-			// 优化:使用更高效的状态管理
 			amountBuffer: '0',
 			updateScheduled: false,
 			updateTimer: null,
-
-			id:0,
-			salt:'',
-			ghsInfo:[],
-			customInfo:{},
-			payWay:1
+			id: 0,
+			salt: '',
+			ghsInfo: {},
+			customInfo: {},
+			payWay: 1
 		}
 	},
 	computed: {
-		// 简化支付按钮判断逻辑:只要大于0就能支付
 		canPay() {
-			const amount = parseFloat(this.currentAmount);
-			return amount > 0;
+			return parseFloat(this.currentAmount) > 0
+		},
+		/** 金额展示:输入中保留原始缓冲,避免过早补零打断输入 */
+		amountText() {
+			if (!this.canPay && this.amountBuffer === '0') {
+				return '0.00'
+			}
+			return this.amountBuffer
 		},
-		/** 客户名最多 7 字,避免挤占入口区 */
 		displayCustomName() {
-			const name = (this.customInfo && this.customInfo.name) ? String(this.customInfo.name) : '客户'
+			const name = (this.customInfo && this.customInfo.name) ? String(this.customInfo.name) : ''
+			if (!name) {
+				return ''
+			}
 			if (name.length > 7) {
 				return name.slice(0, 7) + '...'
 			}
 			return name
 		},
-		/** 待结金额:优先 remainDebtAmount,否则净 balance 负值取绝对值 */
+		merchantName() {
+			const name = (this.ghsInfo && this.ghsInfo.name) ? String(this.ghsInfo.name) : '供货商'
+			if (name.length > 12) {
+				return name.slice(0, 12) + '...'
+			}
+			return name
+		},
+		merchantInitial() {
+			const name = (this.ghsInfo && this.ghsInfo.name) ? String(this.ghsInfo.name) : '商'
+			return name.charAt(0) || '商'
+		},
 		outstandingAmount() {
 			const info = this.customInfo || {}
 			const remain = parseFloat(info.remainDebtAmount || 0)
@@ -168,700 +182,498 @@ export default {
 		hasOutstanding() {
 			return this.outstandingAmount > 0
 		},
-		/** 有待结时才展示「查看待结订单」 */
 		showGatheringBtn() {
 			return this.hasOutstanding && !!this.id
+		},
+		/** 键盘扁平化为 12 键网格,配合右侧付款柱 */
+		flatKeys() {
+			const keys = []
+			this.keyboardKeys.forEach((row) => {
+				row.forEach((key) => {
+					keys.push(key)
+				})
+			})
+			return keys
 		}
 	},
 	onLoad(options) {
 		if (options.id) {
-			this.id = options.id;
+			this.id = options.id
 		}
 		if (options.salt) {
-			this.salt = options.salt;
+			this.salt = options.salt
 		}
-		let that = this
 		if (this.id && this.salt) {
-			getGhsData({id:this.id,salt:this.salt}).then(res => {
-				if (res.data && res.data.ghs){
-					that.ghsInfo = res.data.ghs
-					that.customInfo = res.data.custom?res.data.custom:[]
-
-					if(that.customInfo.remainDebtAmount && Number(that.customInfo.remainDebtAmount)>0){
-						that.currentAmount = parseFloat(that.customInfo.remainDebtAmount).toString()
-						that.updateDisplay()
+			getGhsData({ id: this.id, salt: this.salt }).then(res => {
+				if (res.data && res.data.ghs) {
+					this.ghsInfo = res.data.ghs
+					this.customInfo = res.data.custom ? res.data.custom : {}
+					if (this.hasOutstanding) {
+						this.fillOutstanding()
 					}
 				}
 			})
 		}
-		
-
 	},
 	methods: {
-		changeAmount(amount){
-			this.currentAmount = amount
-			this.updateDisplay()
-		},
-		// 优化:添加触摸反馈
-		handleTouchStart(e) {
-			const target = e.currentTarget;
-			if (target && target.style) {
-				target.style.transform = 'scale(0.95)';
+		/** 同步缓冲与展示金额 */
+		changeAmount(amount) {
+			const num = parseFloat(amount)
+			if (!num || num <= 0) {
+				this.amountBuffer = '0'
+				this.currentAmount = '0'
+				this.displayAmount = '0'
+				return
 			}
+			const amountStr = parseFloat(num.toFixed(2)).toString()
+			this.amountBuffer = amountStr
+			this.currentAmount = amountStr
+			this.updateDisplay()
 		},
-		
-		handleTouchEnd(e) {
-			const target = e.currentTarget;
-			if (target && target.style) {
-				setTimeout(() => {
-					target.style.transform = 'scale(1)';
-				}, 100);
+		/** 一键填入待结金额 */
+		fillOutstanding() {
+			if (!this.hasOutstanding) {
+				return
 			}
+			this.changeAmount(this.outstandingAmount)
 		},
-
-		// 优化:简化的键盘处理逻辑
+		handleTouchStart() {},
+		handleTouchEnd() {},
 		handleKeyPress(key) {
-			// 防抖处理
 			if (this.updateTimer) {
-				clearTimeout(this.updateTimer);
+				clearTimeout(this.updateTimer)
 			}
-			
 			if (key.type === KEY_TYPES.NUMBER) {
-				this.addNumber(key.value);
+				this.addNumber(key.value)
 			} else if (key.type === KEY_TYPES.DELETE) {
-				this.deleteNumber();
+				this.deleteNumber()
 			} else if (key.type === KEY_TYPES.DOT) {
-				this.addDecimal();
+				this.addDecimal()
 			}
-			
-			// 使用 requestAnimationFrame 优化更新
-			this.scheduleUpdate();
+			this.scheduleUpdate()
 		},
-
-		// 优化:使用 requestAnimationFrame 调度更新
 		scheduleUpdate() {
 			if (!this.updateScheduled) {
-				this.updateScheduled = true;
+				this.updateScheduled = true
 				requestAnimationFrame(() => {
-					this.updateDisplay();
-					this.updateScheduled = false;
-				});
+					this.updateDisplay()
+					this.updateScheduled = false
+				})
 			}
 		},
-
-		// 优化:更高效的数字添加逻辑
 		addNumber(num) {
-			const buffer = this.amountBuffer;
-			
-			// 快速路径:如果当前是0且输入的不是小数点,直接替换
+			const buffer = this.amountBuffer
 			if (buffer === '0' && num !== '.') {
-				this.amountBuffer = num;
-				this.currentAmount = num;
-				return;
+				this.amountBuffer = num
+				this.currentAmount = num
+				return
 			}
-
-			// 检查长度限制
-			const parts = buffer.split('.');
-			const integerPart = parts[0];
-			const decimalPart = parts[1];
-
-			// 整数部分限制
+			const parts = buffer.split('.')
+			const integerPart = parts[0]
+			const decimalPart = parts[1]
 			if (!decimalPart && integerPart.length >= MAX_INTEGER_LENGTH) {
-				uni.showToast({
-					title: '金额不能超过8位数',
-					icon: 'none',
-					duration: 1500
-				})
-				return;
+				uni.showToast({ title: '金额不能超过8位数', icon: 'none', duration: 1500 })
+				return
 			}
-
-			// 小数部分限制
 			if (decimalPart && decimalPart.length >= MAX_DECIMAL_LENGTH) {
-				uni.showToast({
-					title: '最多支持2位小数',
-					icon: 'none',
-					duration: 1500
-				})
-				return;
+				uni.showToast({ title: '最多支持2位小数', icon: 'none', duration: 1500 })
+				return
 			}
-
-			// 添加数字
-			this.amountBuffer = buffer + num;
-			this.currentAmount = this.amountBuffer;
+			this.amountBuffer = buffer + num
+			this.currentAmount = this.amountBuffer
 		},
-
-		// 优化:更高效的小数点添加逻辑
 		addDecimal() {
 			if (!this.amountBuffer.includes('.')) {
-				this.amountBuffer += '.';
-				this.currentAmount = this.amountBuffer;
+				this.amountBuffer += '.'
+				this.currentAmount = this.amountBuffer
 			}
 		},
-
-		// 优化:更高效的删除逻辑
 		deleteNumber() {
-			const buffer = this.amountBuffer;
+			const buffer = this.amountBuffer
 			if (buffer.length > 1) {
-				this.amountBuffer = buffer.slice(0, -1);
+				this.amountBuffer = buffer.slice(0, -1)
 			} else {
-				this.amountBuffer = '0';
+				this.amountBuffer = '0'
 			}
-			this.currentAmount = this.amountBuffer;
+			this.currentAmount = this.amountBuffer
 		},
-
-		// 优化:更高效的显示更新逻辑
 		updateDisplay() {
-			let amount = this.currentAmount;
-			
-			// 确保 amount 是字符串类型
+			let amount = this.currentAmount
 			if (typeof amount !== 'string') {
-				amount = amount.toString();
+				amount = amount.toString()
 			}
-			
-			// 快速路径:如果是0,直接显示
 			if (amount === '0') {
-				this.displayAmount = '0';
-				return;
+				this.displayAmount = '0'
+				return
 			}
-
-			// 检查是否包含小数点
 			if (amount.includes('.')) {
-				const numAmount = parseFloat(amount) || 0;
-				this.displayAmount = numAmount.toFixed(2);
+				const numAmount = parseFloat(amount) || 0
+				this.displayAmount = numAmount.toFixed(2)
 			} else {
-				// 整数显示
-				this.displayAmount = amount;
+				this.displayAmount = amount
 			}
 		},
-
-		// 优化:更高效的金额设置
 		setAmount(amount) {
-			const numAmount = parseFloat(amount);
-			if (!isNaN(numAmount) && numAmount > 0) {
-				const amountStr = numAmount.toString();
-				this.amountBuffer = amountStr;
-				this.currentAmount = amountStr;
-				this.updateDisplay();
-			}
+			this.changeAmount(amount)
 		},
-
-
-		// 处理支付
 		handlePay() {
-			if (!this.canPay) return;
-			const amount = parseFloat(this.currentAmount);
-			// 简化验证:只要大于0就能支付
+			if (!this.canPay) {
+				return
+			}
+			const amount = parseFloat(this.currentAmount)
 			if (amount <= 0) {
-				uni.showToast({
-					title: '请输入金额!',
-					icon: 'none',
-					duration: 2000
-				})
+				uni.showToast({ title: '请输入金额!', icon: 'none', duration: 2000 })
 				return false
 			}
-			let params = {}
-			params = {
+			const params = {
 				actPrice: amount,
 				payWay: this.payWay,
+				ghsId: this.id,
+				salt: this.salt
 			}
-			params.ghsId = this.id
-			params.salt = this.salt
+			uni.showLoading({ title: '跳转中...', mask: true })
 			rechargeFn(params).then(res => {
-				//错误返回判断
-				if(res.code == 0){
-					uni.hideLoading()
-					uni.showToast({
-						title: res.msg,
-						icon: 'none',
-						duration: 2000
-					})
-					return false
-				}			
-				// 隐藏加载提示
 				uni.hideLoading()
-				// 显示成功提示
-				uni.showToast({
-					title: '正在跳转支付...',
-					icon: 'success',
-					duration: 1500
-				})
-				// 延迟跳转到支付页面
+				if (res.code == 0) {
+					uni.showToast({ title: res.msg, icon: 'none', duration: 2000 })
+					return false
+				}
+				uni.showToast({ title: '正在跳转支付...', icon: 'success', duration: 1500 })
 				setTimeout(() => {
-					window.location.href = res.data.url;
-				}, 300)					
-			}).catch(err => {
-				// 隐藏加载提示
+					window.location.href = res.data.url
+				}, 300)
+			}).catch(() => {
 				uni.hideLoading()
-				// 显示错误提示
-				uni.showToast({
-					title: '请求失败,请重试',
-					icon: 'none',
-					duration: 2000
-				})
+				uni.showToast({ title: '请求失败,请重试', icon: 'none', duration: 2000 })
 			})
-
 		},
-
-		// 返回上一页
 		goBack() {
-			uni.navigateBack({
-				delta: 1
-			});
+			uni.navigateBack({ delta: 1 })
 		},
-
-		// 跳转到待结订单页面
 		goGathering() {
 			if (!this.id) {
-				uni.showToast({
-					title: '供货商信息加载中,请稍后再试',
-					icon: 'none'
-				});
-				return;
+				uni.showToast({ title: '供货商信息加载中,请稍后再试', icon: 'none' })
+				return
 			}
 			uni.navigateTo({
 				url: `/pagesPurchase/gathering?id=${this.id}&salt=${this.salt}`
-			});
+			})
 		},
-		/** 跳转余额变动明细(与小程序共用 /ghs-balance-change/list,带 salt 访客可查) */
+		/** 跳转余额变动明细(与小程序共用接口,salt 访客可查) */
 		goBalanceChange() {
 			if (!this.id) {
-				uni.showToast({
-					title: '供货商信息加载中,请稍后再试',
-					icon: 'none'
-				});
-				return;
+				uni.showToast({ title: '供货商信息加载中,请稍后再试', icon: 'none' })
+				return
 			}
 			uni.navigateTo({
 				url: `/admin/ghs/balanceChange?ghsId=${this.id}&salt=${this.salt}`
-			});
-		},
+			})
+		}
 	}
 }
 </script>
 
 <style lang="scss" scoped>
-.pay-container {
+.pay-page {
 	min-height: 100vh;
-	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-	position: relative;
+	background: #f5f5f5;
+	box-sizing: border-box;
+	padding-bottom: 560upx;
 }
 
-.nav-bar {
+/* 收款方:简洁头像 + 名称 */
+.pay-merchant {
 	display: flex;
+	flex-direction: row;
 	align-items: center;
-	justify-content: center; /* Changed to center the title */
-	padding: 20upx 30upx;
-	background: rgba(255, 255, 255, 0.1);
-	backdrop-filter: blur(10px);
-	
-	.nav-back {
-		width: 80upx;
-		height: 80upx;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		border-radius: 50%;
-		background: rgba(255, 255, 255, 0.2);
-		cursor: pointer;
-		transition: all 0.2s ease;
-		
-		&:active {
-			background: rgba(255, 255, 255, 0.3);
-			transform: scale(0.9);
-		}
-		
-		.iconfont {
-			font-size: 40upx;
-			color: #fff;
-			font-weight: bold;
-		}
-	}
-	
-	.nav-title {
-		color: #fff;
-		font-size: 36upx;
-		font-weight: 600;
-	}
-	
-	.nav-placeholder {
-		width: 80upx; /* Placeholder for back button */
-	}
+	justify-content: center;
+	padding: 56upx 40upx 28upx;
 }
 
-.amount-section {
-	padding: 60upx 40upx;
-	text-align: center;
-	
-	.amount-label {
-		color: rgba(255, 255, 255, 0.8);
-		font-size: 34upx;
-		margin-bottom: 20upx;
-	}
-	
-	.amount-display {
-		display: flex;
-		align-items: baseline;
-		justify-content: center;
-		margin-bottom: 20upx;
-		
-		.currency {
-			color: #fff;
-			font-size: 48upx;
-			font-weight: 600;
-			margin-right: 10upx;
-		}
-		
-		.amount {
-			color: #fff;
-			font-size: 80upx;
-			font-weight: 700;
-			font-family: 'Arial', sans-serif;
-		}
-	}
-	
-	.clear-amount-btn {
-		color: rgb(226, 219, 219);
-		font-size: 22upx;
-		margin-top: 20upx;
-		background: transparent;
-		border: 1upx solid rgb(226, 219, 219);
-		border-radius: 12upx;
-		padding: 6upx 12upx;
-		transition: all 0.3s ease;
-		cursor: pointer;
-		width: auto;
-		display: inline-block;
-	}
+.pay-merchant__avatar {
+	width: 72upx;
+	height: 72upx;
+	border-radius: 16upx;
+	background: #1677ff;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	flex-shrink: 0;
 }
 
-.customer-info-card {
-	background: #fff; /* Changed to white */
-	margin: 0 30upx 20upx;
-	border-radius: 20upx;
-	padding: 30upx;
-	box-shadow: 0 8upx 30upx rgba(0, 0, 0, 0.08);
-	position: relative;
-	overflow: hidden;
-	
-	&::before {
-		content: '';
-		position: absolute;
-		top: 0;
-		left: 0;
-		right: 0;
-		height: 8upx;
-		background: #fff; /* Changed to white */
-		box-shadow: 0 2upx 8upx rgba(0, 0, 0, 0.1);
-	}
-	
-	.card-header {
-		display: flex;
-		align-items: center;
-		margin-bottom: 20upx;
-		margin-top: 8upx;
-		
-		.customer-avatar {
-			width: 70upx;
-			height: 70upx;
-			border-radius: 50%;
-			background: linear-gradient(135deg, #1677ff 0%, #4096ff 100%);
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			margin-right: 25upx;
-			box-shadow: 0 6upx 20upx rgba(22, 119, 255, 0.3);
-			position: relative;
-			
-			&::after {
-				content: '';
-				position: absolute;
-				top: -2upx;
-				left: -2upx;
-				right: -2upx;
-				bottom: -2upx;
-				border-radius: 50%;
-				background: linear-gradient(135deg, #1677ff 0%, #4096ff 100%);
-				z-index: -1;
-				opacity: 0.3;
-			}
-			
-			.avatar-text {
-				color: #fff;
-				font-size: 36upx;
-				font-weight: 600;
-			}
-		}
-		
-		.customer-details {
-			flex: 1;
-			min-width: 0;
-			display: flex;
-			flex-direction: column;
-			justify-content: center;
-			
-			.customer-name {
-				display: block;
-				font-size: 34upx;
-				font-weight: 600;
-				color: #333;
-				line-height: 44upx;
-			}
-		}
-	}
+.pay-merchant__avatar-text {
+	color: #fff;
+	font-size: 34upx;
+	font-weight: 600;
+	line-height: 1;
+}
 
-	/* 明细入口:等宽描边按钮,与待结金额纵向分层;单按钮时半宽 */
-	.pay-entry-row {
-		display: flex;
-		flex-direction: row;
-		align-items: stretch;
-		margin-top: 24upx;
-	}
+.pay-merchant__meta {
+	margin-left: 20upx;
+	display: flex;
+	flex-direction: column;
+	min-width: 0;
+}
 
-	.pay-entry-row--single {
-		width: 50%;
-	}
+.pay-merchant__label {
+	font-size: 24upx;
+	color: #999;
+	line-height: 32upx;
+}
 
-	.pay-entry-btn {
-		flex: 1;
-		height: 72upx;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		box-sizing: border-box;
-		border: 1upx solid #d0e3ff;
-		background-color: #f5f9ff;
-		border-radius: 12upx;
-		margin-left: 16upx;
-
-		&:first-child {
-			margin-left: 0;
-		}
-	}
+.pay-merchant__name {
+	margin-top: 4upx;
+	font-size: 32upx;
+	font-weight: 600;
+	color: #222;
+	line-height: 44upx;
+}
 
-	.pay-entry-btn--debt {
-		border-color: #ffd0d0;
-		background-color: #fff5f5;
-	}
+/* 金额白卡 */
+.pay-amount-card {
+	margin: 0 24upx;
+	padding: 36upx 32upx 28upx;
+	background: #fff;
+	border-radius: 16upx;
+	box-sizing: border-box;
+}
 
-	.pay-entry-btn--debt .pay-entry-btn__text {
-		color: #ff5252;
-	}
+.pay-amount-card__head {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	justify-content: space-between;
+}
 
-	.pay-entry-btn--disabled {
-		opacity: 0.5;
-	}
+.pay-amount-card__title {
+	font-size: 28upx;
+	color: #666;
+	line-height: 40upx;
+}
+
+.pay-amount-card__clear {
+	font-size: 26upx;
+	color: #1677ff;
+	line-height: 40upx;
+	padding: 0 8upx;
+}
+
+.pay-amount-row {
+	display: flex;
+	flex-direction: row;
+	align-items: flex-end;
+	margin-top: 28upx;
+	min-height: 96upx;
+}
+
+.pay-amount-row__currency {
+	font-size: 48upx;
+	font-weight: 600;
+	color: #222;
+	line-height: 1;
+	margin-right: 12upx;
+	padding-bottom: 10upx;
+}
 
-	.pay-entry-btn__text {
-		font-size: 26upx;
-		color: #3385ff;
-		line-height: 36upx;
+.pay-amount-row__value {
+	font-size: 80upx;
+	font-weight: 600;
+	color: #222;
+	line-height: 1;
+	font-family: 'DIN Alternate', 'Helvetica Neue', Arial, sans-serif;
+	word-break: break-all;
+}
+
+.pay-amount-row__value--placeholder {
+	color: #ccc;
+}
+
+/* 仿输入光标闪烁 */
+.pay-amount-row__cursor {
+	width: 4upx;
+	height: 64upx;
+	margin-left: 8upx;
+	margin-bottom: 8upx;
+	background: #1677ff;
+	animation: pay-cursor-blink 1s steps(1) infinite;
+}
+
+@keyframes pay-cursor-blink {
+	0%,
+	50% {
+		opacity: 1;
 	}
-	
-	.debt-info {
-		background: linear-gradient(135deg, #fff5f5 0%, #fef2f2 100%);
-		border-radius: 15upx;
-		padding: 20upx 25upx;
-		margin-top: 20upx;
-		border: 1upx solid rgba(255, 107, 107, 0.2);
-		position: relative;
-		
-		&::before {
-			content: '';
-			position: absolute;
-			top: 0;
-			left: 0;
-			right: 0;
-			bottom: 0;
-			background: linear-gradient(135deg, rgba(255, 107, 107, 0.05) 0%, rgba(255, 107, 107, 0.02) 100%);
-			border-radius: 15upx;
-		}
-		
-		.debt-amount {
-			display: flex;
-			align-items: baseline;
-			justify-content: space-between;
-			margin-bottom: 10upx;
-			position: relative;
-			z-index: 1;
-			
-			.debt-label {
-				font-size: 28upx;
-				color: #666;
-				font-weight: 500;
-			}
-			
-			.debt-value {
-				font-size: 40upx;
-				font-weight: 700;
-				color: #ff6b6b;
-				font-family: 'Arial', sans-serif;
-				text-shadow: 0 2upx 10upx rgba(255, 107, 107, 0.2);
-			}
-		}
-		
-		.debt-tip {
-			font-size: 22upx;
-			color: #999;
-			text-align: right;
-			position: relative;
-			z-index: 1;
-			font-style: italic;
-		}
+	51%,
+	100% {
+		opacity: 0;
 	}
 }
 
-.keyboard-section {
-	position: fixed;
-	bottom: 160upx;
-	left: 0;
-	right: 0;
-	background: rgba(255, 255, 255, 0.98);
-	backdrop-filter: blur(20px);
-	padding: 30upx;
-	border-top: 1upx solid rgba(0, 0, 0, 0.05);
-	
-	.keyboard {
-		.keyboard-row {
-			display: flex;
-			margin-bottom: 20upx;
-			
-			&:last-child {
-				margin-bottom: 0;
-			}
-			
-			.key-item {
-				flex: 1;
-				height: 120upx;
-				margin: 0 10upx;
-				border-radius: 20upx;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				font-size: 40upx;
-				font-weight: 600;
-				transition: all 0.15s ease;
-				user-select: none;
-				-webkit-user-select: none;
-				cursor: pointer;
-				will-change: transform;
-				position: relative;
-				overflow: hidden;
-				
-				&::before {
-					content: '';
-					position: absolute;
-					top: 0;
-					left: 0;
-					right: 0;
-					bottom: 0;
-					background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
-					opacity: 0;
-					transition: opacity 0.15s ease;
-				}
-				
-				&:active::before {
-					opacity: 1;
-				}
-				
-				&.key-number {
-					background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
-					color: #333;
-					box-shadow: 0 4upx 20upx rgba(0, 0, 0, 0.08);
-					border: 1upx solid rgba(0, 0, 0, 0.05);
-				}
-				
-				&.key-delete {
-					background: linear-gradient(135deg, #ff6b6b 0%, #ff5252 100%);
-					color: #fff;
-					box-shadow: 0 4upx 20upx rgba(255, 107, 107, 0.3);
-				}
-				
-				&.key-dot {
-					background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
-					color: #333;
-					box-shadow: 0 4upx 20upx rgba(0, 0, 0, 0.08);
-					border: 1upx solid rgba(0, 0, 0, 0.05);
-				}
-				
-				&.key-confirm {
-					background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-					color: #fff;
-					box-shadow: 0 4upx 20upx rgba(102, 126, 234, 0.3);
-				}
-			}
-		}
-	}
+.pay-debt-tip {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	margin-top: 28upx;
+	padding: 18upx 20upx;
+	background: #fff7f0;
+	border-radius: 12upx;
+	box-sizing: border-box;
+}
+
+.pay-debt-tip__label {
+	font-size: 24upx;
+	color: #999;
+	line-height: 34upx;
+}
+
+.pay-debt-tip__value {
+	margin-left: 12upx;
+	flex: 1;
+	font-size: 28upx;
+	font-weight: 600;
+	color: #ff6a00;
+	line-height: 34upx;
+}
+
+.pay-debt-tip__action {
+	font-size: 24upx;
+	color: #1677ff;
+	line-height: 34upx;
+}
+
+.pay-links {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	flex-wrap: wrap;
+	margin-top: 28upx;
 }
 
-.pay-button-section {
+.pay-link {
+	font-size: 26upx;
+	color: #1677ff;
+	line-height: 36upx;
+}
+
+.pay-link--debt {
+	color: #ff6a00;
+}
+
+.pay-link--disabled {
+	opacity: 0.45;
+}
+
+.pay-link__dot {
+	margin-left: 16upx;
+	margin-right: 16upx;
+	font-size: 24upx;
+	color: #ddd;
+	line-height: 36upx;
+}
+
+.pay-payer {
+	padding: 20upx 40upx 0;
+}
+
+.pay-payer__text {
+	font-size: 30upx;
+	color: #999;
+	line-height: 34upx;
+}
+
+/* 底部键盘:左 3×4 数字区 + 右通栏付款 */
+.pay-keyboard-wrap {
 	position: fixed;
-	bottom: 0;
 	left: 0;
 	right: 0;
-	padding: 30upx;
-	background: rgba(255, 255, 255, 0.98);
-	backdrop-filter: blur(20px);
-	border-top: 1upx solid rgba(0, 0, 0, 0.05);
-	
-	.pay-button {
-		width: 100%;
-		height: 100upx;
-		background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-		color: #fff;
-		font-size: 36upx;
-		font-weight: 600;
-		border-radius: 50upx;
-		border: none;
-		transition: all 0.3s ease;
-		position: relative;
-		overflow: hidden;
-		
-		&::before {
-			content: '';
-			position: absolute;
-			top: 0;
-			left: 0;
-			right: 0;
-			bottom: 0;
-			background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
-			opacity: 0;
-			transition: opacity 0.3s ease;
-		}
-		
-		&:active::before {
-			opacity: 1;
-		}
-		
-		&.disabled {
-			background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
-			color: #adb5bd;
-			box-shadow: none;
-		}
-		
-		&:not(.disabled):active {
-			transform: scale(0.98);
-		}
-		
-		.button-text {
-			position: absolute;
-			left: 50%;
-			transform: translateX(-50%);
-			font-size: 36upx;
-			font-weight: 600;
-			color: #fff;
-		}
-		
-		.button-amount {
-			position: absolute;
-			right: 30upx;
-			font-size: 36upx;
-			font-weight: 700;
-			color: #fff;
-			font-family: 'Arial', sans-serif;
-		}
-	}
+	bottom: 0;
+	background: #d1d3d9;
+	z-index: 20;
+	box-sizing: border-box;
 }
 
+.pay-keyboard {
+	display: flex;
+	flex-direction: row;
+	align-items: stretch;
+	padding: 12upx;
+	box-sizing: border-box;
+}
 
+.pay-keyboard__keys {
+	flex: 3;
+	display: flex;
+	flex-direction: row;
+	flex-wrap: wrap;
+}
 
+.pay-key {
+	width: 33.333%;
+	height: 108upx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+	padding: 6upx;
+}
+
+.pay-key__inner {
+	width: 100%;
+	height: 100%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	background: #fff;
+	border-radius: 12upx;
+	box-shadow: 0 2upx 0 #b8bbc3;
+}
+
+.pay-key:active .pay-key__inner {
+	background: #e8e8e8;
+}
+
+.pay-key__num {
+	font-size: 44upx;
+	font-weight: 500;
+	color: #222;
+	line-height: 1;
+}
+
+.pay-key__del {
+	font-size: 40upx;
+	color: #333;
+	line-height: 1;
+}
+
+.pay-key-pay {
+	flex: 1;
+	margin: 6upx;
+	margin-left: 4upx;
+	border-radius: 12upx;
+	background: #1677ff;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+}
+
+.pay-key-pay--disabled {
+	background: #a0c4ff;
+}
+
+.pay-key-pay:not(.pay-key-pay--disabled):active {
+	background: #0958d9;
+}
+
+.pay-key-pay__text {
+	color: #fff;
+	font-size: 36upx;
+	font-weight: 600;
+	letter-spacing: 4upx;
+}
+
+.pay-safe-area {
+	height: env(safe-area-inset-bottom);
+	background: #d1d3d9;
+}
 </style>

+ 3 - 3
mallh5/unpackage/dist/cache/.vite/deps/_metadata.json

@@ -1,8 +1,8 @@
 {
-  "hash": "964a26c4",
-  "configHash": "732862a2",
+  "hash": "bd818bf7",
+  "configHash": "0397d4ff",
   "lockfileHash": "e3b0c442",
-  "browserHash": "9fe8f204",
+  "browserHash": "af9be4c9",
   "optimized": {},
   "chunks": {}
 }