Files
gxtyzx-uniapp/src/pages/order.vue
T
2025-01-08 09:44:25 +08:00

713 lines
24 KiB
Vue

<template>
<view>
<!-- <view class="segmented">-->
<!-- <uni-segmented-control :current="current" :values="items" :styleType="styleType" :activeColor="activeColor"-->
<!-- inActiveColor="#808080" @clickItem="onClickItem"/>-->
<!-- </view>-->
<uv-sticky title="订单" bg-color="white">
<view class="w-100p" :style="{height: `${safeTop}px`}"></view>
<view v-if="hasMerchantRole || hasMerchantClerkRole || hasSuperAdminRole"
class="px-20 pb-20 flex justify-center items-center" style="width: calc(100vw - 250rpx)">
<uv-input v-model="orderNo" shape="circle" clearable placeholder="订单号搜索"
:customStyle="{backgroundColor: 'white'}" @change="reload"/>
</view>
<view class="flex justify-center items-center p-10" style="width: calc(100vw - 220rpx); height: 40px">
<view class="flex-2 mx-15 flex justify-center" @click="openOrderTypePicker">
<uv-icon name="arrow-down" :label="orderTypeStr" label-pos="left"/>
</view>
<view class="flex-2 mx-15 flex justify-center" @click="openOrderStatusPicker" v-if="orderType !== 2">
<uv-icon name="arrow-down" :label="orderStatusStr" label-pos="left"/>
</view>
<view class="flex-1 mx-15 flex justify-center" @click="reset">
<text class="text-24 text-blue">重置</text>
</view>
</view>
</uv-sticky>
<view class="order">
<block v-if="orderList.length > 0">
<template v-if="orderType === 2">
<view v-for="(item, index) in orderList" class="card m-20" :key="index">
<view class="pb-20 border-bottom flex justify-between items-center text-25">
<text>{{ item.orderNum }}</text>
<text v-if="item.status === 0">未支付</text>
<text v-if="item.status === 1" class="text-red">已支付,未退款</text>
<text v-if="item.status === 2" class="text-green">已退款</text>
</view>
<view class="py-20 border-bottom flex justify-between items-center text-25">
<text>{{ item.siteName }}-{{ item.info }}</text>
<text class="text-red font-bold">¥{{ item.money }}</text>
</view>
<view class="py-20 flex justify-start items-center text-25 text-gray">
<text>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}</text>
</view>
</view>
</template>
<template v-else>
<block v-for="(item,index) in orderList" :key="index">
<uni-card :border="false" :is-shadow="false" :padding="0">
<template v-slot:title>
<div class="order-title web-cell">
<view class="web-cell web-cell-content">
<text class="merchant-name">订单号: {{ item.orderNum }}</text>
</view>
<view class="web-cell web-cell-content flex justify-between items-center" v-if="orderType === 1">
<text class="merchant-name">{{ item.siteNames }}</text>
<text class="text-25 text-red" v-if="item.status === 2">待支付</text>
<text class="text-25 text-green" v-else-if="item.status === 1">已支付</text>
<text class="text-25 text-gray" v-else-if="item.status === 3">已退款</text>
<text class="text-25 text-gray" v-else-if="item.status === 0">已取消</text>
</view>
<block v-if="item.orderStatus === 3">
<text class="btn-status web-text-secondary">已取消</text>
</block>
<block v-else-if="item.orderStatus === 1">
<text class="btn-status web-text-success">已完成</text>
</block>
<block v-else>
<text v-if="item.payStatus === 1" class="btn-status web-text-success">已支付</text>
<view v-if="item.payStatus === 0" class="btn-status web-text-danger">
<uv-count-down :time="item.timestamp" format="mm:ss"></uv-count-down>
<text class="no-pay" style="margin-left: 10rpx;">未支付</text>
</view>
</block>
</div>
</template>
<view class="order-body web-cell web-cell-align-top">
<view class="web-cell-content" @click="toDetail(item.id)">
<uv-cell-group :customStyle="{backgroundColor: '#ffffff'}" :border="false" v-if="orderType === 0">
<block v-for="(sub,subIndex) in item.thinkOrderInfos" :key="subIndex">
<uv-cell :title="`${item.siteName} - ${sub.fieldName}`" :label="`${sub.dateTime}`"
:cellStyle="{padding: '0', paddingBottom: '5px'}" :border="false"/>
</block>
</uv-cell-group>
<uv-cell-group :customStyle="{backgroundColor: '#ffffff'}" :border="false"
v-else-if="orderType === 1">
<uv-cell :title="item.name"
:cellStyle="{padding: '0', paddingBottom: '5px'}" :border="false">
</uv-cell>
</uv-cell-group>
<view class="total-price" v-if="orderType === 0">
<view class="web-text-heading">合计:¥{{ item.totalPrice }}</view>
</view>
<view class="total-price" v-else-if="orderType === 1">
<view class="web-text-heading">合计:¥{{ item.price }}</view>
</view>
</view>
</view>
<view slot="actions" class="card-actions">
<template v-if="orderType === 0">
<view class="card-actions-item" v-if="item.payStatus === 2 && item.orderStatus === 2">
<button class="mini-btn" size="mini" @click="closeOrder(item)"
style="margin-right: 20rpx;">取消订单
</button>
<button class="mini-btn" type="primary" size="mini"
@click="openPayOrder(item.id)">立即支付
</button>
</view>
<view class="card-actions-item" v-if="item.payStatus === 1">
<button class="mini-btn mx-10" size="mini" v-if="item.orderStatus === 4">
退款中
</button>
<button class="mini-btn mx-10" size="mini" v-if="item.orderStatus === 6">
{{ item.payType === 1 ? '退款成功' : '已取消' }}
</button>
<button class="mini-btn mx-10" size="mini"
v-if="item.orderStatus === 2 && item.canRefund"
@click="refund(item, index)" :disabled="item.disabled">
{{ item.payType === 1 ? '申请退款' : '取消订单' }}
</button>
<button class="mini-btn mx-10" size="mini" v-if="item.orderStatus === 2" @click="toDetail(item.id)">
核销码
</button>
<button class="mini-btn mx-10" size="mini" v-if="item.canInvoice" @click="onInvoice(item)">
申请开票
</button>
<button class="mini-btn mx-10" size="mini" v-else-if="item.isInvoice === 1"
@click="showInvoice(item.id)">
查看发票
</button>
</view>
</template>
<template v-else-if="orderType === 1">
<view class="card-actions-item" v-if="item.payStatus === 2">
<button class="mini-btn" size="mini" @click="closeVipOrder(item)"
style="margin-right: 20rpx;">取消订单
</button>
<button class="mini-btn" type="primary" size="mini"
@click="openPay(item.id)">立即支付
</button>
</view>
<view class="card-actions-item" v-if="item.status === 1">
<button class="mini-btn" size="mini" v-if="item.isInvoice === 2" @click="onInvoice(item)">
申请开票
</button>
<button class="mini-btn" size="mini" v-else-if="item.isInvoice === 1" @click="showInvoice(item.id)">
查看发票
</button>
</view>
</template>
</view>
</uni-card>
</block>
</template>
</block>
<!-- <block v-if="orderList.length === 0 && loadMore != 'no-more'">-->
<!-- <uni-card :border="false" :padding="'18px 6px'">-->
<!-- <uv-skeleton rows="3" avatar :loading="hideTools" :title="false">-->
<!-- </uv-skeleton>-->
<!-- <uv-gap height="16"></uv-gap>-->
<!-- </uni-card>-->
<!-- <uni-card :border="false" :padding="'18px 6px'">-->
<!-- <uv-skeleton rows="3" avatar :loading="hideTools" :title="false">-->
<!-- </uv-skeleton>-->
<!-- <uv-gap height="16"></uv-gap>-->
<!-- </uni-card>-->
<!-- <uni-card :border="false" :padding="'18px 6px'">-->
<!-- <uv-skeleton rows="3" avatar :loading="hideTools" :title="false">-->
<!-- </uv-skeleton>-->
<!-- <uv-gap height="16"></uv-gap>-->
<!-- </uni-card>-->
<!-- <uni-card :border="false" :padding="'18px 6px'">-->
<!-- <uv-skeleton rows="3" avatar :loading="hideTools" :title="false">-->
<!-- </uv-skeleton>-->
<!-- <uv-gap height="16"></uv-gap>-->
<!-- </uni-card>-->
<!-- </block>-->
<uv-empty :show="orderList.length === 0" mode="order" class="none"
icon="https://cdn.uviewui.com/uview/empty/car.png"></uv-empty>
<uni-load-more v-if="orderList.length > 0" :status="loadMore"></uni-load-more>
<!-- 登录组件 -->
<ws-login ref="login" :logo="logo" @done="reload"/>
</view>
<uv-picker ref="orderTypePicker" :columns="[orderTypeList]" keyName="label" @confirm="confirmOrderType"/>
<uv-picker ref="orderStatusPicker" :columns="[orderStatusList]" keyName="label" @confirm="confirmOrderStatus"/>
</view>
</template>
<script>
import * as OrderApi from '@/api/think/thinkOrder'
import {
getWeek,
getKey
} from '@/utils/common';
import {pageThinkOrder, thinkOrderRepay, updateThinkOrder} from "@/api/think/thinkOrder";
import {pageThinkUsersVip, thinkUsersVipRepay, updateThinkUsersVip} from "@/api/think/thinkUsersVip";
import {pageThinkDeposit} from "@/api/think/thinkDeposit";
import dayjs from "dayjs";
import * as Api from "@/api/booking/userInvoice";
import {addThinkOrderRefundLog} from "@/api/think/thinkOrderRefundLog";
import {authUser} from "@/api/user";
import {useUserStore} from "@/store/modules/user";
const userStore = useUserStore();
export default {
computed: {
dayjs() {
return dayjs
}
},
components: {},
data() {
return {
isRefresh: false,
isLogin: false,
userId: 0,
userInfo: null,
where: {
page: 1
// sceneType: 'showOrderInfo' // 查询订单附加场地信息
},
canReset: false,
loadMore: 'more',
logo: '',
items: ['全部订单', '未支付', '已支付', '已完成', '押金'],
orderList: [],
styles: [{
value: 'button',
text: '按钮',
checked: true
},
{
value: 'text',
text: '文字'
}
],
colors: ['#333333', '#4cd964', '#dd524d'],
current: 0,
colorIndex: 0,
activeColor: '#108001',
styleType: 'text',
getWeek,
// 骨架屏
hideTools: true,
orderTypeStr: '订场订单',
orderType: 0,
orderTypeList: [
{
label: '订场订单',
value: 0
},
{
label: '会员卡订单',
value: 1
},
{
label: '押金',
value: 2
},
],
orderStatusList: [
{
label: '未支付',
value: 2
},
{
label: '已支付',
value: 1
}
],
orderStatusStr: '全部状态',
orderStatus: null,
hasMerchantRole: false,
hasMerchantClerkRole: false,
hasSuperAdminRole: false,
orderNo: '',
safeTop: 44,
}
},
// async onLoad(option) {
// this.userId = await uni.getStorageSync('user_id')
// // 加载数据
// await this.reload()
// // if(option.isRefresh){
// // this.isRefresh = true
// // }
// },
async onShow(e) {
const sysInfo = uni.getSystemInfoSync()
this.safeTop = sysInfo.statusBarHeight
this.userId = await uni.getStorageSync('user_id')
const userInfo = await userStore.fetchUserInfo();
if (Object.keys(userInfo).length > 0) {
this.userInfo = userInfo;
this.hasMerchantRole = userInfo.roles.find((d) => d.roleCode === 'merchant');
this.hasMerchantClerkRole = userInfo.roles.find((d) => d.roleCode === 'merchantClerk');
this.hasSuperAdminRole = userInfo.roles.find((d) => d.roleCode === 'superAdmin');
}
await this.reload()
},
// 触底函数
onReachBottom() {
const app = this
const {
where
} = this
console.log(app.canReset)
if (app.canReset) {
app.where.page += 1;
app.getOrderList()
}
},
methods: {
openOrderTypePicker() {
this.$refs.orderTypePicker.open()
},
openOrderStatusPicker() {
this.$refs.orderStatusPicker.open()
},
confirmOrderType({value}) {
this.orderType = value[0].value
this.orderTypeStr = value[0].label
this.reload()
},
confirmOrderStatus({value}) {
if (this.orderType === 0) {
this.where.payStatus = value[0].value
} else if (this.orderType === 1) {
this.where.status = value[0].value
} else if (this.orderType === 2) {
this.where.status = value[0].value
}
this.orderStatus = value[0].value
this.orderStatusStr = value[0].label
this.reload()
},
async reload() {
this.loadMore = 'loading'
this.where.page = 1
this.orderList = []
this.$refs.orderTypePicker.close()
await this.getOrderList()
},
async getOrderList() {
let res
if (this.orderType === 0) {
if (this.orderNo) {
this.where.orderNum = this.orderNo
this.where.forAdmin = true
} else {
this.where.orderNum = null
this.where.forAdmin = null
}
res = await pageThinkOrder(this.where).catch(err => {
this.$refs.login.open('bottom')
})
} else if (this.orderType === 1) res = await pageThinkUsersVip(this.where).catch(err => {
this.$refs.login.open('bottom')
})
else if (this.orderType === 2) res = await pageThinkDeposit(this.where).catch(err => {
this.$refs.login.open('bottom')
})
if (this.orderList.length < res.count) {
let list = res.list
if (this.orderType === 1) list = list.map(item => {
item.orderNum = item.wechatOrder
item.payPrice = item.price
return item
})
if (this.orderType === 0) list = list.map(item => {
item.canRefund = false
// 游泳馆没有用就可以退
if (item.sid === 37) {
if (item.orderStatus === 2) item.canRefund = true
} else {
// 可提前6小时退
item.canRefund = item.startTime - dayjs().unix() > (3600 * 6)
}
item.disabled = false
return item
})
this.orderList = this.orderList.concat(list)
console.log(this.orderList)
this.canReset = true
this.loadMore = 'no-more'
} else {
this.canReset = false;
this.loadMore = 'no-more'
}
if (this.orderType !== 2) {
this.orderList = this.orderList.map(item => {
item.canInvoice = false
if (this.orderType === 0 && item.isInvoice === 2 && item.orderStatus === 1) {
const date = item.dateTime.split("(")[0]
const endTime = item.dateTime.split(" - ")[1]
const time = `${date} ${endTime}:00`
if (dayjs().isAfter(dayjs(time))) item.canInvoice = true
}
return item
})
}
},
async onClickItem(e) {
const app = this
// this.uid = await uni.getStorageSync('uid')
const {
where,
// uid
} = this
// if (app.uid === 0 || !app.uid) {
// console.log(app.uid, '>>>>>>>2', app.uid)
// app.orderList = [];
// app.loadMore = 'no-more'
// return;
// }
const index = e.currentIndex
if (this.current !== e.currentIndex) {
this.current = e.currentIndex
}
// 全部
if (index === 0) {
where.payStatus = undefined;
where.orderStatus = undefined;
}
// 未支付
if (index === 1) {
where.payStatus = 2;
where.orderStatus = undefined;
}
// 已支付
if (index === 2) {
where.payStatus = 1;
where.orderStatus = undefined;
}
// 已完成
if (index === 3) {
where.payStatus = 1;
where.orderStatus = 1;
}
// 押金
// if (index === 4) {
// pageThinkWechatDeposit({
// uid: uni.getStorageSync('user_id')
// }).then(res => {
// app.orderList = res.list;
// if (res.count === 0) {
// app.loadMore = 'no-more'
// }
// uni.hideLoading()
// })
// return false
// }
this.where.page = 1;
this.orderList = [];
this.reload()
},
openUrl(url) {
uni.navigateTo({
url
})
},
toPay(orderId) {
uni.navigateTo({
url: '/package/booking/confirm?id=' + orderId
})
},
closeOrder(item) {
const _this = this
uni.showModal({
title: '确定取消此订单?',
async success(o) {
if (o.confirm) {
await updateThinkOrder({
orderStatus: 3,
id: item.id
})
uni.showToast({
title: '取消成功',
icon: 'none'
})
await _this.reload()
}
}
});
},
// 弹出登录提示框
async openLogin() {
const userId = uni.getStorageSync('user_id');
if (!this.userId) {
this.$refs.login.open('bottom')
return false;
}
},
// 申请开票
onInvoice({id, orderNum, payPrice}) {
let url = `/package/user/invoice?id=${id}&orderNum=${orderNum}&itype=${this.orderType + 1}`
url += `&price=${payPrice}`
uni.navigateTo({url})
},
showInvoice(id) {
uni.navigateTo({
url: `/package/user/invoice-show?id=${id}`
})
},
async closeVipOrder({id}) {
await updateThinkUsersVip({id, status: 0})
await uni.showToast({
title: '取消成功',
icon: 'none'
})
await this.reload()
},
toDetail(id) {
let url
if (this.orderType === 0) url = `/package/order/detail?id=${id}`
else if (this.orderType === 1) url = `/package/order/vipDetail?id=${id}`
else if (this.orderType === 2) url = `/package/order/detail?id=${id}`
uni.navigateTo({url})
},
async openPay(id) {
const orderInfo = await thinkUsersVipRepay({id})
const _this = this
uni.requestPayment({
provider: orderInfo.provider, // 服务提供商
timeStamp: orderInfo.timeStamp, // 时间戳
nonceStr: orderInfo.nonceStr, // 随机字符串
package: orderInfo.package,
signType: orderInfo.signType, // 签名算法
paySign: orderInfo.paySign, // 签名
success: function (res) {
// 业务逻辑。。。
uni.showToast({
title: '支付成功',
icon: 'success'
});
setTimeout(function () {
_this.reload()
}, 1500);
},
fail: function (err) {
console.log('支付失败', err);
}
})
},
async openPayOrder(id) {
const orderInfo = await thinkOrderRepay({id})
const _this = this
uni.requestPayment({
provider: orderInfo.provider, // 服务提供商
timeStamp: orderInfo.timeStamp, // 时间戳
nonceStr: orderInfo.nonceStr, // 随机字符串
package: orderInfo.package,
signType: orderInfo.signType, // 签名算法
paySign: orderInfo.paySign, // 签名
success: function (res) {
// 业务逻辑。。。
uni.showToast({
title: '支付成功',
icon: 'success'
});
setTimeout(function () {
_this.reload()
}, 1500);
},
fail: function (err) {
console.log('支付失败', err);
}
})
},
reset() {
this.where = {
page: 1
}
this.orderList = []
this.orderType = 0
this.orderTypeStr = '订场订单'
this.orderStatus = null
this.orderStatusStr = '全部状态'
this.reload()
},
refund(order, index) {
uni.showModal({
title: '确定要退款吗?',
success: async ({confirm}) => {
if (confirm) {
this.orderList[index].disabled = true
uni.showLoading({
title: '退款请求中'
})
await addThinkOrderRefundLog({
uid: order.uid,
refundAmount: order.payPrice,
sid: order.sid,
oid: order.id,
status: 1,
type: 0
})
this.orderList[index].disabled = false
uni.hideLoading()
uni.showToast({
title: '申请退款成功',
icon: 'none'
})
await this.reload()
}
}
})
}
}
}
</script>
<style lang="scss">
.content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
height: 150px;
text-align: center;
}
.segmented {
padding: 0 12rpx;
}
.content-text {
font-size: 14px;
color: #666;
}
.color-tag {
width: 25px;
height: 25px;
}
.uni-list {
flex: 1;
}
.order {
.order-title {
padding: 20rpx 0;
border-bottom: 1px #eee solid;
.merchant-avatar {
margin-right: 12rpx;
}
.merchant-name {
// padding-left: 12rpx;
}
.btn-status {
font-size: 30rpx;
display: flex;
}
}
.order-body {
padding: 16px 0;
}
}
.ele-flex {
display: flex;
justify-content: space-between;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.close {
top: 60rpx !important;
}
.total-price {
display: flex;
flex-direction: column;
justify-content: flex-start;
font-size: 30rpx;
align-items: flex-start;
padding-left: 6rpx;
margin-left: 450rpx;
.web-text-heading {
font-size: 30rpx !important;
}
}
</style>