| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- <template>
- <view class="o-header-list">
- <view :class="[selected == index ? 'sel-item-list' : 'item-list']" v-for="(item, index) in orderTypeList"
- :key="index" @click="selectedItem(index)">{{ item }}</view>
- </view>
- <view style="height: 80rpx;"></view>
- <view class="content">
- <view class="o-orderlist-card" v-for="item in orderList" :key="item.orderId"
- @click="RouterUtils.to_page(`/pages/index/toBeUsed/index?orderId=${item.orderId}&orderType=${item.orderType}&isPayOrder=1`)">
- <view class="o-order-name">
- <view class="order-name" v-if="item?.orderProInfoList && item.orderProInfoList.length > 0">{{
- item.orderType == 5 ? '上课地点' : '场地' }}:{{ item?.orderProInfoList[0].address || '--'
- }}</view>
- <!-- 待付款 -->
- <view class="order-status" v-if="item.orderStatus == 0">待支付(剩余{{ item.downTime }})</view>
- <view class="item-order-status" style="color:#FB5B5B;" v-if="item.orderStatus == 1">待使用</view>
- <view class="item-order-status" v-if="item.orderStatus == 2">已使用</view>
- <view class="item-order-status" v-if="item.orderStatus == 3">已到期</view>
- <view class="item-order-status" v-if="item.orderStatus == 4">已取消</view>
- <view class="item-order-status" v-if="item.orderStatus == 5">待退款</view>
- <view class="item-order-status" v-if="item.orderStatus == 6">已退款</view>
- </view>
- <view class="line"></view>
- <view class="o-order-info">
- <view class="item-info">
- <!-- 有保险 -->
- <scroll-view class="scroll-view_H scroll-order" scroll-x="true"
- v-if="item?.orderInsureList?.length > 0 && item?.orderProInfoList && item.orderProInfoList.length > 0">
- <view class="scroll-view-item_H scroll-order-item">
- <view class="item-order">
- <view class="order-img">
- <image :src="item.orderProInfoList[0].productImage" mode="">
- </image>
- </view>
- <view class="order-name textHidden">{{ item?.orderProInfoList[0].productName }}</view>
- </view>
- </view>
- <view class="scroll-view-item_H scroll-order-item">
- <view class="item-order">
- <view class="order-img">
- <image :src="item?.orderInsureList[0].productImage.split(',')[0]" mode="">
- </image>
- </view>
- <view class="order-name textHidden">{{ item?.orderInsureList[0].productName }}</view>
- </view>
- </view>
- </scroll-view>
- <!-- 没保险 -->
- <view class="item-order-single" v-else>
- <view class="single-img">
- <image
- :src="item?.orderProInfoList && item.orderProInfoList.length > 0 ? item?.orderProInfoList[0]?.productImage.split(',')[0] : ''"
- mode=""></image>
- </view>
- <view class="single-name">
- <view class="item-single-name textHidden"
- v-if="item.orderType != 1 && item?.orderProInfoList && item.orderProInfoList.length > 0">
- {{
- item?.orderProInfoList[0].productName }}</view>
- <view class="item-single-name" v-else-if="item.orderType == 1 && item?.orderProInfoList">
- <!-- {{ item.orderProInfoList[0].productName }} -->
- <view class="textHidden" v-for="name in item.orderProInfoList" :key="name.id">{{
- name.productName }}</view>
- </view>
- </view>
- </view>
- </view>
- <view class="order-data">
- <view class="order-price"><text class="mini-text">¥</text>{{ item.price.toFixed(2) }}</view>
- <view class="order-num">共{{ item?.orderProInfoList?.length || 0 }}件</view>
- </view>
- </view>
- <view class="line"></view>
- <!-- 待付款 -->
- <view class="o-order-btn">
- <view class="cancel-btn" v-if="item?.orderStatus == 0" @click.stop="cancelOrder(item)">取消订单</view>
- <view class="pay-btn" v-if="item?.orderStatus == 0" @click.stop="submitPay(item)">付款</view>
- <!-- 售后/退款 -->
- <view class="pay-btn"
- v-if="item?.orderStatus == 2 && item.orEvaluate == 0 && item.orderType != 3 && item.orderType != 4 && item?.orderProInfoList && item.orderProInfoList.length > 0"
- @click.stop="RouterUtils.to_page(`/pages/index/writeComments/index?siteId=${item.addressSiteId}&orderId=${item.orderId}&siteName=${item.orderProInfoList[0].address}`)">
- 评价</view>
- <!-- 已使用 -->
- <view class="cancel-btn" v-if="selected == 4">申请退款</view>
- <view class="pay-btn" v-if="selected == 4">凭证</view>
- </view>
- <!-- 待使用 -->
- <view class="o-order-tips"
- v-if="item.orderStatus == 1 && item.orderType != 3 && item.orderType != 4 && item?.orderProInfoList && item.orderProInfoList.length > 0">
- <text
- v-if="item.orderProInfoList[0].frameTimeStr && item.orderProInfoList[0].frameTimeStr != '00:00-00:00'">限{{
- item.orderProInfoList[0].frameTimeStr }}使用,过期作废</text>
- <text v-if="item.earlyRefundTime">请按时到场,退款需提前{{ item.earlyRefundTime }}分钟</text>
- </view>
- </view>
- <zs-empty v-if="orderList.length == 0"></zs-empty>
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, onMounted, onUnmounted } from 'vue'
- import { http } from '@/utils/http'
- import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app';
- import zsEmpty from '@/components/zs-empty/index.vue';
- import { RouterUtils, TipsUtils } from '@/utils/util';
- import { useCacheStore } from '@/stores/cache'
- const cache = useCacheStore()
- const selected = ref(0)
- const orderTypeList = ref(['全部', '待付款', '待使用', '已使用', '退款/售后'])
- onLoad((option) => {
- })
- onShow(() => {
- // selected.value = cache.get('ORDER_SEL_INDEX') || 0
- const statusMap:any = {
- 0: { orderStatus: null, orAfterSale: 0 },
- 1: { orderStatus: 0, orAfterSale: 0 },
- 2: { orderStatus: 1, orAfterSale: 0 },
- 3: { orderStatus: 2, orAfterSale: 0 },
- 4: { orderStatus: null, orAfterSale: 1 }
- }
- const selectedIndex = cache.get('ORDER_SEL_INDEX')
- selected.value = selectedIndex||0
- if (statusMap[selectedIndex]) {
- Object.assign(orderFormData.value, statusMap[selectedIndex])
- }
- // 使用完成后移除缓存
- cache.remove('ORDER_SEL_INDEX')
- getOrderList()
- })
- onReachBottom(() => {
- orderFormData.value.pageNo++;
- getOrderList()
- })
- onMounted(() => {
- // getOrderList()
- })
- const selectedItem = (i) => {
- orderFormData.value.pageNo = 1
- selected.value = i
- if (selected.value == 0) {
- orderFormData.value.orderStatus = null
- orderFormData.value.orAfterSale = 0
- } else if (selected.value == 1) {
- orderFormData.value.orderStatus = 0
- orderFormData.value.orAfterSale = 0
- } else if (selected.value == 2) {
- orderFormData.value.orAfterSale = 0
- orderFormData.value.orderStatus = 1
- } else if (selected.value == 3) {
- orderFormData.value.orAfterSale = 0
- orderFormData.value.orderStatus = 2
- } else if (selected.value == 4) {
- orderFormData.value.orderStatus = null
- orderFormData.value.orAfterSale = 1
- }
- getOrderList()
- }
- // 提交支付start
- const orderCode = ref()
- const orderId = ref()
- const submitPay = (e: any) => {
- http.put(`/order/payOrder?appOrderId=${e.orderId}`, {}, { loading: true }).then((res) => {
- orderCode.value = res.result.orderCode
- orderId.value = res.result.orderId
- paymentOrder(res.result.params)
- })
- }
- const paymentOrder = (payInfo: object) => {
- // getOrderQuery(orderCode.value, orderId.value)
- console.log(payInfo, '支付参数');
- uni.requestPayment({
- provider: 'wxpay',
- ...payInfo,
- success: function (res) {
- console.log('支付成功', res);
- setTimeout(() => {
- getOrderQuery(orderCode.value, orderId.value)
- }, 500)
- },
- fail: function (err) {
- console.log('支付失败', err);
- // TipsUtils.tips_toast('支付失败,请稍后重试');
- }
- });
- }
- const getOrderQuery = (orderCode: string, orderId: string, retryCount = 0) => {
- http.get('/order/orderQuery', { data: { orderCode: orderCode }, loading: true }).then((res) => {
- if (res.result == '100001') {
- TipsUtils.tips_toast('支付成功');
- getOrderList()
- } else if (retryCount <= 3) {
- setTimeout(() => {
- getOrderQuery(orderCode, orderId, retryCount + 1)
- }, 1000)
- } else {
- if (res.result == '100003') {
- console.log('查询中,但已达到最大查询次数')
- } else if (res.result == '100002') {
- console.log('查询失败')
- } else if (res.result == '100004') {
- console.log('支付失败')
- TipsUtils.tips_toast('支付失败')
- }
- }
- }).catch((error) => {
- console.error('查询订单失败:', error)
- if (retryCount < 2) {
- setTimeout(() => {
- getOrderQuery(orderCode, orderId, retryCount + 1)
- }, 1000)
- }
- })
- }
- // 提交支付end
- // 获取订单数据
- const orderFormData = ref({
- pageNo: 1,
- pageSize: 10,
- orderStatus: null,
- orAfterSale: 0
- })
- const orderList = ref([])
- // 订单状态 0-待付款 1-待使用 2-已使用 3-已到期 4-已取消 5-待退款 6已退款
- const getOrderList = () => {
- http.post('/order/pageOrders', orderFormData.value, { loading: true }).then((res) => {
- if (orderFormData.value.pageNo == 1) {
- orderList.value = res.result.records
- } else {
- orderList.value = [...orderList.value, ...res.result.records]
- }
- orderList.value.forEach((item) => {
- // const [datePart, timePart] = item.createTime.split(' ');
- // const [year, month, day] = datePart.split('-').map(Number);
- // const [hours, minutes, seconds] = timePart.split(':').map(Number);
- // item.createTime = new Date(year, month - 1, day, hours, minutes, seconds);
- console.log(item.createTime);
- if (item.orderStatus == 0) {
- item.downTime = "";
- item.timer = null;
- startCountdown(item);
- }
- })
- console.log(orderList.value, '订单列表');
- })
- }
- // 倒计时
- let callCount = 0;
- const startCountdown = (item) => {
- if (item.timer) {
- clearInterval(item.timer);
- }
- const endTime = new Date(item.epxTime);
- const remainingTime = endTime - new Date();
- if (remainingTime > 0) {
- const minutes = Math.floor(remainingTime / (1000 * 60));
- const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);
- item.downTime = `${minutes.toString().padStart(2, '0')}分${seconds.toString().padStart(2, '0')}秒`;
- item.timer = setInterval(() => {
- const now = new Date();
- const newRemainingTime = endTime - now;
- if (newRemainingTime <= 0) {
- clearInterval(item.timer);
- item.downTime = "00:00";
- if (callCount < 3) {
- callCount++;
- setTimeout(()=>{
- getOrderList();
- },500)
- }
- return;
- }
- const newMinutes = Math.floor(newRemainingTime / (1000 * 60));
- const newSeconds = Math.floor((newRemainingTime % (1000 * 60)) / 1000);
- item.downTime = `${newMinutes.toString().padStart(2, '0')}分${newSeconds.toString().padStart(2, '0')}秒`;
- }, 1000);
- } else {
- item.downTime = "00:00";
- if (callCount < 3) {
- callCount++;
- getOrderList();
- }
- }
- }
- const cancelOrder = async (e: any) => {
- let res: any = await TipsUtils.tips_alert('确定取消订单吗?', true)
- if (res.confirm) {
- http.put(`/order/cancelOrder?orderId=${e.orderId}`, {}, { loading: true }).then((res: any) => {
- TipsUtils.tips_toast('订单已取消')
- getOrderList()
- })
- }
- }
- onUnmounted(() => {
- orderList.value.forEach(item => {
- if (item.timer) {
- clearInterval(item.timer);
- }
- });
- });
- </script>
- <style lang="less" scoped>
- .o-header-list {
- position: fixed;
- top: 0;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: space-around;
- height: 80rpx;
- background: #fff;
- z-index: 1000;
- .sel-item-list {
- font-weight: bold;
- font-size: 28rpx;
- color: #222222;
- transition: all .3s;
- }
- .item-list {
- font-size: 28rpx;
- color: #AAAAAA;
- transition: all .3s;
- }
- }
- .o-orderlist-card {
- background: #FFFFFF;
- border-radius: 32rpx;
- padding: 20rpx;
- margin-top: 20rpx;
- .o-order-name {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 26rpx;
- .order-name {
- font-size: 24rpx;
- color: #222222;
- }
- .order-status {
- font-weight: bold;
- font-size: 28rpx;
- color: #FB5B5B;
- }
- .item-order-status {
- font-weight: bold;
- font-size: 28rpx;
- color: #AAAAAA;
- }
- }
- .o-order-info {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-top: 24rpx;
- margin-bottom: 24rpx;
- .item-info {
- // 多个商品
- .scroll-order {
- width: 500rpx;
- .scroll-order-item {
- margin-right: 20rpx;
- .item-order {
- .order-img {
- &>image {
- width: 160rpx;
- height: 160rpx;
- border-radius: 16rpx;
- }
- }
- .order-name {
- width: 160rpx;
- font-size: 28rpx;
- color: #222222;
- }
- }
- }
- }
- // 单个商品
- .item-order-single {
- display: flex;
- align-items: center;
- gap: 20rpx;
- .single-img {
- &>image {
- width: 160rpx;
- height: 160rpx;
- border-radius: 16rpx;
- }
- }
- .single-name {
- width: 360rpx;
- font-size: 28rpx;
- color: #222222;
- .item-single-name {
- width: 360rpx;
- margin-bottom: 10rpx;
- }
- }
- }
- }
- .order-data {
- width: 400rpx;
- border-left: 1rpx solid #efefef;
- text-align: center;
- .order-price {
- font-weight: 600;
- font-size: 28rpx;
- color: #FB5B5B;
- }
- .order-num {
- margin-top: 10rpx;
- font-size: 24rpx;
- color: #AAAAAA;
- }
- }
- }
- .o-order-btn {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- gap: 20rpx;
- margin-top: 24rpx;
- .cancel-btn {
- width: 200rpx;
- height: 68rpx;
- background: #FFFFFF;
- border-radius: 60rpx;
- border: 2rpx solid #AAAAAA;
- font-weight: bold;
- font-size: 28rpx;
- color: #AAAAAA;
- line-height: 68rpx;
- text-align: center;
- }
- .pay-btn {
- width: 200rpx;
- height: 68rpx;
- background: #C8FF0C;
- border-radius: 60rpx;
- font-weight: bold;
- font-size: 28rpx;
- color: #222222;
- text-align: center;
- line-height: 68rpx;
- }
- }
- .o-order-tips {
- margin-top: 24rpx;
- background: #F6F6F6;
- border-radius: 16rpx;
- padding: 20rpx;
- font-size: 28rpx;
- color: #222222;
- }
- }
- </style>
|