Procházet zdrojové kódy

0元订单购买,支付回调页面

skyblued před 2 roky
rodič
revize
7623577a82

+ 8 - 0
src/router/routes-common.ts

@@ -137,6 +137,14 @@ export const router = [
     meta: {
       title: '订单详情'
     }
+  },
+  {
+    path: '/shopTrade',
+    name: 'shopTrade',
+    component: () => import('@/views/shop-mall/shop-trade/trade-detail'),
+    meta: {
+      title: '交易详情'
+    }
   }
 ]
 

+ 14 - 1
src/views/cart/cart-confirm/index.tsx

@@ -19,7 +19,10 @@ import ColPopup from '@/components/col-popup'
 import UserAuth from '@/views/order-detail/userAuth'
 import ColResult from '@/components/col-result'
 import { moneyFormat } from '@/helpers/utils'
-import { listenerMessage, removeListenerMessage } from '@/helpers/native-message'
+import {
+  listenerMessage,
+  removeListenerMessage
+} from '@/helpers/native-message'
 export default defineComponent({
   name: 'cartConfirm',
   setup() {
@@ -94,6 +97,16 @@ export default defineComponent({
           { data: body }
         )
         if (code === 200) {
+          if (data.order.status === 1) {
+            router.push({
+              path: `/shopTrade`,
+              query: {
+                orderNo: data?.order.orderSn,
+                id: data?.order.id
+              }
+            })
+            return
+          }
           paymentPopup.value = true
           orderInfo.orderNo = data?.order.orderSn || ''
           orderInfo.actualPrice = data?.order.payAmount || 0

+ 1 - 1
src/views/cart/index.tsx

@@ -204,7 +204,7 @@ export default defineComponent({
                     price={this.totalPrice}
                     buttonText={`结算(${this.len})`}
                     buttonColor="var(--van-primary)"
-                    disabled={this.totalPrice === 0}
+                    disabled={this.len === 0}
                     onSubmit={() => this.generateConfirmOrder()}
                   >
                     <Checkbox

+ 9 - 0
src/views/order-detail/payment/index.tsx

@@ -139,6 +139,15 @@ export default defineComponent({
       if (res.status === 'success') {
         Toast.clear()
         this.$emit('update:modelValue', false)
+        if (this.paymentType === 'goodsPay') {
+          this.$router.replace({
+            path: '/shopTrade',
+            query: {
+              orderNo: this.orderInfo.orderNo
+            }
+          })
+          return 
+        }
         this.$router.replace({
           path: '/tradeDetail',
           query: {

binární
src/views/shop-mall/shop-trade/images/icon_close.png


binární
src/views/shop-mall/shop-trade/images/icon_close_block.png


binární
src/views/shop-mall/shop-trade/images/icon_paying.png


binární
src/views/shop-mall/shop-trade/images/icon_paying_block.png


binární
src/views/shop-mall/shop-trade/images/icon_success.png


binární
src/views/shop-mall/shop-trade/images/icon_success_block.png


+ 129 - 0
src/views/shop-mall/shop-trade/trade-detail.module.less

@@ -0,0 +1,129 @@
+.tradeDetail {
+  .orderType {
+    padding: 30px 0 72px;
+    background: var(--van-primary);
+    text-align: center;
+    color: #fff;
+    font-size: 24px;
+
+    & > p {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      span {
+        padding-top: 8px;
+        padding-left: 13px;
+      }
+    }
+  }
+  .orderImg {
+    width: 42px;
+    height: 47px;
+  }
+
+  &.FAILED,
+  &.CLOSE {
+    .orderType {
+      background-color: #bdbdbd;
+    }
+    .orderContent::before {
+      background: url('./images/icon_close_block.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+  &.ING {
+    .orderType {
+      background-color: #ff802c;
+    }
+    .orderContent::before {
+      background: url('./images/icon_paying_block.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+  .orderContent {
+    border-radius: 0px 0px 10px 10px;
+    margin: -30px 16px 0;
+    position: relative;
+    &::before {
+      content: ' ';
+      position: absolute;
+      top: -6px;
+      left: -8px;
+      right: -8px;
+      height: 14px;
+      background: url('./images/icon_success_block.png') no-repeat center;
+      background-size: contain;
+    }
+
+    .payPrice {
+      color: #333;
+      font-size: 32px;
+      text-align: center;
+      font-weight: 500;
+      padding: 10px 0 5px;
+      & > span {
+        font-size: 12px;
+      }
+    }
+  }
+
+  .tradeLogo {
+    width: 35px;
+    height: 35px;
+    border-radius: 50%;
+    margin-right: 10px;
+    overflow: hidden;
+  }
+
+  .title,
+  .content {
+    padding-top: 1px;
+    display: flex;
+    justify-content: space-between;
+    flex-direction: column;
+    line-height: 18px;
+    color: #333333;
+    font-size: 14px;
+  }
+  .desc,
+  .num {
+    padding-top: 3px;
+    font-size: 13px;
+    color: #999999;
+  }
+
+  .optionRow {
+    line-height: 26px;
+    display: flex;
+    position: relative;
+    padding-bottom: 15px;
+    box-sizing: border-box;
+    color: #333333;
+    font-size: 14px;
+
+    :global {
+      .van-col {
+        display: flex;
+        line-height: 1.5;
+      }
+      .van-col--8 {
+        color: #999999;
+        justify-content: flex-start;
+      }
+      .van-col--14 {
+        justify-content: flex-end;
+        word-break: break-word; /* 文本行的任意字内断开 */
+        word-wrap: break-word; /* IE */
+        white-space: -moz-pre-wrap; /* Mozilla */
+        white-space: -hp-pre-wrap; /* HP printers */
+        white-space: -o-pre-wrap; /* Opera 7 */
+        white-space: -pre-wrap; /* Opera 4-6 */
+        white-space: pre; /* CSS2 */
+        white-space: pre-wrap; /* CSS 2.1 */
+        white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
+      }
+    }
+  }
+}

+ 240 - 0
src/views/shop-mall/shop-trade/trade-detail.tsx

@@ -0,0 +1,240 @@
+import ColHeader from '@/components/col-header'
+import { Button, Cell, CellGroup, Col, Image, Popup, Row } from 'vant'
+import { defineComponent } from 'vue'
+import styles from './trade-detail.module.less'
+import { goodsType } from '@/constant'
+
+import iconTeacher from '@common/images/icon_teacher.png'
+import request from '@/helpers/request'
+import { orderStatus } from '../../order-detail/orderStatus'
+import { orderState } from '../shop-mall'
+
+export const getAssetsHomeFile = (fileName: string) => {
+  const path = `./images/${fileName}`
+  const modules = import.meta.globEager('./images/*')
+  return modules[path].default
+}
+
+// 0, 6 待支付 2 支付中 CLOSE 已关闭 FAIL 支付失败
+type orderType = 0 | 1 | 2 | 3 | 4 | 5 | 6
+
+export default defineComponent({
+  name: 'tradeDetail',
+  data() {
+    const query = this.$route.query
+    return {
+      type: (query.type as string) || 'ING',
+      path: query.path, // 来源
+      orderNo: query.orderNo || '',
+      orderId: query.id || '',
+      paymentStatus: false,
+      order: {
+        ING: {
+          img: getAssetsHomeFile('icon_paying.png'),
+          background: '#FF802C',
+          title: '支付中'
+        },
+        SUCCESS: {
+          img: getAssetsHomeFile('icon_success.png'),
+          background: 'var(--van-primary)',
+          title: '支付成功'
+        },
+        FAILED: {
+          img: getAssetsHomeFile('icon_close.png'),
+          background: '#BDBDBD',
+          title: '支付失败'
+        },
+        CLOSE: {
+          img: getAssetsHomeFile('icon_close.png'),
+          background: '#BDBDBD',
+          title: '订单关闭'
+        }
+      },
+      result: {} as any,
+      loading: true,
+      timerOut: null as any,
+      timer: 3
+    }
+  },
+  computed: {
+    orderDetailList() {
+      const result: any = this.result
+      return result.orderItemList || []
+    }
+  },
+  async mounted() {
+    setTimeout(async () => {
+      this.loading = true
+      await this.getOrder()
+      this.loading = false
+
+      this.type === 'ING' && this.path !== 'tradeRecord' && this.interval()
+    }, 0)
+  },
+  unmounted() {
+    clearInterval(this.timerOut)
+  },
+  methods: {
+    onRePay() {
+      orderStatus.orderInfo = {
+        orderNo: this.result.orderNo,
+        actualPrice: this.result.actualPrice,
+        payStatus: true
+      }
+      this.paymentStatus = true
+      this.interval()
+    },
+    interval() {
+      let countTime = 0
+      this.timerOut = setInterval(async () => {
+        countTime === 25 && clearInterval(this.timerOut)
+        await this.getOrder(true)
+        countTime++
+      }, 5000)
+    },
+    async getOrder(status?: true) {
+      const url = this.orderId ? `/api-mall-portal/order/detail/${this.orderId}` : `/api-mall-portal/order/detail/sn/${this.orderNo}`
+      try {
+        const res = await request.get(
+          url,
+          {
+            hideLoading: status
+          }
+        )
+        this.result = res.data
+        // WAIT_PAY 待支付 PAYING 支付中 PAID 已付款 CLOSE 已关闭 FAIL 支付失败
+        this.type = this.formatType(this.result.status)
+        this.type !== 'ING' && clearInterval(this.timerOut)
+      } catch {}
+    },
+    formatType(type: number) {
+      let str = 'PAYING'
+      console.log(orderState[type], type)
+      switch (type) {
+        case 0:
+        case 6:
+          str = 'ING'
+          break
+        case 1:
+        case 2:
+        case 3:
+          str = 'SUCCESS'
+          break
+        case 4:
+          str = 'CLOSE'
+          break
+        case 5:
+          str = 'FAILED'
+          break
+        default:
+          str = 'ING'
+          break
+      }
+      return str
+    }
+  },
+  render() {
+    return (
+      <div class={[styles.tradeDetail, styles[this.type]]}>
+        {!this.loading && (
+          <>
+            <ColHeader
+              background={this.order[this.type].background}
+              color="#fff"
+              title="交易详情"
+              backIconColor="white"
+              border={false}
+            />
+
+            <div class={styles.orderType}>
+              <p>
+                <Image
+                  class={styles.orderImg}
+                  src={this.order[this.type].img}
+                  fit="cover"
+                />
+                <span>{this.order[this.type].title}</span>
+              </p>
+            </div>
+
+            <CellGroup border={false} class={[styles.orderContent, 'mb12']}>
+              <Cell
+                v-slots={{
+                  title: () => (
+                    <div class={styles.payPrice}>
+                      <span>¥</span>
+                      {(this as any).$filters.moneyFormat(
+                        this.result.payAmount
+                      )}
+                    </div>
+                  )
+                }}
+              />
+
+              {this.orderDetailList.map((item: any) => (
+                <Cell
+                  border={false}
+                  style={{ paddingBottom: '15px' }}
+                  v-slots={{
+                    icon: () => (
+                      <Image
+                        class={styles.tradeLogo}
+                        src={item.productPic || iconTeacher}
+                        fit="cover"
+                      />
+                    ),
+                    title: () => (
+                      <div class={styles.title}>
+                        <span>{item.productName}</span>
+                        <span class={styles.desc}>商品购买
+                        </span>
+                      </div>
+                    ),
+                    default: () => (
+                      <div class={styles.content}>
+                        <span class={styles.price}>
+                          ¥
+                          {(this as any).$filters.moneyFormat(item.productPrice)}
+                        </span>
+                        <span class={styles.num}>x{item.productQuantity}</span>
+                      </div>
+                    )
+                  }}
+                />
+              ))}
+
+              <Row class={styles.optionRow}>
+                <Col span="8" offset={1}>
+                  订单号:
+                </Col>
+                <Col span="14">{this.result.orderSn}</Col>
+                <Col span="1"> </Col>
+              </Row>
+              {/* <Row class={styles.optionRow}>
+                <Col span="8" offset={1}>
+                  交易流水号:
+                </Col>
+                <Col span="14">{this.result.transNo}</Col>
+                <Col span="1"> </Col>
+              </Row> */}
+              <Row class={styles.optionRow}>
+                <Col span="8" offset={1}>
+                  创建时间:
+                </Col>
+                <Col span="14">{this.result.createTime}</Col>
+                <Col span="1"> </Col>
+              </Row>
+              <Row class={styles.optionRow}>
+                <Col span="8" offset={1}>
+                  付款时间:
+                </Col>
+                <Col span="14">{this.result.paymentTime}</Col>
+                <Col span="1"> </Col>
+              </Row>
+            </CellGroup>
+          </>
+        )}
+      </div>
+    )
+  }
+})