修正了 pages 名为拼音的问题
This commit is contained in:
547
pages/submit/submit.js
Normal file
547
pages/submit/submit.js
Normal file
@@ -0,0 +1,547 @@
|
||||
// pages/submit/submit.js
|
||||
const app = getApp()
|
||||
import request from '../../utils/request.js'
|
||||
// 引入弹窗服务(路径请根据项目实际调整)
|
||||
import PopupService from '../../services/popupService.js'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
// 全局变量
|
||||
ossImageUrl: '',
|
||||
apiBaseUrl: '',
|
||||
|
||||
// 从商品详情页传入的数据
|
||||
shangpinData: null,
|
||||
shangpinId: '',
|
||||
|
||||
// 表单数据
|
||||
nicheng: '', // 游戏昵称/ID
|
||||
beizhu: '', // 备注信息
|
||||
zhiding: '', // 指定打手ID(新增)
|
||||
jine: 0, // 总金额
|
||||
|
||||
// 页面状态
|
||||
isSubmitting: false,
|
||||
canSubmit: false,
|
||||
isPaying: false,
|
||||
|
||||
// 支付相关
|
||||
orderId: '',
|
||||
payParams: null,
|
||||
checkCount: 0,
|
||||
maxCheckCount: 3
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
// 获取全局变量
|
||||
this.setData({
|
||||
ossImageUrl: app.globalData.ossImageUrl || '',
|
||||
apiBaseUrl: app.globalData.apiBaseUrl || ''
|
||||
})
|
||||
|
||||
// 设置页面标题
|
||||
wx.setNavigationBarTitle({
|
||||
title: '提交订单'
|
||||
})
|
||||
|
||||
// 解析传递的商品数据
|
||||
try {
|
||||
if (options.data) {
|
||||
const shangpinData = JSON.parse(decodeURIComponent(options.data))
|
||||
|
||||
// 处理图片URL(拼接完整路径)
|
||||
if (shangpinData.image && !shangpinData.image.startsWith('http')) {
|
||||
shangpinData.image = this.data.ossImageUrl + shangpinData.image
|
||||
}
|
||||
|
||||
// 处理价格显示
|
||||
if (shangpinData.price) {
|
||||
const price = parseFloat(shangpinData.price) || 0
|
||||
const priceInteger = Math.floor(price)
|
||||
let priceDecimal = '00'
|
||||
|
||||
const decimalPart = (price - priceInteger).toFixed(2)
|
||||
if (decimalPart > 0) {
|
||||
priceDecimal = decimalPart.toString().split('.')[1]
|
||||
}
|
||||
|
||||
shangpinData.priceInteger = priceInteger
|
||||
shangpinData.priceDecimal = priceDecimal
|
||||
}
|
||||
|
||||
// 设置商品数据
|
||||
this.setData({
|
||||
shangpinData: shangpinData,
|
||||
shangpinId: shangpinData.id || '',
|
||||
jine: parseFloat(shangpinData.price) || 0,
|
||||
})
|
||||
} else {
|
||||
this.handleDataError('商品数据不完整')
|
||||
}
|
||||
} catch (error) {
|
||||
this.handleDataError('解析商品数据失败')
|
||||
}
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 原有代码:注册通知组件
|
||||
this.registerNotificationComponent();
|
||||
|
||||
// 🆕 进入页面时触发弹窗检查(PopupService 会自动判断是否展示)
|
||||
PopupService.checkAndShow(this, 'tijiao');
|
||||
},
|
||||
|
||||
// pages/submit/submit.js 中添加 onHide 方法(如果已有则合并内容)
|
||||
onHide() {
|
||||
const popupComp = this.selectComponent('#popupNotice');
|
||||
if (popupComp && popupComp.cleanup) {
|
||||
popupComp.cleanup();
|
||||
}
|
||||
},
|
||||
|
||||
// 新增:注册通知组件
|
||||
registerNotificationComponent() {
|
||||
const app = getApp();
|
||||
const notificationComp = this.selectComponent('#global-notification');
|
||||
|
||||
if (notificationComp && notificationComp.showNotification) {
|
||||
//console.log('🏪 商城页面注册通知组件');
|
||||
app.globalData.globalNotification = {
|
||||
show: (data) => notificationComp.showNotification(data),
|
||||
hide: () => notificationComp.hideNotification()
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理数据错误
|
||||
*/
|
||||
handleDataError(errorMsg) {
|
||||
wx.showToast({
|
||||
title: errorMsg || '数据错误',
|
||||
icon: 'none'
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
wx.navigateBack()
|
||||
}, 1500)
|
||||
},
|
||||
|
||||
/**
|
||||
* 游戏昵称输入事件
|
||||
*/
|
||||
onNicknameInput(e) {
|
||||
const value = e.detail.value.trim()
|
||||
this.setData({
|
||||
nicheng: value
|
||||
}, () => {
|
||||
this.checkFormValid()
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 备注信息输入事件
|
||||
*/
|
||||
onRemarkInput(e) {
|
||||
const value = e.detail.value.trim()
|
||||
this.setData({
|
||||
beizhu: value
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 指定打手ID输入事件
|
||||
*/
|
||||
onZhidingInput(e) {
|
||||
const value = e.detail.value.trim()
|
||||
this.setData({
|
||||
zhiding: value
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查表单是否有效
|
||||
*/
|
||||
checkFormValid() {
|
||||
const { nicheng } = this.data
|
||||
|
||||
const isValid = nicheng && nicheng.length > 0 && nicheng.length <= 15
|
||||
|
||||
this.setData({
|
||||
canSubmit: isValid
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交订单
|
||||
*/
|
||||
onSubmitOrder() {
|
||||
const { nicheng, beizhu, zhiding, jine, shangpinId, canSubmit, isSubmitting } = this.data
|
||||
|
||||
// 验证表单
|
||||
if (!canSubmit) {
|
||||
wx.showToast({
|
||||
title: '请填写游戏昵称',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 防止重复提交
|
||||
if (isSubmitting) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setData({
|
||||
isSubmitting: true,
|
||||
isPaying: false
|
||||
})
|
||||
|
||||
// 显示loading(超时设为10秒)
|
||||
wx.showLoading({
|
||||
title: '创建订单中...',
|
||||
mask: true
|
||||
})
|
||||
|
||||
const timeoutTimer = setTimeout(() => {
|
||||
wx.hideLoading()
|
||||
wx.showToast({
|
||||
title: '网络超时,请检查您是否已登录',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
}, 10000)
|
||||
|
||||
// 构建请求数据(添加zhiding字段)
|
||||
const orderData = {
|
||||
shangpin_id: shangpinId, // 商品ID
|
||||
nicheng: nicheng, // 游戏昵称
|
||||
beizhu: beizhu || '', // 备注(可为空)
|
||||
zhiding: zhiding || '', // 指定打手ID(可为空)
|
||||
jine: jine // 金额
|
||||
}
|
||||
|
||||
// 调用后端创建订单接口
|
||||
request({
|
||||
url: '/dingdan/xiadan',
|
||||
method: 'POST',
|
||||
data: orderData
|
||||
})
|
||||
.then(res => {
|
||||
clearTimeout(timeoutTimer)
|
||||
wx.hideLoading()
|
||||
|
||||
if (res.statusCode === 200 && res.data) {
|
||||
const response = res.data
|
||||
|
||||
if (response.code === 0 && response.data) {
|
||||
// 保存订单ID和支付参数
|
||||
const orderId = response.data.dingdanid
|
||||
const payParams = response.data.payParams || {}
|
||||
|
||||
this.setData({
|
||||
orderId: orderId,
|
||||
payParams: payParams,
|
||||
isSubmitting: false,
|
||||
isPaying: true,
|
||||
checkCount: 0
|
||||
})
|
||||
|
||||
// 调起微信支付
|
||||
this.triggerWxPayment(payParams)
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: response.msg || '创建订单失败',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '网络错误,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
clearTimeout(timeoutTimer)
|
||||
wx.hideLoading()
|
||||
wx.showToast({
|
||||
title: '创建订单失败',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 调起微信支付
|
||||
*/
|
||||
triggerWxPayment(payParams) {
|
||||
// 验证支付参数是否完整
|
||||
if (!payParams || !payParams.timeStamp || !payParams.nonceStr ||
|
||||
!payParams.package || !payParams.signType || !payParams.paySign) {
|
||||
wx.showToast({
|
||||
title: '支付参数不完整',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
wx.requestPayment({
|
||||
timeStamp: payParams.timeStamp,
|
||||
nonceStr: payParams.nonceStr,
|
||||
package: payParams.package,
|
||||
signType: payParams.signType,
|
||||
paySign: payParams.paySign,
|
||||
|
||||
success: (res) => {
|
||||
// 支付成功,开始双重确认
|
||||
this.onPaymentSuccess()
|
||||
},
|
||||
|
||||
fail: (err) => {
|
||||
// 根据错误类型处理
|
||||
if (err.errMsg === 'requestPayment:fail cancel') {
|
||||
// 用户取消支付
|
||||
this.handleUserCancel()
|
||||
} else {
|
||||
// 其他支付错误
|
||||
this.handlePaymentFail(err)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理用户取消支付
|
||||
*/
|
||||
handleUserCancel() {
|
||||
const { orderId } = this.data
|
||||
|
||||
wx.showToast({
|
||||
title: '已取消支付',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
})
|
||||
|
||||
// 通知后端用户取消(静默请求,不阻塞用户)
|
||||
if (orderId) {
|
||||
request({
|
||||
url: '/dingdan/shibai',
|
||||
method: 'POST',
|
||||
data: {
|
||||
dingdanid: orderId,
|
||||
yuanyin: 'user_cancel'
|
||||
}
|
||||
}).catch(() => {
|
||||
// 静默失败
|
||||
})
|
||||
}
|
||||
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理支付失败
|
||||
*/
|
||||
handlePaymentFail(err) {
|
||||
const { orderId } = this.data
|
||||
|
||||
wx.showToast({
|
||||
title: '支付失败',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
})
|
||||
|
||||
// 通知后端支付失败(简化流程,直接请求,不显示loading)
|
||||
if (orderId) {
|
||||
request({
|
||||
url: '/dingdan/shibai',
|
||||
method: 'POST',
|
||||
data: {
|
||||
dingdanid: orderId,
|
||||
yuanyin: 'payment_fail',
|
||||
cuowu: err.errMsg || ''
|
||||
}
|
||||
}).catch(() => {
|
||||
// 静默失败
|
||||
}).finally(() => {
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 支付成功处理(双重确认)
|
||||
*/
|
||||
onPaymentSuccess() {
|
||||
const { orderId } = this.data
|
||||
|
||||
if (!orderId) {
|
||||
wx.showToast({
|
||||
title: '订单ID不存在',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 显示支付成功提示(时间缩短)
|
||||
wx.showToast({
|
||||
title: '支付成功,确认中...',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
})
|
||||
|
||||
// 开始双重确认流程
|
||||
this.checkOrderStatus()
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查订单状态(双重确认)
|
||||
*/
|
||||
checkOrderStatus() {
|
||||
const { orderId, checkCount, maxCheckCount } = this.data
|
||||
|
||||
// 显示加载(时间缩短)
|
||||
wx.showLoading({
|
||||
title: `确认支付状态${checkCount > 0 ? `(${checkCount + 1})` : ''}`,
|
||||
mask: true
|
||||
})
|
||||
|
||||
// 超时设为5秒
|
||||
const timeoutTimer = setTimeout(() => {
|
||||
wx.hideLoading()
|
||||
this.handleConfirmError('网络超时')
|
||||
}, 5000)
|
||||
|
||||
// 向后端发起支付复查请求
|
||||
request({
|
||||
url: '/dingdan/fucha',
|
||||
method: 'POST',
|
||||
data: {
|
||||
dingdanid: orderId
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
clearTimeout(timeoutTimer)
|
||||
wx.hideLoading()
|
||||
|
||||
if (res.statusCode === 200 && res.data) {
|
||||
const response = res.data
|
||||
|
||||
if (response.code === 0) {
|
||||
// 确认成功,订单状态已更新
|
||||
this.handleConfirmSuccess()
|
||||
} else {
|
||||
// 后端返回错误
|
||||
this.handleConfirmError(response.msg || '订单状态异常')
|
||||
}
|
||||
} else {
|
||||
// 网络错误
|
||||
this.handleConfirmError('网络错误')
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
clearTimeout(timeoutTimer)
|
||||
wx.hideLoading()
|
||||
this.handleConfirmError('检查失败')
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理确认成功
|
||||
*/
|
||||
handleConfirmSuccess() {
|
||||
// 显示最终成功提示
|
||||
wx.showToast({
|
||||
title: '购买成功!',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
|
||||
// 1.5秒后跳转到首页
|
||||
setTimeout(() => {
|
||||
wx.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}, 1500)
|
||||
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理确认错误
|
||||
*/
|
||||
handleConfirmError(errorMsg) {
|
||||
const { checkCount, maxCheckCount } = this.data
|
||||
const newCheckCount = checkCount + 1
|
||||
|
||||
if (newCheckCount < maxCheckCount) {
|
||||
// 还可以重试
|
||||
this.setData({
|
||||
checkCount: newCheckCount
|
||||
})
|
||||
|
||||
// 1秒后重试
|
||||
setTimeout(() => {
|
||||
this.checkOrderStatus()
|
||||
}, 1000)
|
||||
} else {
|
||||
// 达到最大重试次数
|
||||
wx.showModal({
|
||||
title: '支付确认中',
|
||||
content: '支付已成功,但订单状态确认异常。请稍后在订单列表中查看状态,如有问题请联系客服。',
|
||||
showCancel: false,
|
||||
confirmText: '我知道了',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.setData({
|
||||
isSubmitting: false,
|
||||
isPaying: false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
5
pages/submit/submit.json
Normal file
5
pages/submit/submit.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"global-notification": "/components/global-notification/global-notification"
|
||||
}
|
||||
}
|
||||
124
pages/submit/submit.wxml
Normal file
124
pages/submit/submit.wxml
Normal file
@@ -0,0 +1,124 @@
|
||||
<!--pages/submit/submit.wxml-->
|
||||
<view class="submit-page">
|
||||
<!-- 商品信息区域 -->
|
||||
<view class="product-section">
|
||||
<view class="product-card">
|
||||
<!-- 商品图片 -->
|
||||
<view class="product-image-box">
|
||||
<image
|
||||
src="{{shangpinData && shangpinData.image ? shangpinData.image : ''}}"
|
||||
mode="aspectFill"
|
||||
class="product-image"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="product-info">
|
||||
<view class="product-title">
|
||||
<text class="title-text">{{shangpinData && shangpinData.title ? shangpinData.title : '商品标题'}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 价格信息 -->
|
||||
<view class="price-info">
|
||||
<text class="price-label">价格:</text>
|
||||
<view class="price-value">
|
||||
<text class="price-icon">¥</text>
|
||||
<text class="price-integer">{{shangpinData && shangpinData.priceInteger ? shangpinData.priceInteger : '0'}}</text>
|
||||
<text class="price-decimal">.{{shangpinData && shangpinData.priceDecimal ? shangpinData.priceDecimal : '00'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 表单区域(左右布局) -->
|
||||
<view class="form-section">
|
||||
<view class="form-card">
|
||||
<!-- 游戏昵称 - 左右布局 -->
|
||||
<view class="form-item-row">
|
||||
<view class="item-label-row">
|
||||
<text class="label-text-bold">昵称</text>
|
||||
<text class="label-required">*</text>
|
||||
</view>
|
||||
<input
|
||||
class="item-input-row"
|
||||
type="text"
|
||||
placeholder="请输入您的昵称"
|
||||
placeholder-class="input-placeholder-gray"
|
||||
maxlength="15"
|
||||
value="{{nicheng}}"
|
||||
bindinput="onNicknameInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 备注信息 - 左右布局 -->
|
||||
<view class="form-item-row">
|
||||
<view class="item-label-row">
|
||||
<text class="label-text-bold">备注</text>
|
||||
</view>
|
||||
<input
|
||||
class="item-input-row"
|
||||
type="text"
|
||||
placeholder="请补充您要补充的其他联系信息"
|
||||
placeholder-class="input-placeholder-gray"
|
||||
maxlength="30"
|
||||
value="{{beizhu}}"
|
||||
bindinput="onRemarkInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 指定打手ID - 左右布局 -->
|
||||
<view class="form-item-row">
|
||||
<view class="item-label-row">
|
||||
<text class="label-text-bold">指定服务者ID(选填)</text>
|
||||
</view>
|
||||
<input
|
||||
class="item-input-row"
|
||||
type="text"
|
||||
placeholder="填写您需要指定的服务者"
|
||||
placeholder-class="input-placeholder-gray"
|
||||
maxlength="20"
|
||||
value="{{zhiding}}"
|
||||
bindinput="onZhidingInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<view class="payment-item">
|
||||
<view class="payment-method">
|
||||
<image src="/images/weixinzhifu.png" class="payment-icon" />
|
||||
<text class="payment-text">微信支付</text>
|
||||
<view class="payment-checkbox">
|
||||
<text class="checkbox-text">✓</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="footer-section">
|
||||
<view class="total-price">
|
||||
<text class="total-label">总价:</text>
|
||||
<view class="total-value">
|
||||
<text class="price-icon">¥</text>
|
||||
<text class="price-integer">{{shangpinData && shangpinData.priceInteger ? shangpinData.priceInteger : '0'}}</text>
|
||||
<text class="price-decimal">.{{shangpinData && shangpinData.priceDecimal ? shangpinData.priceDecimal : '00'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="submit-btn {{canSubmit && !isSubmitting ? 'submit-btn-active' : 'submit-btn-disabled'}}"
|
||||
bindtap="onSubmitOrder"
|
||||
>
|
||||
<text class="btn-text">{{isSubmitting ? '提交中...' : '提交订单'}}</text>
|
||||
<view class="btn-glow"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 全局通知组件 -->
|
||||
<global-notification id="global-notification" />
|
||||
|
||||
<!-- 弹窗公告组件(供 PopupService 调用) -->
|
||||
<popup-notice id="popupNotice" />
|
||||
</view>
|
||||
280
pages/submit/submit.wxss
Normal file
280
pages/submit/submit.wxss
Normal file
@@ -0,0 +1,280 @@
|
||||
/* pages/submit/submit.wxss */
|
||||
|
||||
.submit-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #f8f9ff 0%, #f0f3ff 100%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 商品信息区域 */
|
||||
.product-section {
|
||||
padding: 30rpx 30rpx 20rpx 30rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.product-image-box {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
background: #f5f5f5;
|
||||
flex-shrink: 0;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 160rpx;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.price-info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.price-value {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price-icon {
|
||||
font-size: 28rpx;
|
||||
color: #ff4d4f;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.price-integer {
|
||||
font-size: 38rpx;
|
||||
color: #ff4d4f;
|
||||
font-weight: 700;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
|
||||
.price-decimal {
|
||||
font-size: 28rpx;
|
||||
color: #ff4d4f;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 表单区域 */
|
||||
.form-section {
|
||||
padding: 0 30rpx 20rpx 30rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.form-item-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 25rpx 0;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.form-item-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-label-row {
|
||||
width: 220rpx;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label-text-bold {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.label-required {
|
||||
font-size: 30rpx;
|
||||
color: #ff4d4f;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.item-input-row {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #222;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
padding: 0 20rpx;
|
||||
text-align: right;
|
||||
background: #fafafa;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.input-placeholder-gray {
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 支付方式 */
|
||||
.payment-item {
|
||||
margin-top: 30rpx;
|
||||
padding-top: 30rpx;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.payment-method {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.payment-icon {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.payment-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.payment-checkbox {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
background: #52c41a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.checkbox-text {
|
||||
color: white;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.footer-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 30rpx;
|
||||
background: white;
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
margin-top: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.total-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.total-label {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.total-value {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 240rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.submit-btn-active {
|
||||
background: linear-gradient(135deg, #52c41a, #389e0d);
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
|
||||
.submit-btn-disabled {
|
||||
background: #ccc;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.submit-btn-active:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: 0 4rpx 20rpx rgba(255, 77, 79, 0.5);
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.btn-glow {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transform: translateX(-100%);
|
||||
animation: btnGlow 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes btnGlow {
|
||||
0% { transform: translateX(-100%); }
|
||||
50% { transform: translateX(100%); }
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
Reference in New Issue
Block a user