Browse Source

feat(order): pre order

LaveyD 1 day ago
parent
commit
5849f4b6b8

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "ticket",
-  "version": "1.0.17.6",
+  "version": "1.0.17.7",
   "private": true,
   "description": "多巴胺科技",
   "author": "",

+ 10 - 0
src/api/order.js

@@ -88,6 +88,16 @@ export function cancelOrder (params) {
   return http.post('/admin/order/cancelOrder', { data: params })
 }
 
+// 登记订单-确认出票:NO_PAY 直接出票;扫码支付传入付款码 qrcode 走被扫支付
+export function confirmRegisterOrder (params) {
+  return http.post('/admin/order/confirmRegisterOrder', { data: params })
+}
+
+// 登记订单-关闭:手动关闭未支付的登记订单并释放库存
+export function closeRegisterOrder (params) {
+  return http.post('/admin/order/closeRegisterOrder', { data: params })
+}
+
 // 门票补打
 export function reprintTicket (params) {
   return http.post('/admin/order/secondPrintTicket', { data: params })

+ 202 - 41
src/pages/queryReport/salesQuery.vue

@@ -177,6 +177,23 @@
           </el-option>
         </el-select>
       </el-form-item>
+      <el-form-item
+        label="登记订单"
+        prop="isRegisterOrder"
+      >
+        <el-select
+          v-model="form.isRegisterOrder"
+          clearable
+          placeholder="请选择"
+        >
+          <el-option
+            label="登记订单"
+            :value="1"></el-option>
+          <el-option
+            label="正常出票"
+            :value="0"></el-option>
+        </el-select>
+      </el-form-item>
       <el-form-item
         label="票种"
         prop="ticketTypeIdList"
@@ -446,6 +463,9 @@
             <div>
               {{ scope.row.createTime | formatTime }}
             </div>
+            <div>
+              支付时间:{{ scope.row.payTime | formatTime }}
+            </div>
           </template>
         </el-table-column>
         <el-table-column
@@ -545,43 +565,57 @@
               @click="showOrderDetail(scope.row)">
               详情
             </el-link>
-            <el-link
-              type="primary"
-              v-if="hasPermission('order-update')"
-              @click="editOrder(scope.row)">
-              修改
-            </el-link>
-            <el-link
-              type="primary"
-              v-if="hasPermission('manual-print')"
-              @click="printOrder(scope.row)">
-              取票
-            </el-link>
-            <br>
-            <el-link
-              type="primary"
-              v-if="hasPermission('manual-check')"
-              @click="checkOrder(scope.row)">
-              核销
-            </el-link>
-            <el-link
-              type="primary"
-              v-if="hasPermission('manual-cancel')"
-              @click="refundOrder(scope.row)">
-              退单
-            </el-link>
-            <el-link
-              type="primary"
-              v-if="hasPermission('manual-part-cancel')"
-              @click="partRefundOrder(scope.row)">
-              部分退单
-            </el-link>
-            <el-link
-              type="primary"
-              v-if="hasPermission('manual-second-print')"
-              @click="secondPrint(scope.row)">
-              补打
-            </el-link>
+            <template v-if="isRegisterPending(scope.row)">
+              <el-link
+                type="primary"
+                @click="handleConfirmTicket(scope.row)">
+                确认出票
+              </el-link>
+              <el-link
+                type="danger"
+                @click="handleCloseTicket(scope.row)">
+                关闭
+              </el-link>
+            </template>
+            <template v-else>
+              <el-link
+                type="primary"
+                v-if="hasPermission('order-update')"
+                @click="editOrder(scope.row)">
+                修改
+              </el-link>
+              <el-link
+                type="primary"
+                v-if="hasPermission('manual-print')"
+                @click="printOrder(scope.row)">
+                取票
+              </el-link>
+              <br>
+              <el-link
+                type="primary"
+                v-if="hasPermission('manual-check')"
+                @click="checkOrder(scope.row)">
+                核销
+              </el-link>
+              <el-link
+                type="primary"
+                v-if="hasPermission('manual-cancel')"
+                @click="refundOrder(scope.row)">
+                退单
+              </el-link>
+              <el-link
+                type="primary"
+                v-if="hasPermission('manual-part-cancel')"
+                @click="partRefundOrder(scope.row)">
+                部分退单
+              </el-link>
+              <el-link
+                type="primary"
+                v-if="hasPermission('manual-second-print')"
+                @click="secondPrint(scope.row)">
+                补打
+              </el-link>
+            </template>
             <!--
             <el-link
               type="primary"
@@ -620,6 +654,28 @@
 
     <OrderDetail ref="orderDetail"></OrderDetail>
 
+    <el-dialog
+      title="请扫码支付"
+      :visible.sync="payCodeDialogVisible"
+      :close-on-click-modal="false"
+      append-to-body
+      width="420px">
+      <el-input
+        autofocus
+        ref="payCodeInputRef"
+        v-model="payCode"
+        placeholder="请扫/输入付款码"></el-input>
+      <div slot="footer">
+        <el-button @click="payCodeDialogVisible = false; payCode = ''">取消</el-button>
+        <el-button
+          type="primary"
+          :loading="registerConfirming"
+          @click="submitPayCode">
+          确定
+        </el-button>
+      </div>
+    </el-dialog>
+
     <el-dialog
       title="选择导出列"
       :visible.sync="dialogVisible"
@@ -1786,7 +1842,7 @@
 
 <script>
 /* eslint-disable no-unused-vars */
-import { apiOrderList, pickInvoice, getInvoice, cancelOrder, reprintTicket, checkTickets, updateOrder, getSaleChannelList, getSingleOrder, printTickets, exportFinanceReport } from '@/api/order'
+import { apiOrderList, pickInvoice, getInvoice, cancelOrder, reprintTicket, checkTickets, updateOrder, getSaleChannelList, getSingleOrder, printTickets, exportFinanceReport, confirmRegisterOrder, closeRegisterOrder } from '@/api/order'
 import { orderStatusDic, ticketStatusDic, channelList, papersType, orderCategories } from '@/assets/staticData'
 import { getPayStatus } from '@/utils/index'
 // import Ellipsis from '@/components/Ellipsis'
@@ -1958,6 +2014,7 @@ export default {
         orderStatus: '', // 订单状态
         payStatus: '', // 支付状态
         ticketStatus: '', // 门票状态
+        isRegisterOrder: '', // 登记订单
         visitorName: '', // 游客姓名
         visitorPhone: '', // 游客手机
         visitorIdentify: '', // 游客身份证
@@ -2049,7 +2106,13 @@ export default {
       },
       ticketNoSearch: '',
       summaryReportDialogVisible: false,
-      summaryReportDate: [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
+      summaryReportDate: [moment().format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
+      // 登记订单确认出票
+      payCode: '',
+      payCodeDialogVisible: false,
+      currentRegisterOrder: null,
+      registerConfirming: false,
+      registerPollTimer: null
     }
   },
   filters: {
@@ -2149,6 +2212,89 @@ export default {
     hasPermission (key) {
       return !!this.permissionList.some(item => item.code === key)
     },
+    // 未支付的登记订单:只显示 详情/确认出票/关闭
+    isRegisterPending (row) {
+      return row.isRegisterOrder === 1 && row.payStatus === 'WAIT_PAY'
+    },
+    async handleConfirmTicket (row) {
+      // 列表行不一定返回 payType,取订单详情拿到权威的 payType 再决定支付分支
+      let detail = row
+      try {
+        const res = await getSingleOrder(row.id)
+        detail = res?.data || row
+      } catch (e) {
+        detail = row
+      }
+      if (detail.payType === 'NO_PAY') {
+        this.doConfirmRegisterOrder(detail)
+      } else if (detail.payType === 'B_SCAN_C_PAY') {
+        this.currentRegisterOrder = detail
+        this.payCode = ''
+        this.payCodeDialogVisible = true
+      } else {
+        this.$message.warning('暂不支持该支付渠道的登记确认,请联系管理员')
+      }
+    },
+    submitPayCode () {
+      if (!this.payCode) {
+        this.$message.error('请输入付款码')
+        return
+      }
+      this.payCodeDialogVisible = false
+      const row = this.currentRegisterOrder
+      const qrcode = this.payCode
+      this.payCode = ''
+      this.doConfirmRegisterOrder(row, qrcode)
+    },
+    doConfirmRegisterOrder (row, qrcode) {
+      if (!row) return
+      this.registerConfirming = true
+      const params = { orderId: row.id }
+      if (qrcode) {
+        params.qrcode = qrcode
+      }
+      confirmRegisterOrder(params).then(() => {
+        this.startRegisterPayPolling(row)
+      }).finally(() => {
+        this.registerConfirming = false
+      })
+    },
+    startRegisterPayPolling (row) {
+      let count = 0
+      this.registerPollTimer && clearTimeout(this.registerPollTimer)
+      const loop = () => {
+        if (++count > 150) {
+          this.$message.warning('支付确认超时,请刷新列表查看订单状态')
+          return
+        }
+        getSingleOrder(row.id).then(res => {
+          if (res.data?.payStatus === 'PAYED') {
+            this.$message.success('出票成功')
+            this.getOrderList()
+          } else if (res.data?.payStatus === 'CLOSED') {
+            this.$message.error('交易失败,订单已关闭')
+            this.getOrderList()
+          } else {
+            this.registerPollTimer = setTimeout(loop, 2000)
+          }
+        }).catch(() => {
+          this.registerPollTimer = setTimeout(loop, 2000)
+        })
+      }
+      loop()
+    },
+    handleCloseTicket (row) {
+      this.$confirm('确定关闭该登记订单吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        closeRegisterOrder({ orderId: row.id }).then(() => {
+          this.$message.success('操作成功')
+          this.getOrderList()
+        }).catch(() => {})
+      }).catch(() => {})
+    },
     reset () {
       this.$refs.form.resetFields()
       this.form.unitPriceBegin = undefined
@@ -2274,7 +2420,11 @@ export default {
     dataExport () {
       this.form.export = true
       // this.form.exportDetail = true
-      apiOrderList(this.form).then(() => {
+      const params = { ...this.form }
+      if (!params.isRegisterOrder) {
+        delete params.isRegisterOrder
+      }
+      apiOrderList(params).then(() => {
         this.$message.success('导出成功。')
         this.goToDownload()
       }, () => {
@@ -2311,6 +2461,10 @@ export default {
       })
     },
     handleExport (params) {
+      // 登记订单:未选择时不传,避免空串歧义
+      if (!params.isRegisterOrder) {
+        delete params.isRegisterOrder
+      }
       apiOrderList(params).then(() => {
         this.$message.success('导出成功。')
         this.goToDownload()
@@ -2334,7 +2488,13 @@ export default {
         this.$message.warning('单价区间起始金额不能大于终止金额')
       }
 
-      apiOrderList(this.form).then(res => {
+      // 登记订单:未选择时不传,避免空串歧义
+      const params = { ...this.form }
+      if (!params.isRegisterOrder) {
+        delete params.isRegisterOrder
+      }
+
+      apiOrderList(params).then(res => {
         this.total = res.data.total
 
         // const list = []
@@ -2678,6 +2838,7 @@ export default {
   },
   beforeDestroy () {
     EventBus.$off('activeTag')
+    this.registerPollTimer && clearTimeout(this.registerPollTimer)
   }
 }
 </script>

+ 25 - 0
src/pages/sellManage/common/confirmMixin.js

@@ -43,6 +43,11 @@ export default {
     currentTicket: {
       type: Object,
       default: () => null
+    },
+    // 登记出票:创单传 isRegisterOrder=1,不做支付与轮询
+    isRegisterOrder: {
+      type: Boolean,
+      default: false
     }
   },
   components: {
@@ -185,6 +190,11 @@ export default {
     }),
     handleSubmit (qrcode, cardInfo) {
       console.log(this.payType)
+      // 登记出票:跳过全部支付流程,创单即完成
+      if (this.isRegisterOrder) {
+        return this.submitRegister()
+      }
+
       // 西宁景区储值卡支付预留
       if (this.payType === 'VALUECARD' && this.scenicName === '西宁景区') {
         this.setParams()
@@ -275,6 +285,15 @@ export default {
       this.payCodeDialogVisible = false
       this.payCode = ''
     },
+    submitRegister () {
+      // 防止重复提交
+      if (this.submitDisable) return
+      this.submitDisable = true
+      this.setParams()
+      const params = this.params
+      params.isRegisterOrder = 1
+      this.createOrder(params)
+    },
     createOrder (params, isOnlinePay = false) {
       // if (this.payType === 'B_SCAN_C_PAY' && !isOnlinePay) {
       //   this.payCodeDialogVisible = true
@@ -313,6 +332,12 @@ export default {
           this.$log.warn(`下单成功,订单号ID:${order.id}`)
           this.createOrderStatus = 1
           this.orderTempInfo = order
+          // 登记出票:创单即完成,不发起支付、不轮询支付状态
+          if (this.isRegisterOrder) {
+            EventBus.$emit('orderCreated', order)
+            this.handleCreateSuccess(params, order)
+            return
+          }
           handlePay(this.params, order, this, () => { })
           if (this.payStatus !== 1) {
             this.getSingleOrder(order, params)

+ 1 - 1
src/pages/sellManage/retail/Confirm.vue

@@ -4,7 +4,7 @@
     :close-on-press-escape="false"
     :visible="visible"
     :before-close="handleClose"
-    title="出票确认"
+    :title="isRegisterOrder ? '登记出票确认' : '出票确认'"
     width="80%">
     <el-form
       v-loading="submitDisable"

+ 23 - 1
src/pages/sellManage/retail/OrderInfo.vue

@@ -70,9 +70,17 @@
             type="primary"
             class="danger-btn item"
             :disabled="value.length === 0 || !payChannel"
-            @click="handleConfirm">
+            @click="handleNormalConfirm">
             确认出票
           </el-button>
+          <el-button
+            v-if="hasPermission('order-register-create')"
+            type="primary"
+            class="danger-btn item"
+            :disabled="value.length === 0 || !payChannel"
+            @click="handleRegisterConfirm">
+            登记出票
+          </el-button>
           <el-button
             type="primary"
             class="danger-btn item"
@@ -196,6 +204,7 @@
       :total-count="totalCount"
       :pay-channel="payChannel"
       :current-ticket="currentTicket"
+      :is-register-order="registerMode"
       @complete="handleComplete"
       ref="confirm"></Confirm>
     <!-- 图片备注 -->
@@ -381,6 +390,7 @@ export default {
       payChannel: '',
       actualMoney: 0,
       createOrderRemark: '',
+      registerMode: false,
       formData: {},
       pictureRemarks: [{
         idKey: randomString(),
@@ -473,7 +483,19 @@ export default {
     handleAutoPrintChange (val) {
       this.$localStore.set('autoPrint', val)
     },
+    handleNormalConfirm () {
+      this.registerMode = false
+      this.handleConfirm()
+    },
+    handleRegisterConfirm () {
+      this.registerMode = true
+      this.handleConfirm()
+    },
+    hasPermission (key) {
+      return !!((this.$store.state.user.menuList || []).some(item => item.code === key))
+    },
     handleComplete () {
+      this.registerMode = false
       this.$emit('clear')
       this.createOrderRemark = ''
       this.$localStore.get('defaultPayWay') && this.setPayWay()