更新:课程确认订单和订单支付功能初步完成
This commit is contained in:
@@ -4,7 +4,11 @@ import type { IApiResponse } from '@/api/types'
|
||||
import type {
|
||||
ICreateOrderParams,
|
||||
IGooglePayVerifyParams,
|
||||
ICreateOrderResponse
|
||||
ICreateOrderResponse,
|
||||
IOrderGoods,
|
||||
ICoupon,
|
||||
ICourseOrderCreateParams,
|
||||
IOrderInitData
|
||||
} from '@/types/order'
|
||||
import type { IUserInfo } from '@/types/user'
|
||||
|
||||
@@ -59,5 +63,96 @@ export const orderApi = {
|
||||
method: 'POST'
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化订单准备数据
|
||||
* @param params 初始化参数
|
||||
*/
|
||||
async initPrepareOrder(params: { uid: number; productList: Array<{ productId: number; quantity: number }> }) {
|
||||
const res = await mainClient.request<IApiResponse<IOrderInitData>>({
|
||||
url: 'common/buyOrder/initPrepareOrder',
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据商品ID获取商品详情列表
|
||||
* @param productIds 商品ID字符串(逗号分隔)
|
||||
*/
|
||||
async getShopProductListByIds(productIds: string) {
|
||||
const res = await mainClient.request<IApiResponse<{ shopProductList: IOrderGoods[] }>>({
|
||||
url: 'book/buyOrder/getShopProductListByIds',
|
||||
method: 'POST',
|
||||
data: { productIds }
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取VIP优惠金额
|
||||
* @param productList 商品列表
|
||||
*/
|
||||
async getVipDiscountAmount(productList: Array<{ productId: number; quantity: number }>) {
|
||||
const res = await mainClient.request<IApiResponse<{ discountAmount: number }>>({
|
||||
url: 'book/buyOrder/getVipDiscountAmount',
|
||||
method: 'POST',
|
||||
data: { productList }
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取地区优惠金额
|
||||
* @param productList 商品列表
|
||||
*/
|
||||
async getDistrictAmount(productList: Array<{ productId: number; quantity: number }>) {
|
||||
const res = await mainClient.request<IApiResponse<{ districtAmount: number }>>({
|
||||
url: 'book/buyOrder/getDistrictAmount',
|
||||
method: 'POST',
|
||||
data: { productList }
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取可用优惠券列表
|
||||
* @param shopProductInfos 商品信息字符串(格式:productId:price:quantity,productId:price:quantity)
|
||||
*/
|
||||
async getCouponListPayment(shopProductInfos: string) {
|
||||
const res = await mainClient.request<IApiResponse<{ couponHistoryList: ICoupon[] }>>({
|
||||
url: 'common/coupon/getCouponListPayment',
|
||||
method: 'POST',
|
||||
data: { shopProductInfos }
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新购物车商品
|
||||
* @param data 商品数据
|
||||
*/
|
||||
async updateCart(data: { productId: number; productAmount: number; price: number }) {
|
||||
const res = await mainClient.request<IApiResponse>({
|
||||
url: 'book/ordercart/update',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
return res
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建课程订单
|
||||
* @param data 订单数据
|
||||
*/
|
||||
async placeCourseOrder(data: ICourseOrderCreateParams) {
|
||||
const res = await mainClient.request<IApiResponse<{ orderSn: string; money: number }>>({
|
||||
url: 'book/buyOrder/placeOrder',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ export async function getVipInfo() {
|
||||
* @param current 当前页码
|
||||
* @param limit 每页数量
|
||||
*/
|
||||
export async function getOrderList(current: number, limit: number, orderStatus: string) {
|
||||
export async function getOrderList(page: number, limit: number, orderStatus: string) {
|
||||
const res = await mainClient.request<IApiResponse<{ orders: IPageData<IOrder> }>>({
|
||||
url: 'common/buyOrder/commonBuyOrderList',
|
||||
method: 'POST',
|
||||
data: { current, limit, orderStatus, come: '10', userId: uni.getStorageSync('userInfo').id }
|
||||
data: { page, limit, orderStatus, come: '10', userId: uni.getStorageSync('userInfo').id }
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<!-- VIP优惠价 -->
|
||||
<view v-if="item.isVipPrice === 1 && item.vipPrice" class="price-info">
|
||||
<text class="vip-price">{{ parseFloat(item.vipPrice).toFixed(2) }} 天医币</text>
|
||||
<text class="vip-label">VIP到手价</text>
|
||||
<text class="vip-label">VIP优惠价</text>
|
||||
<text class="original-price">{{ parseFloat(item.price).toFixed(2) }} 天医币</text>
|
||||
</view>
|
||||
|
||||
|
||||
0
components/order/Payment.vue
Normal file
0
components/order/Payment.vue
Normal file
229
components/order/Price.vue
Normal file
229
components/order/Price.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<!-- 商品总价 -->
|
||||
<!-- <view class="price-item">
|
||||
<text class="label">{{ $t('order.totalPrice') }}</text>
|
||||
<text class="value">¥{{ totalPrice.toFixed(2) }}</text>
|
||||
</view> -->
|
||||
|
||||
<!-- 优惠券 -->
|
||||
<!-- <view class="price-item" @click="showCouponPopup = true">
|
||||
<view class="label-row">
|
||||
<text class="label">{{ $t('order.coupon') }}</text>
|
||||
</view>
|
||||
<view class="value-row">
|
||||
<template v-if="!selectedCoupon">
|
||||
<view v-if="availableCouponCount > 0" class="coupon-badge">
|
||||
<text>{{ $t('order.couponCount', { count: availableCouponCount }) }}</text>
|
||||
</view>
|
||||
<text v-else-if="couponList.length === 0" class="unavailable-text">
|
||||
{{ $t('order.noCoupon') }}
|
||||
</text>
|
||||
<text v-else class="unavailable-text">
|
||||
{{ $t('order.unavailable') }}
|
||||
</text>
|
||||
</template>
|
||||
<template v-else>
|
||||
<text class="discount-value">-¥{{ selectedCoupon.couponEntity.couponAmount }}</text>
|
||||
<text class="reselect-btn">{{ $t('order.reselect') }}</text>
|
||||
</template>
|
||||
<image
|
||||
v-if="availableCouponCount > 0 || selectedCoupon"
|
||||
src="/static/icon/icon_right.png"
|
||||
class="arrow-icon"
|
||||
/>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 活动立减 -->
|
||||
<view v-if="hasActivityDiscount" class="price-item">
|
||||
<text class="label">{{ $t('order.activityDiscount') }}</text>
|
||||
<text class="discount-value">-¥{{ activityDiscountAmount.toFixed(2) }}</text>
|
||||
</view>
|
||||
|
||||
<!-- VIP专享立减 -->
|
||||
<view v-if="vipPrice > 0" class="price-item">
|
||||
<view class="label-row">
|
||||
<text class="vip-icon">VIP</text>
|
||||
<text class="label">{{ $t('order.vipDiscount') }}</text>
|
||||
</view>
|
||||
<text class="discount-value">-¥{{ vipPrice.toFixed(2) }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 地区优惠 -->
|
||||
<view v-if="districtAmount > 0" class="price-item">
|
||||
<text class="label">{{ $t('order.districtDiscount') }}</text>
|
||||
<text class="discount-value">-¥{{ districtAmount.toFixed(2) }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 积分 -->
|
||||
<view v-if="initData && initData.user.jf > 0" class="price-item">
|
||||
<view class="label-row">
|
||||
<image src="/static/icon/jifen.png" class="icon-img" />
|
||||
<text class="label">{{ $t('order.points') }}</text>
|
||||
<text class="points-total">
|
||||
({{ $t('order.allPoints') }}:{{ initData.user.jf }})
|
||||
</text>
|
||||
</view>
|
||||
<text class="discount-value">-¥{{ jfNumberShow }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 积分输入 -->
|
||||
<view v-if="initData && initData.user.jf > 0" class="points-input-section">
|
||||
<text class="points-label">
|
||||
{{ $t('order.maxPoints', { max: jfNumberMax }) }}
|
||||
</text>
|
||||
<view class="points-input-box">
|
||||
<wd-input
|
||||
v-model="jfNumber"
|
||||
type="number"
|
||||
:placeholder="$t('order.pointsPlaceholder')"
|
||||
@input="handlePointsInput"
|
||||
@clear="handlePointsClear"
|
||||
clearable
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<wd-cell-group border class="p-0!">
|
||||
<wd-cell title="商品总价" :value="`${totalPrice.toFixed(2)}天医币`" />
|
||||
<wd-cell title="优惠券" :value="`-${selectedCoupon?.couponEntity?.couponAmount || 0}天医币`" />
|
||||
<wd-cell title="活动立减" :value="`-${selectedCoupon?.couponEntity?.couponAmount || 0}天医币`" />
|
||||
<wd-cell :value="`-${vipPrice.toFixed(2)}天医币`">
|
||||
<template #title><text class="text-[#f94f04] font-bold">VIP</text>专项立减</template>
|
||||
</wd-cell>
|
||||
<wd-cell title="地区优惠" :value="`-${selectedCoupon?.couponEntity?.couponAmount || 0}天医币`" />
|
||||
</wd-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
totalPrice: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
vipPrice: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.wd-cell__wrapper) {
|
||||
padding: 5px 0;
|
||||
|
||||
.wd-cell__title {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.price-section {
|
||||
.price-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 0;
|
||||
font-size: 28rpx;
|
||||
|
||||
.label-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.vip-icon {
|
||||
padding: 2rpx 8rpx;
|
||||
background-color: #f94f04;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
border-radius: 4rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icon-img {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.points-total {
|
||||
font-size: 24rpx;
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.value-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
|
||||
.coupon-badge {
|
||||
padding: 4rpx 20rpx;
|
||||
background-color: #fceeeb;
|
||||
color: #ec4729;
|
||||
font-size: 24rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.unavailable-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.reselect-btn {
|
||||
padding: 4rpx 12rpx;
|
||||
background-color: #fe6035;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.discount-value {
|
||||
color: #fe6035;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.points-input-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15rpx 0;
|
||||
margin-top: 10rpx;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 20rpx;
|
||||
padding: 20rpx;
|
||||
|
||||
.points-label {
|
||||
font-size: 28rpx;
|
||||
color: #7dc1f0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.points-input-box {
|
||||
width: 320rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -412,6 +412,66 @@
|
||||
},
|
||||
"order": {
|
||||
"selectFuduScheme": "Select Fudu Scheme",
|
||||
"selectPurchaseScheme": "Select Purchase Scheme"
|
||||
"selectPurchaseScheme": "Select Purchase Scheme",
|
||||
"confirmTitle": "Confirm Order",
|
||||
"goodsInfo": "Product Information",
|
||||
"priceDetail": "Price Details",
|
||||
"totalPrice": "Subtotal",
|
||||
"coupon": "Coupon",
|
||||
"points": "Points",
|
||||
"vipDiscount": "VIP Exclusive Discount",
|
||||
"activityDiscount": "Activity Discount",
|
||||
"districtDiscount": "Regional Discount",
|
||||
"actualPayment": "Total",
|
||||
"paymentMethod": "Payment Method",
|
||||
"virtualCoin": "Virtual Coin",
|
||||
"balance": "Balance",
|
||||
"recharge": "Recharge Now",
|
||||
"remark": "Order Remark",
|
||||
"remarkPlaceholder": "Optional: Leave a message",
|
||||
"remarkTitle": "Order Remark",
|
||||
"submit": "Pay Now",
|
||||
"submitting": "Submitting...",
|
||||
"total": "Total",
|
||||
"noCoupon": "No coupons available",
|
||||
"unavailable": "Unavailable",
|
||||
"selectCoupon": "Please select a coupon",
|
||||
"notUseCoupon": "Don't use coupon",
|
||||
"reselect": "Reselect",
|
||||
"selected": "Confirm",
|
||||
"maxPoints": "Available Points ({max} pts)",
|
||||
"pointsPlaceholder": "Enter points",
|
||||
"allPoints": "Total Points",
|
||||
"insufficientBalance": "Insufficient virtual coin balance",
|
||||
"orderCreating": "Creating order",
|
||||
"orderSuccess": "Purchase successful",
|
||||
"orderFailed": "Failed, please try again",
|
||||
"tooFrequent": "Too frequent, please wait",
|
||||
"duplicateOrder": "You have a similar order recently. Continue?",
|
||||
"duplicateConfirm": "Continue",
|
||||
"duplicateCancel": "Cancel",
|
||||
"customerService": "Customer Service",
|
||||
"paymentTip": "1 Virtual Coin = 1 CNY",
|
||||
"paymentTipTitle": "Notes",
|
||||
"paymentTip1": "1. 1 Virtual Coin = 1 CNY",
|
||||
"paymentTip2": "2. For questions, please call customer service",
|
||||
"paymentTip3": "3. Non-mainland China users can pay by credit card. Simple and fast, recommended! Credit cards with Visa or MasterCard logos are accepted. Please send payment request to email",
|
||||
"paymentTip3_1": "(click to copy) with course name, amount, registered name and phone number, or add WeChat customer service (",
|
||||
"paymentTip3_2": ") (click to copy). We will send payment link within 24 hours.",
|
||||
"ensureBalance": "Ensure sufficient virtual coin balance",
|
||||
"vipLabel": "VIP Discount",
|
||||
"activityLabel": "Activity Price",
|
||||
"vipPriceLabel": "VIP Price",
|
||||
"quantity": "Quantity",
|
||||
"couponAmount": "¥",
|
||||
"couponUseLevel": "Min. {level} CNY",
|
||||
"couponExpiry": "Valid until",
|
||||
"couponForever": "Permanent",
|
||||
"couponReason": "Reason",
|
||||
"couponUsage": "Usage",
|
||||
"couponType0": "All Products",
|
||||
"couponType1": "Specific Courses",
|
||||
"couponType2": "Course Categories",
|
||||
"couponCount": "{count} coupons"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,6 +413,66 @@
|
||||
},
|
||||
"order": {
|
||||
"selectFuduScheme": "选择复读方案",
|
||||
"selectPurchaseScheme": "选择购买方案"
|
||||
"selectPurchaseScheme": "选择购买方案",
|
||||
"confirmTitle": "确认订单",
|
||||
"goodsInfo": "商品信息",
|
||||
"priceDetail": "价格明细",
|
||||
"totalPrice": "商品总价",
|
||||
"coupon": "优惠券",
|
||||
"points": "积分",
|
||||
"vipDiscount": "VIP专享立减",
|
||||
"activityDiscount": "活动立减",
|
||||
"districtDiscount": "地区优惠",
|
||||
"actualPayment": "实付款",
|
||||
"paymentMethod": "支付方式",
|
||||
"virtualCoin": "天医币",
|
||||
"balance": "余额",
|
||||
"recharge": "立即充值",
|
||||
"remark": "订单备注",
|
||||
"remarkPlaceholder": "选填:给商家留言",
|
||||
"remarkTitle": "订单备注",
|
||||
"submit": "立即支付",
|
||||
"submitting": "提交中...",
|
||||
"total": "合计",
|
||||
"noCoupon": "暂无可用优惠券",
|
||||
"unavailable": "不可用",
|
||||
"selectCoupon": "请选择优惠券",
|
||||
"notUseCoupon": "不使用优惠券",
|
||||
"reselect": "重新选择",
|
||||
"selected": "选好了",
|
||||
"maxPoints": "可用积分({max}分)",
|
||||
"pointsPlaceholder": "请输入积分",
|
||||
"allPoints": "全部积分",
|
||||
"insufficientBalance": "天医币余额不足",
|
||||
"orderCreating": "正在请求订单",
|
||||
"orderSuccess": "购买成功",
|
||||
"orderFailed": "失败,请重新下单",
|
||||
"tooFrequent": "操作太频繁了,休息下吧",
|
||||
"duplicateOrder": "您短时间内有一笔相同金额的订单,是否确定继续下单?",
|
||||
"duplicateConfirm": "继续操作",
|
||||
"duplicateCancel": "点错了",
|
||||
"customerService": "客服",
|
||||
"paymentTip": "1天医币 = 1元人民币",
|
||||
"paymentTipTitle": "说明",
|
||||
"paymentTip1": "1. 1天医币 = 1元人民币",
|
||||
"paymentTip2": "2.若有疑问或意见请致电客服",
|
||||
"paymentTip3": "3.非中国大陆用户可以信用卡支付。简单快捷,推荐使用!支付时使用的信用卡需要带有Visa或MasterCard的标识。请向邮箱",
|
||||
"paymentTip3_1": "(点击复制)发送支付请求,内容需包含:拟购买的课程名称、支付金额、APP注册姓名及手机号码,或者加一路健康客服微信(",
|
||||
"paymentTip3_2": ")(点击复制)联系我们,我们将在24小时内向您的邮箱或者微信发送支付链接,根据提示即可完成信用卡支付,无需兑换外币。",
|
||||
"ensureBalance": "确保您的天医币足够支付",
|
||||
"vipLabel": "VIP优惠",
|
||||
"activityLabel": "活动价",
|
||||
"vipPriceLabel": "VIP到手价",
|
||||
"quantity": "数量",
|
||||
"couponAmount": "¥",
|
||||
"couponUseLevel": "满{level}元可用",
|
||||
"couponExpiry": "有效期至",
|
||||
"couponForever": "永久有效",
|
||||
"couponReason": "不可用原因",
|
||||
"couponUsage": "使用说明",
|
||||
"couponType0": "全场通用",
|
||||
"couponType1": "指定课程可用",
|
||||
"couponType2": "指定课程品类可用",
|
||||
"couponCount": "共 {count} 张"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +152,10 @@
|
||||
"navigationBarTitleText": "%courseDetails.chapter%"
|
||||
}
|
||||
}, {
|
||||
"path": "pages/course/order",
|
||||
"path": "pages/order/confirmOrder",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "%courseOrder.orderTitle%"
|
||||
"navigationBarTitleText": "%order.confirmTitle%"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -449,8 +449,6 @@ const closeGoodsSelector = () => {
|
||||
*/
|
||||
const confirmPurchase = () => {
|
||||
showProtocol.value = false
|
||||
uni.showToast({ icon: 'none', title: '订单及支付功能开发中' })
|
||||
return false
|
||||
if (!selectedGoods.value) return
|
||||
|
||||
showProtocol.value = false
|
||||
@@ -458,15 +456,16 @@ const confirmPurchase = () => {
|
||||
// 跳转到确认订单页
|
||||
const orderData = {
|
||||
goods: [{ ...selectedGoods.value, productAmount: 1 }],
|
||||
typeId: 0,
|
||||
navTitle: courseDetail.value?.title,
|
||||
title: courseDetail.value?.title,
|
||||
isFudu: isFudu.value,
|
||||
fuduId: isFudu.value ? fuduCatalogueId.value : undefined
|
||||
// typeId: 0,
|
||||
// navTitle: courseDetail.value?.title,
|
||||
// title: courseDetail.value?.title,
|
||||
// isFudu: isFudu.value,
|
||||
// fuduId: isFudu.value ? fuduCatalogueId.value : undefined
|
||||
}
|
||||
|
||||
uni.navigateTo({
|
||||
url: `/pages/course/order?data=${encodeURIComponent(JSON.stringify(orderData))}`
|
||||
// url: `/pages/order/confirmOrder?data=${encodeURIComponent(JSON.stringify(orderData))}`
|
||||
url: `/pages/order/confirmOrder?goods=${selectedGoods.value.productId}`
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
static/icon/jifen.png
Normal file
BIN
static/icon/jifen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
BIN
static/icon/pay_3.png
Normal file
BIN
static/icon/pay_3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -10,6 +10,7 @@
|
||||
--color-red-500: oklch(63.7% 0.237 25.331);
|
||||
--color-white: #fff;
|
||||
--spacing: 0.25rem;
|
||||
--font-weight-bold: 700;
|
||||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--default-transition-duration: 150ms;
|
||||
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
@@ -293,15 +294,40 @@
|
||||
.bg-red-500 {
|
||||
background-color: var(--color-red-500);
|
||||
}
|
||||
.p-0 {
|
||||
padding: calc(var(--spacing) * 0);
|
||||
}
|
||||
.p-0\! {
|
||||
padding: calc(var(--spacing) * 0) !important;
|
||||
}
|
||||
.pt-\[40px\] {
|
||||
padding-top: 40px;
|
||||
}
|
||||
.pb-0 {
|
||||
padding-bottom: calc(var(--spacing) * 0);
|
||||
}
|
||||
.pb-0\! {
|
||||
padding-bottom: calc(var(--spacing) * 0) !important;
|
||||
}
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
.font-bold {
|
||||
--tw-font-weight: var(--font-weight-bold);
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
.text-\[\#000\] {
|
||||
color: #000;
|
||||
}
|
||||
.text-\[\#7dc1f0\] {
|
||||
color: #7dc1f0;
|
||||
}
|
||||
.text-\[\#f94f04\] {
|
||||
color: #f94f04;
|
||||
}
|
||||
.text-\[\#fff\] {
|
||||
color: #fff;
|
||||
}
|
||||
@@ -393,6 +419,10 @@
|
||||
inherits: false;
|
||||
initial-value: solid;
|
||||
}
|
||||
@property --tw-font-weight {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-ordinal {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
@@ -585,6 +615,7 @@
|
||||
--tw-skew-x: initial;
|
||||
--tw-skew-y: initial;
|
||||
--tw-border-style: solid;
|
||||
--tw-font-weight: initial;
|
||||
--tw-ordinal: initial;
|
||||
--tw-slashed-zero: initial;
|
||||
--tw-numeric-figure: initial;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
:root,
|
||||
page {
|
||||
/* 文字字号 */
|
||||
--wot-fs-title: 18px; // 标题字号/重要正文字号
|
||||
--wot-fs-content: 16px; // 普通正文
|
||||
--wot-fs-secondary: 14px; // 次要信息,注释/补充/正文
|
||||
--wot-fs-tertiary: 12px; // 次次要信息,注释/补充/正文
|
||||
--wot-fs-title: 36rpx; // 标题字号/重要正文字号
|
||||
--wot-fs-content: 28rpx; // 普通正文
|
||||
--wot-fs-secondary: 24rpx; // 次要信息,注释/补充/正文
|
||||
--wot-fs-tertiary: 20rpx; // 次次要信息,注释/补充/正文
|
||||
|
||||
// 导航栏
|
||||
--wot-navbar-background: #fff;
|
||||
@@ -16,7 +16,7 @@ page {
|
||||
// --wot-tabbar-item-title-font-size: 16px;
|
||||
|
||||
// cell
|
||||
--wot-cell-title-fs: 16px;
|
||||
--wot-cell-title-fs: 28rpx;
|
||||
|
||||
// dropdown
|
||||
// --wot-drop-menu-selected-color: #5355C8;
|
||||
|
||||
148
types/order.d.ts
vendored
148
types/order.d.ts
vendored
@@ -26,61 +26,127 @@ export interface IOrder {
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单创建参数接口
|
||||
* 课程订单商品信息
|
||||
*/
|
||||
export interface ICreateOrderParams {
|
||||
paymentMethod: '4' | '5' // 支付方式: 4-虚拟币, 5-Google Pay
|
||||
orderMoney: number | string // 订单金额
|
||||
abroadBookId: number // 图书ID
|
||||
orderType: 'abroadBook' // 订单类型
|
||||
export interface IOrderGoods {
|
||||
productId: number
|
||||
productName: string
|
||||
productImages: string
|
||||
price: number
|
||||
vipPrice: number | null
|
||||
activityPrice: number | null
|
||||
isVipPrice: number // 是否有VIP优惠 0-否 1-是
|
||||
productAmount: number // 购买数量
|
||||
goodsType: string // 商品类型 "05" for course
|
||||
}
|
||||
|
||||
/**
|
||||
* Google Pay 验证参数接口
|
||||
* 优惠券实体信息
|
||||
*/
|
||||
export interface IGooglePayVerifyParams {
|
||||
purchaseToken: string // 购买凭证
|
||||
orderSn: string // 订单号
|
||||
productId: string // 产品ID
|
||||
export interface ICouponEntity {
|
||||
id: number
|
||||
couponName: string
|
||||
couponAmount: number
|
||||
useLevel: number // 满多少可用
|
||||
couponRange: number // 0-全场 1-指定课程 2-指定品类
|
||||
remark?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单创建响应接口
|
||||
* 优惠券信息
|
||||
*/
|
||||
export interface ICreateOrderResponse {
|
||||
code: number
|
||||
orderSn: string // 订单号
|
||||
msg?: string
|
||||
export interface ICoupon {
|
||||
id: number
|
||||
couponId: number
|
||||
canUse: number // 0-不可用 1-可用
|
||||
canUseReason?: string
|
||||
effectType: number // 0-永久有效
|
||||
endTime?: string
|
||||
couponEntity: ICouponEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* Google Pay SKU 信息接口
|
||||
* 课程订单创建参数
|
||||
*/
|
||||
export interface IGooglePaySku {
|
||||
productId: string
|
||||
type: string
|
||||
price: string
|
||||
price_amount_micros: number
|
||||
price_currency_code: string
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Google Pay 支付结果接口
|
||||
*/
|
||||
export interface IGooglePayResult {
|
||||
code: number
|
||||
data?: Array<{
|
||||
original: {
|
||||
purchaseToken: string
|
||||
orderId: string
|
||||
packageName: string
|
||||
productId: string
|
||||
purchaseTime: number
|
||||
purchaseState: number
|
||||
}
|
||||
export interface ICourseOrderCreateParams {
|
||||
buyType: number // 0-商品页直接下单 1-购物车结算
|
||||
userId: number
|
||||
paymentMethod: number // 4-天医币
|
||||
orderMoney: number // 订单金额
|
||||
realMoney: number // 实收金额
|
||||
jfDeduction: number // 积分抵扣
|
||||
couponId?: number // 优惠券ID
|
||||
couponName?: string // 优惠券名称
|
||||
vipDiscountAmount: number // VIP折扣金额
|
||||
districtMoney: number // 地区优惠金额
|
||||
remark?: string // 备注
|
||||
productList: Array<{
|
||||
productId: number
|
||||
quantity: number
|
||||
}>
|
||||
orderType: string // "order"
|
||||
addressId: number // 0 for course products
|
||||
appName: string // "wumen"
|
||||
come: number // 2
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单初始化数据
|
||||
*/
|
||||
export interface IOrderInitData {
|
||||
user: {
|
||||
id: number
|
||||
jf: number // 积分
|
||||
peanutCoin: number // 天医币余额
|
||||
vip?: number // VIP状态
|
||||
}
|
||||
is_course: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单路由参数
|
||||
*/
|
||||
export interface IOrderRouteParams {
|
||||
goods: IOrderGoods[]
|
||||
typeId: number
|
||||
sourceType?: string
|
||||
navTitle?: string
|
||||
title?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 价格明细项
|
||||
*/
|
||||
export interface IPriceBreakdownItem {
|
||||
type: number // 1-商品总价 2-运费 3-优惠券 4-积分 5-活动立减 6-VIP立减
|
||||
text: string
|
||||
imgUrl?: string
|
||||
icon?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单状态
|
||||
*/
|
||||
export interface IOrderState {
|
||||
orderData: IOrderRouteParams
|
||||
goodsList: IOrderGoods[]
|
||||
initData: IOrderInitData | null
|
||||
totalPrice: number
|
||||
vipPrice: number
|
||||
districtAmount: number
|
||||
actualPayment: number
|
||||
jfNumber: number
|
||||
jfNumberMax: number
|
||||
jfNumberShow: string
|
||||
couponList: ICoupon[]
|
||||
selectedCoupon: ICoupon | null
|
||||
showCouponPopup: boolean
|
||||
remark: string
|
||||
showRemarkPopup: boolean
|
||||
payType: number
|
||||
loading: boolean
|
||||
submitting: boolean
|
||||
buyingFlag: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ export const onPageBack = () => {
|
||||
/**
|
||||
* 拨打电话
|
||||
*/
|
||||
export const makePhoneCall = (phoneNumber: string, title: string) => {
|
||||
export const makePhoneCall = (phoneNumber: string, title: string = '') => {
|
||||
uni.showModal({
|
||||
title: title,
|
||||
content: phoneNumber,
|
||||
|
||||
Reference in New Issue
Block a user