第一次提交

This commit is contained in:
gxwebsoft
2023-08-04 13:04:21 +08:00
commit 7a73b38bd5
764 changed files with 166417 additions and 0 deletions

601
pages/checkout/cashier/index.vue Executable file
View File

@@ -0,0 +1,601 @@
<template>
<view>
<view v-if="!isLoading && order" class="container" :style="appThemeStyle">
<!-- 订单信息 -->
<view class="order-info">
<!-- 支付剩余时间 -->
<view class="order-countdown">
<text class="m-r-6">剩余时间</text>
<count-down :date="expirationTime" separator="zh" theme="text" />
</view>
<!-- 付款金额 -->
<view class="order-amount">
<text class="unit"></text>
<text class="amount">{{ order.totalPrice }}</text>
</view>
</view>
<!-- 支付方式 -->
<view class="payment-method">
<view v-for="(item, index) in methods" :key="index" class="pay-item dis-flex flex-x-between"
@click="handleSelectPayType(index)">
<view class="item-left dis-flex flex-y-center">
<view class="item-left_icon" :class="[item.method]">
<text class="iconfont" :class="[item.icon]"></text>
</view>
<view class="item-left_text">
<text>{{ item.method }}</text>
</view>
<view v-if="item.method === '余额支付'" class="user-balance">
<text>(可用{{ personal.balance }})</text>
</view>
</view>
<view class="item-right col-m" v-if="curPaymentItem && curPaymentItem.method == item.method">
<text class="iconfont icon-check"></text>
</view>
</view>
</view>
<!-- 确认按钮 -->
<view class="footer-fixed">
<view class="btn-wrapper">
<view class="btn-item btn-item-main" :class="{ disabled }" @click="handleSubmit()">确认支付</view>
</view>
</view>
<!-- 支付确认弹窗 -->
<!-- #ifdef H5 -->
<u-modal v-if="tempUnifyData" v-model="showConfirmModal" title="支付确认" show-cancel-button confirm-text="已完成支付"
:confirm-color="appTheme.mainBg" negative-top="100" :asyncClose="true"
@confirm="onTradeQuery(tempUnifyData.outTradeNo, tempUnifyData.method)">
<view class="modal-content">
<text>请在{{ PayMethodClientNameEnum[tempUnifyData.method] }}内完成支付如果您已经支付成功请点击已完成支付按钮</text>
</view>
</u-modal>
<!-- #endif -->
</view>
<empty v-else :isLoading="isLoading" tips="订单不存在" />
</view>
</template>
<script>
import storage from '@/utils/storage'
import {
inArray,
urlEncode
} from '@/utils/util'
import {
Alipay,
Wechat
} from '@/core/payment'
import CountDown from '@/components/countdown'
import {
PayMethodEnum
} from '@/common/enum/payment'
import {
PayStatusEnum
} from '@/common/enum/order'
import {
getOrder,
setPayStatus
} from '@/websoft/api/order.js'
import {
pagePayment,
alipay,
payQuery,
balance
} from '@/websoft/api/payment.js'
import {
dateFormat
} from '@/utils/util.js'
import Empty from '@/components/empty'
import * as CashierApi from '@/api/cashier'
import { getUser } from '@/websoft/api/user.js'
// 支付方式对应的图标
const PayMethodIconEnum = {
[PayMethodEnum.WECHAT.value]: 'icon-wechat-pay',
[PayMethodEnum.ALIPAY.value]: 'icon-alipay',
[PayMethodEnum.BALANCE.value]: 'icon-balance-pay'
}
// 支付方式的终端名称
const PayMethodClientNameEnum = {
[PayMethodEnum.WECHAT.value]: '微信',
[PayMethodEnum.ALIPAY.value]: '支付宝'
}
export default {
components: {
CountDown,
Empty
},
data() {
return {
// 加载中
isLoading: true,
// 确认按钮禁用
disabled: false,
// 枚举类
PayMethodEnum,
PayMethodIconEnum,
PayMethodClientNameEnum,
// 当前选中的支付方式
curPaymentItem: {
method: '余额支付'
},
// 当前订单ID
orderId: null,
// 当前结算订单信息
order: null,
// 订单过期时间
expirationTime: new Date(),
// 个人信息
personal: {
balance: '0.00'
},
// 当前客户端的支付方式列表后端根据platform判断
methods: [
{
id: 1,
method: '余额支付',
icon: 'icon-balance-pay'
},
{
id: 2,
method: '支付宝',
icon: 'icon-alipay'
}
],
// 支付确认弹窗
showConfirmModal: false,
// #ifdef H5
// 当前微信支付信息 (临时数据, 仅用于H5端)
tempUnifyData: {
outTradeNo: '',
method: ''
},
// #endif
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad({
orderId
}) {
// 记录订单ID
this.orderId = Number(orderId)
// 获取收银台信息
this.getCashierInfo()
},
methods: {
// 获取收银台信息
getCashierInfo() {
const app = this
const {
orderId
} = this
app.isLoading = true
// 加载订单
getOrder(orderId)
.then(res => {
app.order = res.data
app.isLoading = false
// 处理订单过期时间(*1小时)
var expirationTime = new Date().getTime() + 60 * 60 * 1000 * 0.20
app.expirationTime = dateFormat('YYYY-mm-dd HH:MM:SS', new Date(expirationTime))
})
.catch(e => {
console.log("e: ", e);
})
// 查询余额
getUser().then(res => app.personal = res.data)
// pagePayment({}).then(res => {
// app.methods = res.data.list
// })
// CashierApi.orderInfo(app.orderId, { client: app.platform })
// .then(result => {
// app.order = result.data.order
// console.log("app.order: ",app.order);
// app.personal = result.data.personal
// app.methods = result.data.paymentMethods
// app.isLoading = false
// app.setDefaultPayType()
// app.checkOrderPayStatus()
// // #ifdef H5
// // 判断当前页面来源于浏览器返回
// this.performance()
// // #endif
// })
},
// 设置默认的支付方式
setDefaultPayType() {
const app = this
if (app.disabled) return
const defaultIndex = app.methods.findIndex(item => item.is_default == true)
defaultIndex > -1 && app.handleSelectPayType(defaultIndex)
},
// 判断当前订单是否为已支付
checkOrderPayStatus() {
const app = this
if (app.order.pay_status == PayStatusEnum.SUCCESS.value) {
app.$toast('恭喜您,订单已付款成功')
app.onSuccessNav()
}
},
// 选择支付方式
handleSelectPayType(index) {
this.curPaymentItem = this.methods[index]
console.log("this.curPaymentItem: ", this.curPaymentItem);
},
// 判断当前页面来源于浏览器返回
// #ifdef H5
performance() {
const app = this
// 判断订单状态, 异步回调会将订单状态变为已支付, 那么就不需要让用户手动查单了
if (app.order.pay_status == PayStatusEnum.PENDING.value) {
app.alipayPerformance()
app.wechatPerformance()
}
},
// H5端支付宝支付完成跳转回当前页面时触发
alipayPerformance() {
const app = this
app.tempUnifyData = Alipay.performance()
if (app.tempUnifyData) {
app.onTradeQuery(app.tempUnifyData.outTradeNo, app.tempUnifyData.method)
}
},
// H5端微信支付完成或返回时触发
wechatPerformance() {
const app = this
app.tempUnifyData = Wechat.performance(app.orderId)
if (app.tempUnifyData) {
app.showConfirmModal = true
}
},
// #endif
// 确认支付
handleSubmit() {
const app = this
const {
orderId
} = app.order
// 判断是否选择了支付方式
if (!app.curPaymentItem) {
app.$toast('您还没有选择支付方式')
return
}
// 按钮禁用
if (app.disabled) return
// app.disabled = true
// .js
console.log("curPaymentItem: ",app.curPaymentItem);
if(app.curPaymentItem.method == '余额支付'){
balance(orderId).then(result => app.onSubmitCallback(result)).catch(err => app.$error(err.message))
}
if(app.curPaymentItem.method == '支付宝'){
alipay(orderId).then(result => app.onSubmitCallback(result)).catch(err => app.$error(err.message))
}
// // 提交到后端API
// CashierApi.orderPay(app.orderId, {
// method: app.curPaymentItem.method,
// client: app.platform,
// extra: app.getExtraAsUnify(app.curPaymentItem.method)
// })
// .then(result => app.onSubmitCallback(result))
// .finally(err => setTimeout(() => app.disabled = false, 10))
},
// 获取第三方支付的扩展参数
getExtraAsUnify(method) {
if (method === PayMethodEnum.ALIPAY.value) {
return Alipay.extraAsUnify()
}
if (method === PayMethodEnum.WECHAT.value) {
return Wechat.extraAsUnify()
}
return {}
},
// 订单提交成功后回调
onSubmitCallback(result) {
const app = this
const method = app.curPaymentItem.method
const tradeNO = result.data
console.log("result订单提交成功后回调: ", tradeNO);
// 余额支付
if (method === '余额支付') {
app.onShowSuccess(result)
}
// 发起支付宝支付
if (method === '支付宝') {
my.tradePay({
// 调用统一收单交易创建接口alipay.trade.create获得返回字段支付宝交易号trade_no
tradeNO: tradeNO,
success: (res) => {
console.log("res11: ", res);
if (res.resultCode == "9000") {
payQuery(app.orderId).then(result => {
if(result.code == 0) {
app.$success('支付成功')
app.$navTo('pages/order/index')
}
})
// setPayStatus({
// orderId: app.orderId,
// payStatus: 20,
// payMethod: 20
// }).then(res => {
// console.log("updateOrder: ",res);
// app.$navTo('pages/order/index')
// })
}
if (res.resultCode == "6001") {
app.$navTo('pages/order/index')
}
// my.alert({
// content: JSON.stringify(res),
// });
},
fail: (res) => {
my.alert({
content: JSON.stringify(res),
});
}
});
// Alipay.payment(paymentData)
// .then(res => app.onPaySuccess(res))
// .catch(err => app.onPayFail(err))
}
// 发起微信支付
if (method === PayMethodEnum.WECHAT.value) {
console.log('paymentData', paymentData)
Wechat.payment({
orderKey: app.orderId,
...paymentData
})
.then(res => app.onPaySuccess(res))
.catch(err => app.onPayFail(err))
}
},
// 订单支付成功的回调方法
// 这里只是前端支付api返回结果success,实际订单是否支付成功 以后端的查单和异步通知为准
onPaySuccess({
res,
option: {
isRequireQuery,
outTradeNo,
method
}
}) {
const app = this
// 判断是否需要主动查单
// isRequireQuery为true代表需要主动查单
if (isRequireQuery) {
app.onTradeQuery(outTradeNo, method)
return true
}
this.onShowSuccess(res)
},
// 显示支付成功信息并页面跳转
onShowSuccess({
message
}) {
this.$toast(message || '订单支付成功')
this.onSuccessNav()
},
// 订单支付失败
onPayFail(err) {
console.log('onPayFail', err)
const errMsg = err.message || '订单未支付'
this.$error(errMsg)
},
// 已完成支付按钮事件: 请求后端查单
onTradeQuery(outTradeNo, method) {
const app = this
// 交易查询
// 查询第三方支付订单是否付款成功
CashierApi.tradeQuery({
outTradeNo,
method,
client: app.platform
})
.then(result => result.data.isPay ? app.onShowSuccess(result) : app.onPayFail(result))
.finally(() => app.showConfirmModal = false)
},
// 支付成功后的跳转
onSuccessNav() {
// 相应全局事件订阅: 刷新上级页面数据
uni.$emit('syncRefreshOrder', true)
// 获取上级页面
const pages = getCurrentPages()
const lastPage = pages.length < 2 ? null : pages[pages.length - 2]
const backRoutes = [
'pages/order/index',
'pages/order/detail'
]
setTimeout(() => {
if (lastPage && inArray(lastPage.route, backRoutes)) {
uni.navigateBack()
} else {
this.$navTo('pages/order/index', {}, 'redirectTo')
}
}, 1200)
},
}
}
</script>
<style>
page {
background: #F4F4F4;
}
</style>
<style lang="scss" scoped>
.container {
background-color: #F4F4F4;
}
// 订单信息
.order-info {
padding: 80rpx 0;
text-align: center;
.order-countdown {
display: flex;
justify-content: center;
font-size: 26rpx;
color: #666666;
margin-bottom: 20rpx;
}
.order-amount {
margin: 0 auto;
max-width: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fb0f07;
.unit {
font-size: 30rpx;
margin-bottom: -18rpx;
}
.amount {
font-size: 56rpx;
}
}
}
// 支付方式
.payment-method {
width: 94%;
margin: 0 auto 20rpx auto;
padding: 0 40rpx;
background-color: #ffffff;
border-radius: 20rpx;
.pay-item {
padding: 26rpx 0;
font-size: 28rpx;
border-bottom: 1rpx solid rgb(248, 248, 248);
&:last-child {
border-bottom: none;
}
.item-left_icon {
margin-right: 20rpx;
font-size: 44rpx;
&.wechat {
color: #00c800;
}
&.alipay {
color: #009fe8;
}
&.balance {
color: #ff9700;
}
}
.item-left_text {
font-size: 28rpx;
}
.item-right {
font-size: 32rpx;
}
.user-balance {
margin-left: 20rpx;
font-size: 26rpx;
}
}
}
// 支付确认弹窗
.modal-content {
padding: 40rpx 48rpx;
font-size: 30rpx;
line-height: 50rpx;
text-align: left;
color: #606266;
// height: 620rpx;
box-sizing: border-box;
}
// 底部操作栏
.footer-fixed {
position: fixed;
bottom: var(--window-bottom);
left: 0;
right: 0;
z-index: 11;
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
background: #fff;
// 设置ios刘海屏底部横线安全区域
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.btn-wrapper {
height: 120rpx;
display: flex;
align-items: center;
padding: 0 40rpx;
}
.btn-item {
flex: 1;
font-size: 28rpx;
height: 80rpx;
color: #fff;
border-radius: 50rpx;
display: flex;
justify-content: center;
align-items: center;
}
.btn-item-main {
background: linear-gradient(to right, $main-bg, $main-bg2);
color: $main-text;
// 禁用按钮
&.disabled {
opacity: 0.6;
}
}
}
</style>

378
pages/checkout/checkout.vue Normal file
View File

@@ -0,0 +1,378 @@
<template>
<view>
<view class="goods-info">
<view class="goods">
<image v-if="record.image" :src="record.image" class="equipment-image" mode="aspectFit"></image>
<image v-else src="../../static/goods/battery.png" class="equipment-image" mode="aspectFit"></image>
<view class="info">
<text class="goods-name">{{ record.equipmentName }}</text>
<text class="goods-desc">归属门店{{ record.merchantName }}</text>
<text class="goods-desc">电池型号{{ record.batteryModel }}</text>
<text class="selling-point">{{ record.sellingPoint }}</text>
</view>
</view>
</view>
<view class="order">
<block v-if="record.equipmentCategory === '10'">
<view class="title">
<text>合计总金额</text>
<text>{{ record.batteryPrice + record.batteryInsurance }}</text>
</view>
<!-- <u-cell-group>
<u-cell-item title="电池租金" :border-bottom="false" hover-class="none" :value="record.batteryRent"></u-cell-item>
<u-cell-item title="电池押金" :border-bottom="false" hover-class="none" :value="record.batteryDeposit"></u-cell-item>
<u-cell-item title="电池保险" :border-bottom="false" hover-class="none" :value="record.batteryInsurance"></u-cell-item>
</u-cell-group> -->
</block>
<block v-if="record.equipmentCategory === '20'">
<view class="title">
<text>合计总金额</text>
<text>{{ (record.downPayment).toFixed(2) }}</text>
</view>
<view class="fenqi">
<view class="item">
<view class="name">销售价格</view>
{{ record.batteryPrice }}
</view>
<view class="item">
<view class="name">首付款</view>
{{ record.downPayment }}
</view>
<view class="item">
<view class="name">余额分期期数</view>
{{ record.periods }}
<!-- <u-number-box :min="6" :max="36" :value="record.periods" :step="6" @change="onChangeStepper($event)" /> -->
</view>
<view class="item">
<view class="name">每期还款</view>
{{ record.repayment }}
</view>
<view class="item">
<view class="name">每期手续费</view>
{{ record.serviceCharges }}
</view>
<view class="item">
<view class="name">电动车保险</view>
<view>{{ record.batteryInsurance }}</view>
</view>
</view>
</block>
<block v-if="record.equipmentCategory === '30'">
<view class="title">
<text>合计总金额</text>
<text>{{ (record.batteryRent + record.batteryDeposit + record.batteryInsurance).toFixed(2) }}</text>
</view>
<u-cell-group>
<u-cell-item :title="`租金(按${record.periodsType == 0 ? '周' : '月'})`" :border-bottom="false" hover-class="none" :value="record.batteryRent"></u-cell-item>
<u-cell-item title="分期期数" :border-bottom="false" hover-class="none" :value="record.periods"></u-cell-item>
<u-cell-item title="押金" :border-bottom="false" hover-class="none" :value="record.batteryDeposit"></u-cell-item>
<u-cell-item title="保险" :border-bottom="false" hover-class="none" :value="record.batteryInsurance"></u-cell-item>
</u-cell-group>
</block>
<block v-if="record.equipmentCategory === '40'">
<view class="title">
<text>合计总金额</text>
<text>{{ (record.batteryRent + record.batteryDeposit + record.batteryInsurance).toFixed(2) }}</text>
</view>
<view class="fenqi">
<view class="item">
<view class="name">电动车租金</view>
{{ record.batteryRent }}
</view>
<view class="item">
<view class="name">电动车押金</view>
{{ record.batteryDeposit }}
</view>
<view class="item">
<view class="name">电动车保险</view>
{{ record.batteryInsurance }}
</view>
</view>
<!-- <u-cell-group>
<u-cell-item title="电动车租金" :border-bottom="false" hover-class="none" :value="`¥${record.batteryRent} 元`"></u-cell-item>
<u-cell-item title="电动车押金" :border-bottom="false" hover-class="none" :value="record.batteryDeposit"></u-cell-item>
<u-cell-item title="电动车保险" :border-bottom="false" hover-class="none" :value="record.batteryInsurance"></u-cell-item>
</u-cell-group> -->
</block>
<view class="xieyi">
<checkbox-group @change="onAgree" style="display: flex; align-items: center;">
<checkbox :checked="agree" />我已同意并阅读<div class="xieyi-text" @click="showXieyi">服务协议</div><div class="xieyi-text" @click="showXieyi">隐私协议</div>
</checkbox-group>
</view>
</view>
<view class="submit">
<u-input v-model="dealerId" :disabled="disabled" placeholder="请输入推荐人用户ID" />
</view>
<view class="submit">
<u-button type="primary" :disabled="!agree" @click="onBuy">立即下单</u-button>
</view>
<!-- <view class="submit">
<u-button type="success" :disabled="agree" @click="copyCode(record.equipmentCode)">复制设备编号</u-button>
</view> -->
</view>
</template>
<script>
import { userId } from '@/config.js';
import {
getEquipmentGoods
} from '@/websoft/api/equipment-goods.js'
import { getUser } from '@/websoft/api/user.js'
import { addOrder } from '@/websoft/api/order.js'
import { dateFormat } from '@/utils/util.js'
import { createOrderNo } from '@/utils/util.js'
import store from '../../store';
import {
payQuery
} from '@/websoft/api/payment.js'
export default {
components: {
// Search
},
data() {
return {
record: {},
// 正在加载中
isLoading: true,
// 当前选择的设备ID
goodsId: null,
show: true,
mode: 'range',
month: 6,
agree: false,
dealerId: '',
price: {
batteryRent: 300,
batteryDeposit: 300,
batteryInsurance: 0
},
}
},
onLoad(option) {
const app = this
// 记录当前选择的门店ID
app.goodsId = option.goodsId
// 获取设备列表
app.getEquipment()
},
onShow(){
var time = new Date().getTime() + 60*60*1000*24
const expirationTime = dateFormat('YYYY-mm-dd HH:MM:SS', new Date(time))
console.log("time: ",time);
console.log("expirationTime: ",expirationTime);
payQuery(752).then(res => {
console.log("res123: ",res);
})
},
methods: {
getEquipment() {
const app = this
const {
goodsId
} = this
getEquipmentGoods(goodsId).then(res => {
app.record = res.data
console.log("res: ", app.record);
})
},
onChangeStepper({ value }) {
this.month = value
},
change(e) {
console.log(e);
},
onInput(month) {
this.month = month
},
onAgree(){
this.agree = !this.agree
},
showXieyi(){
this.$navTo('pages/help/xieyi')
},
copyCode(text){
// #ifndef H5
console.log("text: ",text);
uni.setClipboardData({
text: text,
success: (result) => {
this.$success("复制成功")
}
})
// #endif
// #ifdef H5
let textarea = document.createElement("textarea")
textarea.value = text
textarea.readOnly = "readOnly"
document.body.appendChild(textarea)
textarea.select() // 选中文本内容
textarea.setSelectionRange(0, info.length)
uni.showToast({ //提示
title: '复制成功'
})
result = document.execCommand("copy")
textarea.remove()
// #endif
// copy() {
// let result
// // #ifndef H5
// //uni.setClipboardData方法就是讲内容复制到粘贴板
// uni.setClipboardData({
// data: this.downUrl.url, //要被复制的内容
// success: () => { //复制成功的回调函数
// uni.showToast({ //提示
// title: '复制成功'
// })
// }
// });
// // #endif
// }
},
onBuy(){
const app = this
const { record,dealerId } = this
let total = 0.0
// 未登录状态
if(!uni.getStorageSync('userId')) {
app.$error('请先登录',function(){
app.$navTo('pages/login/login');
});
return false;
}
if(record.equipmentCategory == '10'){
total = (record.batteryPrice).toFixed(2)
}
if(record.equipmentCategory == '20'){
total = (record.downPayment).toFixed(2)
}
if(record.equipmentCategory == '40' || record.equipmentCategory == '30'){
total = (record.batteryDeposit + record.batteryRent + record.batteryInsurance).toFixed(2)
}
const testTotal = 0.01
var time = new Date().getTime() + 60*60*1000*24
const expirationTime = dateFormat('YYYY-mm-dd HH:MM:SS', new Date(time))
app.expirationTime = expirationTime
addOrder({
orderNo: createOrderNo(),
merchantCode: record.merchantCode,
goodsId: app.goodsId,
totalPrice: total,
orderPrice: total,
payPrice: total,
month: app.month,
expirationTime: expirationTime,
batteryRent: record.batteryRent,
batteryDeposit: record.batteryDeposit,
batteryInsurance: record.batteryInsurance,
orderSource: record.equipmentCategory,
orderSourceId: record.goodsId,
dealerId
}).then(res => {
const { orderId } = res.data
app.$success("下单成功")
setTimeout(() => {
this.$navTo('pages/checkout/cashier/index', { orderId })
}, 100)
})
}
}
}
</script>
<style lang="scss" scoped>
.goods-info {
background-color: #ffffff;
border-radius: 12rpx;
width: 700rpx;
margin: 20rpx auto;
.goods {
padding: 20rpx;
display: flex;
image {
width: 220rpx;
height: 220rpx;
margin: 20rpx;
}
.info {
display: flex;
flex-direction: column;
padding: 20rpx;
.goods-name {
font-size: 34rpx;
margin-bottom: 10rpx;
}
.goods-desc {
font-size: 28rpx;
color: #999999;
}
.selling-point{
padding: 5px 0;
color: #e6760e;
}
}
}
.between-time {
width: 500rpx;
margin: auto;
padding-bottom: 20rpx;
text-align: center;
.select-slider {
line-height: 2em;
color: #e6760e;
}
}
}
.order {
background-color: #ffffff;
border-radius: 12rpx;
width: 700rpx;
margin: 20rpx auto;
padding: 10rpx 0;
.title {
font-weight: bold;
font-size: 30rpx;
padding: 20rpx;
display: flex;
justify-content: space-between;
}
.xieyi {
padding: 20rpx;
font-size: 26rpx;
}
}
.submit {
border-radius: 12rpx;
width: 700rpx;
margin: 20rpx auto;
padding: 10rpx 0;
}
.xieyi-text{
color: #0000ff;
}
.fenqi{
padding: 30rpx;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
.item{
display: flex;
justify-content: space-between;
padding: 20rpx 0;
}
}
</style>

601
pages/checkout/index.vue Executable file
View File

@@ -0,0 +1,601 @@
<template>
<view class="container p-bottom" :style="appThemeStyle">
<view v-if="order.goodsList.length">
<!-- 实物订单选择配送方式 -->
<block v-if="order.orderType == OrderTypeEnum.PHYSICAL.value">
<!-- 配送方式选项卡 -->
<view v-if="isShowTab" class="swiper-tab dis-flex flex-y-center flex-x-around">
<view class="swiper-tab-item" :class="{ on: curDelivery == DeliveryTypeEnum.EXPRESS.value }"
@click="handleSwichDelivery(DeliveryTypeEnum.EXPRESS.value)">
<text>快递配送</text>
</view>
<view class="swiper-tab-item" :class="{ on: curDelivery == DeliveryTypeEnum.EXTRACT.value }"
@click="handleSwichDelivery(DeliveryTypeEnum.EXTRACT.value)">
<text>上门自提</text>
</view>
</view>
<!-- 快递配送配送地址 -->
<view v-if="curDelivery == DeliveryTypeEnum.EXPRESS.value" @click="onSelectAddress" class="flow-delivery">
<view class="flow-delivery__detail dis-flex flex-y-center">
<view class="detail-location dis-flex">
<text class="iconfont icon-dingwei"></text>
</view>
<view class="detail-content flex-box">
<block v-if="order.address">
<view class="detail-content__title dis-flex">
<text class="f-30">{{ order.address.name }}</text>
<text class="detail-content__title-phone f-28">{{ order.address.phone }}</text>
</view>
<view class="address detail-content__describe">
<text class="region" v-for="(region, idx) in order.address.region" :key="idx">{{ region }}</text>
<text class="detail">{{ order.address.detail }}</text>
</view>
</block>
<block v-else>
<view class="detail-content__describe dis-flex">
<text class="col-6">请选择配送地址</text>
</view>
</block>
</view>
<view class="detail-arrow dis-flex">
<text class="iconfont icon-arrow-right"></text>
</view>
</view>
</view>
<!-- 上门自提自提门店 -->
<block v-if="curDelivery == DeliveryTypeEnum.EXTRACT.value">
<view class="flow-delivery" @click="onSelectExtractPoint()">
<view class="flow-delivery__detail dis-flex flex-y-center">
<view class="detail-location dis-flex">
<text class="iconfont icon-dingwei"></text>
</view>
<view class="detail-content flex-box">
<block v-if="order.extractShop.shop_id">
<view class="detail-content__title dis-flex">
<text class="f-30">{{ order.extractShop.shop_name }}</text>
</view>
<view class="detail-content__describe">
<text class="col-7">{{ order.extractShop.region.province }} {{ order.extractShop.region.city }}</text>
<text class="col-7">{{ order.extractShop.region.region }} {{ order.extractShop.address }}</text>
</view>
</block>
<block v-else>
<view class="detail-content__describe dis-flex">
<text class="col-6">请选择自提点</text>
</view>
</block>
</view>
<view class="detail-arrow dis-flex">
<text class="iconfont icon-arrow-right user-orderJtou"></text>
</view>
</view>
</view>
<!-- 自提联系方式 -->
<view class="flow-extract-contact b-f">
<view class="contact-item dis-flex">
<view class="item_label dis-flex flex-x-end flex-y-center">
<text>联系人</text>
</view>
<view class="item_ipt flex-box dis-flex flex-y-center">
<input placeholder="请填写联系人姓名" v-model="linkman"></input>
</view>
</view>
<view class="contact-item dis-flex">
<view class="item_label dis-flex flex-x-end flex-y-center">
<text>联系电话</text>
</view>
<view class="item_ipt flex-box dis-flex flex-y-center">
<input placeholder="请填写联系电话" v-model="phone"></input>
</view>
</view>
</view>
</block>
</block>
<!-- 商品列表 -->
<view class="checkout_list" v-for="(item, index) in order.goodsList" :key="index">
<view class="flow-shopList dis-flex" data-index="index" @click="onTargetGoods(item.goods_id)">
<!-- 商品图片 -->
<view class="flow-list-left">
<image mode="scaleToFill" :src="item.goods_image"></image>
</view>
<view class="flow-list-right flex-box">
<!-- 商品名称 -->
<text class="goods-name twoline-hide">{{ item.goods_name }}</text>
<!-- 商品规格 -->
<view class="goods-props clearfix">
<view class="goods-props-item" v-for="(props, idx) in item.skuInfo.goods_props" :key="idx">
<text class="group-name">{{ props.group.name }}: </text>
<text>{{ props.value.name }}</text>
</view>
</view>
<!-- 商品数量和单价 -->
<view class="flow-list-cont dis-flex flex-x-between flex-y-center">
<text class="small">×{{ item.total_num }}</text>
<text class="flow-cont" :class="[item.is_user_grade ? 'price-delete' : '']">{{ item.goods_price }}</text>
</view>
<!-- 会员折扣价 -->
<view v-if="item.is_user_grade" class="grade-price">
<text>会员折扣价{{ item.grade_goods_price }}</text>
</view>
</view>
</view>
</view>
<view class="flow-num-box b-f">
<!-- <text>{{ order.orderTotalNum }}件商品合计</text>
<text class="flow-money col-m">{{ order.orderTotalPrice }}</text> -->
<text>{{ order.orderTotalNum }}件商品</text>
</view>
<!-- 商品金额 -->
<view class="flow-all-money b-f m-top20">
<view class="flow-all-list dis-flex">
<text class="flex-five">订单总金额</text>
<view class="flex-five t-r">
<text class="col-m">{{ order.orderTotalPrice }}</text>
</view>
</view>
<!-- 优惠券 -->
<view class="flow-all-list dis-flex">
<text class="flex-five">优惠券</text>
<view class="flex-five t-r">
<view v-if="order.couponList.length > 0" @click="handleShowPopup()">
<text class="col-m" v-if="order.couponId > 0">-{{ order.couponMoney }}</text>
<text class="col-m" v-else>{{ order.couponList.length }}张优惠券</text>
<text class="right-arrow iconfont icon-arrow-right"></text>
</view>
<text v-else class="">无优惠券可用</text>
</view>
</view>
<!-- 积分抵扣 -->
<view v-if="order.isAllowPoints" class="points flow-all-list dis-flex flex-y-center">
<view class="block-left flex-five" @click="handleShowPoints()">
<text class="title">可用{{ setting.points_name }}抵扣</text>
<text class="iconfont icon-help"></text>
</view>
<view class="flex-five dis-flex flex-x-end flex-y-center">
<text class="points-money col-m">-{{ order.pointsMoney }}</text>
<u-switch v-model="isUsePoints" size="48" active-color="#07c160" @change="getOrderData()"></u-switch>
</view>
</view>
<!-- 配送费用 -->
<view v-if="curDelivery == DeliveryTypeEnum.EXPRESS.value" class="dis-flex flow-all-list">
<text class="flex-five">配送费用</text>
<view class="flex-five t-r">
<view v-if="order.address">
<text class="col-m" v-if="order.isIntraRegion">+{{ order.expressPrice }}</text>
<text v-else>不在配送范围</text>
</view>
<view v-else>
<text class="col-7">请先选择配送地址</text>
</view>
</view>
</view>
</view>
<!-- 买家留言 -->
<view class="flow-all-money b-f m-top20">
<view class="ipt-wrapper dis-flex flow-all-list">
<input v-model="remark" placeholder="选填买家留言50字以内"></input>
</view>
</view>
<!-- 提交订单 -->
<view class="flow-fixed-footer b-f m-top10">
<view class="dis-flex chackout-box">
<view class="chackout-left pl-12">实付款
<text class="col-m">{{ order.orderPayPrice }}</text>
</view>
<view class="chackout-right" @click="onSubmitOrder()">
<view class="flow-btn f-32" :class="{ disabled }">提交订单</view>
</view>
</view>
</view>
<!-- 积分说明弹窗 -->
<u-modal v-model="showPoints" :title="`${setting.points_name}说明`">
<scroll-view class="points-content" :scroll-y="true">
<text>{{ setting.points_describe }}</text>
</scroll-view>
</u-modal>
<!-- 优惠券弹出框 -->
<u-popup v-model="showPopup" mode="bottom">
<view class="popup__coupon">
<view class="coupon__title f-30">选择优惠券</view>
<!-- 优惠券列表 -->
<view class="coupon-list">
<scroll-view :scroll-y="true" style="height: 565rpx;">
<view class="coupon-item" v-for="(item, index) in order.couponList" :key="index">
<view class="item-wrapper" :class="[item.is_apply ? 'color-' + CouponColors[index % CouponColors.length] : 'color-gray']"
@click="handleSelectCoupon(index)">
<view class="coupon-type">{{ CouponTypeEnum[item.coupon_type].name }}</view>
<view class="tip dis-flex flex-dir-column flex-x-center">
<view v-if="item.coupon_type == CouponTypeEnum.FULL_DISCOUNT.value">
<text class="f-30"></text>
<text class="money">{{ item.reduce_price }}</text>
</view>
<text class="money" v-if="item.coupon_type == CouponTypeEnum.DISCOUNT.value">{{ item.discount }}</text>
<text class="pay-line">{{ item.min_price }}元可用</text>
</view>
<view class="split-line"></view>
<view class="content dis-flex flex-dir-column flex-x-between">
<view class="title">{{ item.name }}</view>
<view class="bottom dis-flex flex-y-center">
<view class="time flex-box">
<block v-if="item.start_time === item.end_time">{{ item.start_time }} 当天有效</block>
<block v-else>{{ item.start_time }}~{{ item.end_time }}</block>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 不使用优惠券 -->
<view class="coupon__do_not dis-flex flex-y-center flex-x-center">
<view class="control dis-flex flex-y-center flex-x-center" @click="handleNotUseCoupon()">
<text class="f-26">不使用优惠券</text>
</view>
</view>
</view>
</u-popup>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
import * as Verify from '@/utils/verify'
import * as CheckoutApi from '@/api/checkout'
import * as SharpCheckoutApi from '@/api/sharp/checkout'
import * as BargainCheckoutApi from '@/api/bargain/checkout'
import * as GrouponCheckoutApi from '@/api/groupon/checkout'
import { CouponTypeEnum } from '@/common/enum/coupon'
import { OrderTypeEnum, DeliveryTypeEnum } from '@/common/enum/order'
const CouponColors = ['red', 'blue', 'violet', 'yellow']
// 根据指定mode获取对应的api类
const getCheckoutApi = (mode) => {
const apiEnum = {
buyNow: CheckoutApi,
cart: CheckoutApi,
bargain: BargainCheckoutApi,
sharp: SharpCheckoutApi,
groupon: GrouponCheckoutApi
}
return apiEnum[mode]
}
// 根据指定mode获取param
const getModeParam = (mode, options) => {
const param = {}
// 结算模式: 立即购买
if (mode === 'buyNow') {
param.goodsId = options.goodsId
param.goodsNum = options.goodsNum
param.goodsSkuId = options.goodsSkuId
}
// 结算模式: 购物车
if (mode === 'cart') {
param.cartIds = options.cartIds
}
// 结算模式: 砍价活动
if (mode === 'bargain') {
param.taskId = options.taskId
param.goodsSkuId = options.goodsSkuId
}
// 结算模式: 整点秒杀
if (mode === 'sharp') {
param.activeTimeId = options.activeTimeId
param.sharpGoodsId = options.sharpGoodsId
param.goodsSkuId = options.goodsSkuId
param.goodsNum = options.goodsNum
}
// 结算模式: 多人拼团
if (mode === 'groupon') {
param.grouponGoodsId = options.grouponGoodsId
param.taskId = options.taskId
param.goodsSkuId = options.goodsSkuId
param.goodsNum = options.goodsNum
param.stepPeople = options.stepPeople
}
return param
}
export default {
data() {
return {
// 枚举类
OrderTypeEnum,
DeliveryTypeEnum,
CouponTypeEnum,
// 当前页面参数
options: {},
// 配送方式
isShowTab: false,
DeliveryTypeEnum,
curDelivery: null,
// 自提信息
selectedShopId: 0, // 选择的门店ID
linkman: '', // 自提联系人
phone: '', // 自提联系电话
// 优惠券颜色组
CouponColors,
// 选择的优惠券
selectCouponId: 0,
// 是否使用积分抵扣
isUsePoints: false,
// 买家留言
remark: '',
// 禁用submit按钮
disabled: false,
// 是否显示积分说明
showPoints: false,
// 是否显示优惠券弹窗
showPopup: false,
// 订单信息 (从后端api中获取)
order: {
// 商品列表
goodsList: [],
// 优惠券列表
couponList: [],
// 是否存在收货地址
existAddress: false,
// 默认收货地址
address: null,
// 是否存在收货地址
existAddress: false,
// 当前用户收货城市是否存在配送规则中
isIntraRegion: true,
// 是否存在错误
hasError: false,
// 错误信息
errorMsg: '',
},
// 个人信息
personal: {},
// 商城设置
setting: {}
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.options = options
// 注册全局事件订阅: 选择自提门店
uni.$on('syncSelectedId', selectedId => {
this.selectedShopId = selectedId
})
},
/**
* 生命周期函数--监听页面的卸载
*/
onUnload() {
// 卸载全局事件订阅: 选择自提门店
uni.$off('syncSelectedId')
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
// 获取当前订单信息
this.getOrderData()
},
methods: {
// 获取订单数据
getOrderData() {
const app = this
const { options: { mode } } = app
// 请求的参数
const params = app.getRequestParam()
// 请求api
getCheckoutApi(mode)
.order(mode, params)
.then(result => app.initData(result.data))
.catch(err => err)
},
// 初始化数据
initData({ order, setting, personal }) {
const app = this
app.order = order
app.personal = personal
app.setting = setting
// 显示错误信息
if (order.hasError) {
app.showToast(order.errorMsg, 3000)
}
// 当前选择的配送方式
app.curDelivery = order.delivery
// 如果只有一种配送方式则不显示选项卡
app.isShowTab = setting.deliveryType.length > 1
// 上门自提联系信息
if (app.linkman === '') {
app.linkman = order.lastExtract.linkman
}
if (app.phone === '') {
app.phone = order.lastExtract.phone
}
},
// 获取api请求的参数
getRequestParam() {
const app = this
const { options } = app
// 结算模式的固定参数
const modeParam = getModeParam(options.mode, options)
// 订单结算参数(用户选择)
const orderParam = {
delivery: app.curDelivery || 0,
shopId: app.selectedShopId || 0,
couponId: app.selectCouponId || 0,
isUsePoints: app.isUsePoints ? 1 : 0,
}
return { ...orderParam, ...modeParam }
},
// 切换配送方式
handleSwichDelivery(key) {
this.curDelivery = key
this.getOrderData()
},
// 显示积分说明
handleShowPoints() {
this.showPoints = true
},
// 显示优惠券弹窗
handleShowPopup() {
this.showPopup = true
},
// 选择优惠券
handleSelectCoupon(index) {
const app = this
const { couponList } = app.order
// 当前选择的优惠券
const couponItem = couponList[index]
// 判断是否在适用范围
if (!couponItem.is_apply) {
app.showToast(couponItem.not_apply_info)
return
}
// 记录选中的优惠券id
app.selectCouponId = couponItem.user_coupon_id
// 重新获取订单信息
app.getOrderData()
// 隐藏优惠券弹层
app.showPopup = false
},
// 不使用优惠券
handleNotUseCoupon() {
const app = this
app.selectCouponId = 0
// 重新获取订单信息
app.getOrderData()
// 隐藏优惠券弹层
app.showPopup = false
},
// 快递配送:选择收货地址
onSelectAddress() {
this.$navTo('pages/address/index', { from: 'checkout' })
},
// 上门自提:选择自提点
onSelectExtractPoint() {
this.$navTo('pages/shop/extract', { selectedId: this.selectedShopId })
},
// 跳转到商品详情页
onTargetGoods(goodsId) {
this.$navTo('pages/goods/detail', { goodsId })
},
// 订单提交
onSubmitOrder() {
const app = this
if (app.disabled) {
return false
}
// 表单验证
if (!app.onVerifyFrom()) {
return false
}
// 按钮禁用
app.disabled = true
// 请求api
getCheckoutApi(app.options.mode)
.submit(app.options.mode, app.getFormData())
.then(result => {
// 订单创建成功: 跳转到订单支付页
const orderId = result.data.orderId
setTimeout(() => {
this.$navTo('pages/checkout/cashier/index', { orderId }, 'redirectTo')
}, 100)
})
.catch(res => app.showToast(res.errMsg, 3000))
.finally(() => setTimeout(() => app.disabled = false, 800))
},
// 跳转到我的订单(等待1秒)
navToMyOrder() {
setTimeout(() => {
this.$navTo('pages/order/index', {}, 'redirectTo')
}, 1000)
},
// 表单提交的数据
getFormData() {
const app = this
const { options } = app
// 表单数据
const form = {
delivery: app.curDelivery,
couponId: app.selectCouponId || 0,
shopId: app.selectedShopId || 0,
linkman: app.linkman,
phone: app.phone,
isUsePoints: app.isUsePoints ? 1 : 0,
remark: app.remark || '',
}
// 获取不同模式的参数
const modeParam = getModeParam(options.mode, options)
return { ...form, ...modeParam }
},
// 表单验证
onVerifyFrom() {
const app = this
if (app.hasError) {
app.showToast(app.errorMsg, 3000)
return false
}
// 验证自提填写的联系方式
if (app.curDelivery == DeliveryTypeEnum.EXTRACT.value) {
app.linkman = app.linkman.trim()
app.phone = app.phone.trim()
if (app.selectedShopId <= 0) {
app.showToast('请选择自提的门店')
return false
}
if (Verify.isEmpty(app.linkman)) {
app.showToast('请填写自提联系人')
return false
}
if (Verify.isEmpty(app.phone)) {
app.showToast('请填写自提联系电话')
return false
}
if (!Verify.isPhone(app.phone)) {
app.showToast('请输入正确的联系电话')
return false
}
}
return true
},
// 显示toast信息
showToast(title, duration = 2000) {
this.$refs.uToast.show({ title, duration })
}
}
}
</script>
<style lang="scss" scoped>
@import "./style.scss";
</style>

475
pages/checkout/style.scss Executable file
View File

@@ -0,0 +1,475 @@
// 配送信息
.flow-delivery {
padding: 34rpx 30rpx;
background: #fff url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANYAAAANCAYAAADVGpDCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3Yjk4M2ExYy1jMDhkLTQ1OTktYTI0Ny1kZjNjYzdiYTQ5ZTgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDQwNkY3RkU5N0NGMTFFNUI3N0M4NTU4MzM2RjlFODIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDQwNkY3RkQ5N0NGMTFFNUI3N0M4NTU4MzM2RjlFODIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNzgwZWI1NS03OGFhLTQzOTUtODQ4OC1lOWI5YmVlYTY1ZDciIHN0UmVmOmRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo1OTRiYzUyMy1jMzc3LTExNzgtYTdkZS04NGY3YmM1ZGIxMDMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz556PLxAAACBElEQVR42tyaSyhEYRTHP48imlKibDQeSSlkSlEWLCRFsZNH5FE2FqQ8ErIRC9lIkTwXSpMkWWChhEJCSnlkoUZGSsr78f98n43CMFPu/Z/6NZuZ2zn33/+cb869XkmLx8IDEQaGQJbgiytQDSY3MyL+LYnL/HxPXSoHDIJQQq2WQQk4Dbbb/yUB29LJ+6e3B66VB3ZITbUIEqSpCGoJBP1ghtBUD6ARpEtTGSEhXzd+awE9oJzQUPegWdf3QlBPMhgDMYRa7YNisGWkpP5qrBQtVBShUHugUE9hs4fUtwG0utlEjRivoA/Ug1sj3vjffr8FNJEK1auPFHcE9UTq5pdK2PwcoAzMG7mjuRrRYEIfK9jiDJSCBZJ6ynSTsBBqNQ0qgdPISbq6vJCFbJOaagrEk5gqWNczRGiqG1Ah1LLMafRkf5pYIUKtZnMJDXUNasAIST2ZYFioRx9ssQaKwJFZEv5uYmWDXVJTrYBEElP562PfPKGpnkAbSDOTqb6aWAGgW6iHol5kQj2CdtAJngnqkc1hHMQRNr9DPaXWzZj8Z2PZtFCxhEIdaKE2CGqRJ4060AH8CLUaALX6f5VpBZLhI9SaeZXQVHKNLt84SCIxVbhQi5YuQlNd6OVElZlN9TGxrGBUn2PZ4lyoTdIsST0FQj0UDSLUak6ot3gcBLVY3wQYAJoVXxmNERajAAAAAElFTkSuQmCC') bottom left repeat-x;
background-size: 120rpx auto;
margin-bottom: 25rpx;
.detail-location {
font-size: 36rpx;
}
.detail-content {
padding: 0 20rpx;
.detail-content__title-phone {
margin-left: 10rpx;
}
.detail-content__describe {
font-size: 28rpx;
color: #777;
}
}
.detail-content__title {
margin-bottom: 6rpx;
}
}
// 买家留言
.flow-all-money {
.ipt-wrapper {
input {
font-size: 28rpx;
width: 100%;
height: 75rpx;
}
}
}
// 商品列表
.checkout_list {
padding: 20rpx 30rpx 4rpx 30rpx;
background: #fff;
border-bottom: 1rpx solid rgb(248, 248, 248);
.flow-shopList {
padding: 5rpx 0 10rpx;
border-bottom: 1rpx solid rgb(248, 248, 248);
&:last-child {
border-bottom: 0;
}
}
}
.flow-header-left {
padding-left: 90rpx;
}
/* 会员价 */
.flow-shopList {
.flow-list-right {
.flow-cont {
&.price-delete {
font-size: 26rpx;
color: #777;
text-decoration: line-through;
}
}
}
.grade-price {
padding-top: 8rpx;
font-size: 28rpx;
color: $main-bg;
text-align: right;
}
.goods-name{
font-size: 28rpx;
color: #333;
}
}
/* 优惠券选择 */
.popup__coupon {
background: #fff;
box-sizing: border-box;
padding: 30rpx;
.coupon__do_not {
.control {
width: 90%;
height: 72rpx;
color: #888;
border: 1rpx solid #e3e3e3;
border-radius: 10rpx;
}
}
.coupon__title {
text-align: center;
margin-bottom: 30rpx;
}
.coupon-list {
/* #ifdef H5 */
max-width: 1120rpx;
margin: 0 auto;
/* #endif */
margin-bottom: 24rpx;
}
.coupon-item {
overflow: hidden;
margin-bottom: 22rpx;
}
.item-wrapper {
width: 100%;
display: flex;
background: #fff;
border-radius: 8rpx;
color: #fff;
height: 180rpx;
.coupon-type {
position: absolute;
top: 0;
right: 0;
z-index: 10;
width: 128rpx;
padding: 6rpx 0;
background: #a771ff;
font-size: 20rpx;
text-align: center;
color: #ffffff;
transform: rotate(45deg);
transform-origin: 64rpx 64rpx;
}
&.color-blue {
background: linear-gradient(-125deg, #57bdbf, #2f9de2);
}
&.color-red {
background: linear-gradient(-128deg, #ff6d6d, #ff3636);
}
&.color-violet {
background: linear-gradient(-113deg, #ef86ff, #b66ff5);
.coupon-type {
background: #55b5ff;
}
}
&.color-yellow {
background: linear-gradient(-141deg, #f7d059, #fdb054);
}
&.color-gray {
background: linear-gradient(-113deg, #bdbdbd, #a2a1a2);
.coupon-type {
background: #9e9e9e;
}
}
.content {
flex: 1;
padding: 30rpx 20rpx;
border-radius: 16rpx 0 0 16rpx;
.title {
font-size: 32rpx;
}
.bottom {
.time {
font-size: 24rpx;
}
.receive {
height: 46rpx;
width: 122rpx;
border: 1rpx solid #fff;
border-radius: 30rpx;
color: #fff;
font-size: 24rpx;
display: flex;
justify-content: center;
align-items: center;
&.state {
border: none;
}
}
}
}
.tip {
position: relative;
flex: 0 0 32%;
text-align: center;
border-radius: 0 16rpx 16rpx 0;
.money {
font-weight: bold;
font-size: 52rpx;
}
.pay-line {
font-size: 22rpx;
}
}
.split-line {
position: relative;
flex: 0 0 0;
border-left: 4rpx solid #fff;
margin: 0 10rpx 0 6rpx;
background: #fff;
&:before,
{
border-radius: 0 0 16rpx 16rpx;
top: 0;
}
&:after {
border-radius: 16rpx 16rpx 0 0;
bottom: 0;
}
&:before,
&:after {
content: '';
position: absolute;
width: 24rpx;
height: 12rpx;
background: #f7f7f7;
left: -14rpx;
z-index: 1;
}
}
}
}
/* 积分抵扣 */
.points {
.title {
margin-right: 5rpx;
}
.icon-help {
font-size: 28rpx;
}
.points-money {
margin-right: 20rpx;
}
}
// 商品规格
.goods-props {
padding-top: 10rpx;
font-size: 24rpx;
color: #999;
.goods-props-item {
float: left;
.group-name {
margin-right: 6rpx;
}
}
}
// 右侧箭头
.right-arrow {
margin-left: 16rpx;
// color: #777;
font-size: 26rpx;
}
// 底部操作栏
.flow-fixed-footer {
position: fixed;
bottom: var(--window-bottom);
left: var(--window-left);
right: var(--window-right);
// width: 100%;
background: #fff;
border-top: 1px solid #eee;
z-index: 11;
// 设置ios刘海屏底部横线安全区域
padding-bottom: calc(constant(safe-area-inset-bottom) + var(--window-bottom));
padding-bottom: calc(env(safe-area-inset-bottom) + var(--window-bottom));
.chackout-left {
font-size: 28rpx;
line-height: 92rpx;
color: #777;
flex: 4;
padding-left: 12px;
}
.chackout-right {
font-size: 34rpx;
flex: 2;
}
// 提交按钮
.flow-btn {
background: linear-gradient(to right, $main-bg, $main-bg2);
color: $main-text;
text-align: center;
line-height: 92rpx;
display: block;
font-size: 28rpx;
// 禁用按钮
&.disabled {
opacity: 0.6;
}
}
}
// 积分说明
.points-content {
padding: 30rpx 48rpx;
font-size: 28rpx;
line-height: 50rpx;
text-align: left;
color: #606266;
height: 620rpx;
box-sizing: border-box;
}
/* 共几件商品 */
.flow-num-box {
font-size: 28rpx;
color: #777;
padding: 16rpx 24rpx;
text-align: right;
}
/* app.scss */
.flow-shopList {
padding: 18rpx 0;
.flow-list-left {
margin-right: 20rpx;
image {
width: 180rpx;
height: 180rpx;
border: 1rpx solid #eee;
background: #fff;
}
}
.flow-list-right {
.flow-cont {
font-size: 28rpx;
color: $main-bg;
}
.small {
font-size: 26rpx;
color: #777;
}
.flow-list-cont {
padding-top: 10rpx;
}
}
}
.flow-all-money {
padding: 0 24rpx;
color: #444;
.flow-all-list {
font-size: 28rpx;
padding: 20rpx 0;
border-bottom: 1rpx solid rgb(248, 248, 248);
}
.flow-all-list:last-child {
border-bottom: none;
}
.flow-all-list-cont {
font-size: 28rpx;
padding: 10rpx 0;
}
.flow-arrow {
justify-content: flex-end;
align-items: center;
}
}
// 选项卡:配送方式
.swiper-tab {
width: 100%;
text-align: center;
height: 85rpx;
background-color: #fff;
border-bottom: 1px solid rgb(248, 248, 248);
display: flex;
align-items: center;
justify-content: space-around;
.swiper-tab-item {
width: 35%;
height: 100%;
font-size: 28rpx;
color: #777;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-bottom: 2px solid #ffffff00;
&.on {
color: $main-bg;
border-bottom: 2px solid $main-bg;
}
}
}
// 门店自提联系人
.flow-extract-contact {
padding: 8rpx 24rpx;
font-size: 28rpx;
color: #444;
margin-bottom: 25rpx;
.contact-item {
padding: 20rpx 0;
border-bottom: 1rpx solid rgb(248, 248, 248);
&:last-child {
border-bottom: none;
}
}
.item_label {
margin-right: 26rpx;
width: 150rpx;
}
.item_ipt input {
font-size: 28rpx;
width: 100%;
.input-placeholder {
font-size: 28rpx;
}
}
}