LaveyD hai 8 meses
pai
achega
c0c7de032b

+ 9 - 3
src/api/queryReport.js

@@ -29,6 +29,12 @@ export function exportDailyOfflineSale (params) {
 export function getCheckerAccessStatistics (params) {
   return http.post('/admin/statistics/checkerAccessStatistics', { data: params })
 }
+
+// 检票记录
+export function getCheckList (params) {
+  return http.post('/admin/order/listUsed', { data: params })
+}
+
 // 检票核销统计
 export function getCheckerVerifyStatistics (params) {
   return http.post('/admin/statistics/orderCheckStatistics', { data: params })
@@ -42,9 +48,9 @@ export function exportCheckStatisticsInTicketCount (params) {
 export function exportModifyOrderStatistics (params) {
   return http.post('/exportMission/exportModifyOrderStatistics', { data: params })
 }
-// 导出退票统计
-export function exportCancelOrderStatistics (params) {
-  return http.post('/exportMission/exportCancelList', { data: params })
+// 退票统计
+export function getCancelOrderStatistics (params) {
+  return http.post('/admin/statistics/orderCancelStatistics', { data: params })
 }
 
 // 退票记录

+ 269 - 187
src/pages/queryReport/checkQuery.vue

@@ -5,76 +5,200 @@
       ref="form"
       :model="form"
       :inline="true"
-      label-width="70px"
-    >
+      label-width="100px">
       <div class="block-title">
         查询条件
       </div>
       <el-form-item
-        label="核销起始时间"
-        prop="checkTimeBegin"
-        label-width="150px"
+        label="关键词"
+        prop="searchKeywords"
+      >
+        <ReaderInput
+          style="width:320px !important"
+          v-model="form.searchKeywords"
+          placeholder="订单号/票号/游客姓名/电话/证件号"
+          clearable
+          @change="form.searchKeywords=$event.IDNumber,form.name=$event.Name"
+          @input="setSearchKeywords"
+        ></ReaderInput>
+      </el-form-item>
+      <el-form-item
+        label="订单类型"
+        prop="orderCategory"
+      >
+        <el-select
+          v-model="form.orderCategory"
+          placeholder="请选择"
+          clearable
+          filterable>
+          <el-option
+            v-for="item in orderCategories"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="支付方式"
+        prop="payChannelList">
+        <el-select
+          v-model="form.payChannelList"
+          multiple
+          clearable
+          filterable>
+          <el-option
+            v-for="item in payChannelOptions"
+            :key="item"
+            :label="item"
+            :value="item">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="销售来源"
+        prop="otaSourceNameList">
+        <el-select
+          v-model="form.otaSourceNameList"
+          multiple
+          clearable
+          filterable>
+          <el-option
+            v-for="item in otaSourceList"
+            :key="item"
+            :label="item"
+            :value="item">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="订单状态"
+        prop="orderStatus"
+      >
+        <el-select
+          v-model="form.orderStatus"
+          clearable
+          placeholder="请选择"
+        >
+          <el-option
+            label="全部"
+            value=""></el-option>
+          <el-option
+            v-for="item in orderStatusDic"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="订单号"
+        prop="orderNo">
+        <el-input v-model="form.orderNo"></el-input>
+      </el-form-item>
+      <el-form-item
+        label="票号"
+        prop="ticketNo">
+        <QRReader v-model="form.ticketNo"></QRReader>
+      </el-form-item>
+      <el-form-item
+        label="票种"
+        prop="ticketTypeIdList">
+        <el-select
+          v-model="form.ticketTypeIdList"
+          clearable
+          placeholder="请选择">
+          <el-option
+            label="全部"
+            value=""
+          ></el-option>
+          <el-option
+            v-for="item in ticketTypeList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="身份证号"
+        prop="visitorIdentify">
+        <ReaderInput
+          type="ID"
+          v-model="form.visitorIdentify"></ReaderInput>
+      </el-form-item>
+      <el-form-item
+        label="游客手机"
+        prop="visitorPhone"
+      >
+        <el-input v-model="form.visitorPhone"></el-input>
+      </el-form-item>
+      <el-form-item
+        label="游客姓名"
+        prop="visitorName"
+      >
+        <el-input v-model="form.visitorName"></el-input>
+      </el-form-item>
+      <el-form-item
+        label="起始时间"
+        prop="timeBegin"
       >
         <el-date-picker
-          v-model="form.checkTimeBegin"
+          v-model="form.timeBegin"
           type="datetime"
           placeholder="选择日期时间"
         >
         </el-date-picker>
       </el-form-item>
-
       <el-form-item
-        label="核销截止时间"
-        prop="checkTimeEnd"
-        label-width="150px"
+        label="截止时间"
+        prop="timeEnd"
       >
         <el-date-picker
           default-time="23:59:59"
-          v-model="form.checkTimeEnd"
+          v-model="form.timeEnd"
           type="datetime"
           placeholder="选择日期时间"
         >
         </el-date-picker>
       </el-form-item>
-
       <el-form-item
-        label="票种"
-        prop="ticketTypeIdList"
+        label="售票员"
+        prop="adminIdList"
       >
         <el-select
-          v-model="form.ticketTypeIdList"
-          clearable
+          v-model="form.adminIdList"
           multiple
+          clearable
           placeholder="请选择"
-        >
-          <el-option
-            :value="[]"
-            label="全部"></el-option>
+          filterable>
           <el-option
-            v-for="item in ticketTypeList"
+            v-for="item in accountList"
             :key="item.id"
-            :label="item.name"
             :value="item.id"
-          >
+            :label="item.loginName">
           </el-option>
         </el-select>
       </el-form-item>
       <el-form-item
-        label="销售来源"
-        prop="otaSourceNameList">
+        label="售卖自助机"
+        prop="saleTermIdList"
+      >
         <el-select
-          v-model="form.otaSourceNameList"
+          v-model="form.saleTermIdList"
           multiple
+          clearable
+          placeholder="请选择"
           filterable>
           <el-option
-            v-for="item in otaSourceList"
-            :key="item"
-            :label="item"
-            :value="item">
+            v-for="item in termList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name">
           </el-option>
         </el-select>
       </el-form-item>
-
       <div class="btn-wrap">
         <el-button
           @click="reset"
@@ -84,261 +208,219 @@
         <el-button
           :disabled="loading"
           type="primary"
-          @click="getCheckList(true)"
+          @click="getList"
         >
           搜索
         </el-button>
       </div>
     </el-form>
-    <!-- 注意,不应当在@click的getCheckList(true)加个分号然后再写Storage的相关操作,实测可能会因为第一句未执行成功导致第二句不执行 -->
+
     <div class="table-box">
       <!-- <div class="block-title">
-        核销统计
+        退票记录
       </div> -->
-      <!-- <el-table
+      <el-table
         border
         stripe
         v-loading="loading"
-        :data="orderTableData"
-        key="orderTable"
-        v-if="queryType === 'order'"
-      >
-        <el-table-column type="expand">
-          <template slot-scope="scope">
-            <el-table :data="scope.row.check_info">
-              <el-table-column
-                prop="ticketNo"
-                label="票号"
-              ></el-table-column>
-              <el-table-column
-                prop="scenic_name"
-                label="景区"
-              ></el-table-column>
-              <el-table-column
-                prop="checker_channel_group_name"
-                label="通道组"
-              ></el-table-column>
-              <el-table-column
-                prop="checker_channel_name"
-                label="通道"
-              ></el-table-column>
-              <el-table-column
-                prop="checker_name"
-                label="检票设备"
-              ></el-table-column>
-              <el-table-column
-                prop="ip"
-                label="设备IP"
-              ></el-table-column>
-              <el-table-column label="检票时间">
-                <template slot-scope="checkScope">
-                  {{ checkScope.row.checkTime | formatTime }}
-                </template>
-              </el-table-column>
-              <el-table-column
-                prop="has_checked_num"
-                label="已检次数"
-              ></el-table-column>
-            </el-table>
-          </template>
-        </el-table-column>
+        :data="tableData">
         <el-table-column
-          width="160"
+          width="180"
           prop="orderNo"
           label="订单号"
         >
         </el-table-column>
         <el-table-column
-          prop="buyerName"
-          label="预订人"
+          width="180"
+          prop="ticketNo"
+          label="票号"
         >
         </el-table-column>
         <el-table-column
-          prop="buyerPhone"
-          label="手机号"
+          min-width="100"
+          prop="cancel_pay_channel"
+          label="退票方式"
         >
         </el-table-column>
         <el-table-column
-          prop="buyerIdentify"
-          label="身份证号"
+          min-width="140"
+          prop="cancel_remark"
+          label="备注"
         >
         </el-table-column>
         <el-table-column
-          width="100"
+          width="160"
           prop="ticketTypeName"
-          label="票型"
-        >
-        </el-table-column>
-        <el-table-column
-          width="80"
-          prop="sum_count"
-          label="总票数"
+          label="票种"
         >
         </el-table-column>
         <el-table-column
-          width="80"
-          prop="check_count"
-          label="已检"
+          prop="manager"
+          label="退票员"
         >
         </el-table-column>
         <el-table-column
-          width="80"
-          prop="cancel_count"
-          label="已退"
+          prop="adminName"
+          label="操作员"
         >
         </el-table-column>
-      </el-table> -->
-
-      <el-table
-        v-loading="loading"
-        :data="ticketTableData"
-        key="ticketTable"
-      >
         <el-table-column
-          prop="otaSourceName"
-          label="订单渠道"
+          width="160"
+          label="售票时间"
         >
+          <template slot-scope="props">
+            <span>{{ props.row.buy_date | formatTime }}</span>
+          </template>
         </el-table-column>
         <el-table-column
-          prop="ticketTypeName"
-          label="票种"
+          width="140"
+          label="检票时间"
         >
+          <template slot-scope="scope">
+            <span v-if="!scope.row.checkTime.startsWith('1970')">
+              {{ scope.row.checkTime | formatTime }}
+            </span>
+          </template>
         </el-table-column>
         <el-table-column
-          prop="unitPrice"
-          label="单价(元)"
+          width="160"
+          label="退票时间"
         >
+          <template slot-scope="props">
+            <span>{{ props.row.cancelTime | formatTime }}</span>
+          </template>
         </el-table-column>
         <el-table-column
-          prop="checkNum"
-          label="检票人数"
+          width="120"
+          prop="cancel_price"
+          label="退款金额"
         >
         </el-table-column>
         <el-table-column
-          prop="checkPrice"
-          label="检票金额(元)"
+          label="订单操作"
+          width="120"
+          fixed="right"
         >
+          <template slot-scope="scope">
+            <el-link
+              v-if="scope.row.boc_cancel_trade_no"
+              type="primary"
+              @click="$refs.orderDetail.show(scope.row)">
+              退票支付详情
+            </el-link>
+          </template>
         </el-table-column>
       </el-table>
       <el-pagination
         background
         :current-page.sync="form.pageNum"
-        @current-change="getCheckList()"
+        @current-change="getList()"
         layout="total, prev, pager, next"
         :total="total"
       >
       </el-pagination>
     </div>
+
+    <DetailModal ref="orderDetail"></DetailModal>
   </div>
 </template>
 
 <script>
-import { getScenic, getTicketTypeList } from '@/api/ticketType'
-import { apiCheckList, getSaleChannelList } from '@/api/order'
+import { getCheckList } from '@/api/queryReport'
+import { getSaleChannelList } from '@/api/order'
+import ReaderInput from '@/components/ReaderInput'
 import moment from 'moment'
+import DetailModal from './checkQuery/DetailModal'
+import { orderStatusDic, ticketStatusDic, orderCategories } from '@/assets/staticData'
 
 export default {
   name: 'checkQuery',
   components: {
-  },
-  computed: {
-    salesList () {
-      return this.$store.state.user.salesList
-    },
-    userScenic () {
-      return this.$store.state.app.account.managerScenicMatrix ? this.$store.state.app.account.managerScenicMatrix : this.scenicList
-    },
-    ticketTypeList () {
-      return this.$store.state.app.ticketTypeList
-    }
+    ReaderInput,
+    DetailModal
   },
   data () {
     return {
+      orderStatusDic,
+      orderCategories,
+      ticketStatusDic,
+      otaSourceList: [],
       form: {
-        ticketTypeIdList: [], // 票种ID
-        otaSourceNameList: [],
-        checkTimeBegin: new Date(moment().subtract(7, 'day').format('YYYY-MM-DD HH:mm:ss')),
-        checkTimeEnd: new Date(moment().format('YYYY-MM-DD HH:mm:ss')),
+        timeBegin: new Date(moment().startOf('day').valueOf()),
+        timeEnd: new Date(moment().endOf('day').valueOf()),
+        visitorPhone: '',
+        visitorName: '',
+        visitorIdentify: '',
+        orderCategory: '',
+        orderNo: '',
+        partnerOrderNo: '',
+        payChannelList: [],
+        orderStatus: '',
+        ticketTypeIdList: [],
         pageNum: 1,
-        pageSize: 10
+        pageSize: 10,
+        ticketNo: '',
+        searchKeywords: ''
       },
-      otaSourceList: [],
-      scenicList: [],
-      channelGroupOri: [],
-      channelGroupList: [],
-      channelList: [],
-      deviceList: [],
-      // ticketTypeList: [],
-      orderTableData: [],
-      ticketTableData: [],
-      queryType: 'order', // 按订单还是按票
+      tableData: [],
       total: 0,
       loading: false
     }
   },
-  filters: {
-    limitTimes (input) {
-      return input === -1 ? '不限' : input
+  computed: {
+    accountList () {
+      return this.$store.state.app.accountList
+    },
+    termList () {
+      return this.$store.state.app.termList
+    },
+    ticketTypeList () {
+      const { ticketTypeList } = this.$store.state.app
+      const { orderCategory } = this.form
+      return orderCategory ? ticketTypeList.filter(item => item.category === orderCategory) : ticketTypeList
+    },
+    payChannelOptions () {
+      return this.$store.getters.payChannelOptions
     }
   },
-  created () {
-    // this.getScenicList()
-    // this.initChannelGroup()
-    // this.getTicketTypeList()
+  async created () {
     this.getSaleChannelList()
-    this.getCheckList(true) // 初始化查询
+    this.getList()
   },
   methods: {
-    reset () {
-      this.$refs.form.resetFields()
-    },
-    // 获取景点列表
-    getScenicList () {
-      getScenic().then(res => {
-        this.scenicList = res?.data.children.map(item => item.data)
-      })
-    },
     getSaleChannelList () {
       getSaleChannelList().then(res => {
         this.otaSourceList = res.data
       })
     },
-    // 获取票种列表
-    getTicketTypeList () {
-      getTicketTypeList({
-        pageNum: 1,
-        pageSize: -1
-      }).then(res => {
-        console.log('票种列表', res)
-      })
+    reset () {
+      this.$refs.form.resetFields()
     },
-    getCheckList (goFirst) {
+    setSearchKeywords (val) {
+      this.form.searchKeywords = val
+    },
+    getList () {
       this.loading = true
-      goFirst && (this.form.pageNum = 1)
-
-      this.form.checkTimeBegin = moment(this.form.checkTimeBegin).format('YYYY-MM-DD HH:mm:ss')
-      this.form.checkTimeEnd = moment(this.form.checkTimeEnd).format('YYYY-MM-DD HH:mm:ss')
 
-      if (!this.form.otaSourceNameList) {
-        this.form.otaSourceNameList = []
+      if (this.form.timeBegin) {
+        this.form.timeBegin = moment(this.form.timeBegin).format('YYYY-MM-DD HH:mm:ss')
+      } else {
+        this.form.timeBegin = ''
       }
 
-      if (!this.form.ticketTypeIdList) {
-        this.form.ticketTypeIdList = []
+      if (this.form.timeEnd) {
+        this.form.timeEnd = moment(this.form.timeEnd).format('YYYY-MM-DD HH:mm:ss')
+      } else {
+        this.form.timeEnd = ''
       }
 
-      apiCheckList(this.form).then(res => {
-        // this.total = res.data.total
-        this.ticketTableData = res.data || []
+      getCheckList(this.form).then(res => {
+        this.total = res.data.total || 0
+        this.tableData = res.data.records || []
       }).finally(() => {
         this.loading = false
       })
     }
-    /**
-     * 如果 goFirst 为 true,那么这个条件语句会执行,并且会将 this.form.pageNum 的值设置为 1,也就是将当前页码设置为 1。
-     * 假设这段代码的作用是用于实现分页功能,其中 goFirst 表示是否需要跳转到第一页,this.form.pageNum 表示当前页码。在某些情况下,可能需要在执行一些操作后,强制返回到第一页重新加载数据,那么可以设置 goFirst 参数为 true,使得页面先跳转到第一页,然后再执行其它操作。这样可以确保数据始终从第一页开始加载,避免了因为操作产生的历史遗留问题。
-     * 总之,如果 goFirst 为 true,那么这段代码将会影响当前页码的值,使其变为 1。如果 goFirst 为 false,这段代码不会有任何影响,当前页码的值仍然保持原来的状态。
-     */
   }
 }
 </script>

+ 50 - 0
src/pages/queryReport/checkQuery/DetailModal.vue

@@ -0,0 +1,50 @@
+<template>
+  <el-dialog
+    title="退票支付详情"
+    :visible.sync="visible"
+    width="80%"
+    @close="visible=false">
+    <el-table
+      v-if="data && data.boc_cancel_trade_no"
+      border
+      :data="[getPayResponse(data.boc_cancel_trade_no)]">
+      <el-table-column
+        :prop="key"
+        :key="key"
+        :label="key"
+        v-for="(val,key) in getPayResponse(data.boc_cancel_trade_no)"
+      >
+      </el-table-column>
+    </el-table>
+    <span slot="footer">
+      <el-button @click="visible= false">取消</el-button>
+      <el-button
+        type="primary"
+        @click="visible= false">确定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { getPayResponse } from '@/utils/posUtils'
+
+export default {
+  data () {
+    return {
+      visible: false,
+      data: ''
+    }
+  },
+  methods: {
+    getPayResponse,
+    show (data) {
+      this.data = data
+      this.visible = true
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 160 - 40
src/pages/queryReport/refundQuery/RefundQuery.vue

@@ -5,10 +5,93 @@
       ref="form"
       :model="form"
       :inline="true"
-      label-width="70px">
+      label-width="100px">
       <div class="block-title">
         查询条件
       </div>
+      <el-form-item
+        label="关键词"
+        prop="searchKeywords"
+      >
+        <ReaderInput
+          style="width:320px !important"
+          v-model="form.searchKeywords"
+          placeholder="订单号/票号/游客姓名/电话/证件号"
+          clearable
+          @change="form.searchKeywords=$event.IDNumber,form.name=$event.Name"
+          @input="setSearchKeywords"
+        ></ReaderInput>
+      </el-form-item>
+      <el-form-item
+        label="订单类型"
+        prop="orderCategory"
+      >
+        <el-select
+          v-model="form.orderCategory"
+          placeholder="请选择"
+          clearable
+          filterable>
+          <el-option
+            v-for="item in orderCategories"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="支付方式"
+        prop="payChannelList">
+        <el-select
+          v-model="form.payChannelList"
+          multiple
+          clearable
+          filterable>
+          <el-option
+            v-for="item in payChannelOptions"
+            :key="item"
+            :label="item"
+            :value="item">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="销售来源"
+        prop="otaSourceNameList">
+        <el-select
+          v-model="form.otaSourceNameList"
+          multiple
+          clearable
+          filterable>
+          <el-option
+            v-for="item in otaSourceList"
+            :key="item"
+            :label="item"
+            :value="item">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="订单状态"
+        prop="orderStatus"
+      >
+        <el-select
+          v-model="form.orderStatus"
+          clearable
+          placeholder="请选择"
+        >
+          <el-option
+            label="全部"
+            value=""></el-option>
+          <el-option
+            v-for="item in orderStatusDic"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
       <el-form-item
         label="订单号"
         prop="orderNo">
@@ -80,7 +163,42 @@
         >
         </el-date-picker>
       </el-form-item>
-
+      <el-form-item
+        label="售票员"
+        prop="adminIdList"
+      >
+        <el-select
+          v-model="form.adminIdList"
+          multiple
+          clearable
+          placeholder="请选择"
+          filterable>
+          <el-option
+            v-for="item in accountList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.loginName">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item
+        label="售卖自助机"
+        prop="saleTermIdList"
+      >
+        <el-select
+          v-model="form.saleTermIdList"
+          multiple
+          clearable
+          placeholder="请选择"
+          filterable>
+          <el-option
+            v-for="item in termList"
+            :key="item.id"
+            :value="item.id"
+            :label="item.name">
+          </el-option>
+        </el-select>
+      </el-form-item>
       <div class="btn-wrap">
         <el-button
           @click="reset"
@@ -142,7 +260,7 @@
         >
         </el-table-column>
         <el-table-column
-          prop="real_manager"
+          prop="adminName"
           label="操作员"
         >
         </el-table-column>
@@ -169,7 +287,7 @@
           label="退票时间"
         >
           <template slot-scope="props">
-            <span>{{ props.row.cancel_time | formatTime }}</span>
+            <span>{{ props.row.cancelTime | formatTime }}</span>
           </template>
         </el-table-column>
         <el-table-column
@@ -209,11 +327,11 @@
 
 <script>
 import { getCancelOrderList } from '@/api/queryReport'
-import { getTicketTypeList } from '@/api/ticketType'
-import { getAccountList } from '@/api/systemSetting/account'
+import { getSaleChannelList } from '@/api/order'
 import ReaderInput from '@/components/ReaderInput'
 import moment from 'moment'
 import DetailModal from './DetailModal'
+import { orderStatusDic, ticketStatusDic, orderCategories } from '@/assets/staticData'
 
 export default {
   name: 'refundQuery',
@@ -223,7 +341,10 @@ export default {
   },
   data () {
     return {
-      ticketTypeList: [],
+      orderStatusDic,
+      orderCategories,
+      ticketStatusDic,
+      otaSourceList: [],
       form: {
         timeBegin: new Date(moment().startOf('day').valueOf()),
         timeEnd: new Date(moment().endOf('day').valueOf()),
@@ -239,64 +360,63 @@ export default {
         pageNum: 1,
         pageSize: 10,
         ticketNo: '',
-        searchKeywords: '',
-        orderByKeyWords: 'cancel_time'
+        searchKeywords: ''
       },
-      accountList: [],
       tableData: [],
       total: 0,
       loading: false
     }
   },
+  computed: {
+    accountList () {
+      return this.$store.state.app.accountList
+    },
+    termList () {
+      return this.$store.state.app.termList
+    },
+    ticketTypeList () {
+      const { ticketTypeList } = this.$store.state.app
+      const { orderCategory } = this.form
+      return orderCategory ? ticketTypeList.filter(item => item.category === orderCategory) : ticketTypeList
+    },
+    payChannelOptions () {
+      return this.$store.getters.payChannelOptions
+    }
+  },
   async created () {
-    this.getTicketTypeList()
-    await this.getAccountList()
+    this.getSaleChannelList()
     this.getList()
   },
   methods: {
+    getSaleChannelList () {
+      getSaleChannelList().then(res => {
+        this.otaSourceList = res.data
+      })
+    },
     reset () {
       this.$refs.form.resetFields()
     },
-    // 获取票种列表
-    getTicketTypeList () {
-      return getTicketTypeList({
-        pageNum: 1,
-        pageSize: -1
-      }).then(res => {
-        this.ticketTypeList = res.list
-      })
-    },
-    getAccountList () {
-      return getAccountList({
-        pageNum: 1,
-        pageSize: -1
-      }).then(res => {
-        this.accountList = res.list
-      })
+    setSearchKeywords (val) {
+      this.form.searchKeywords = val
     },
     getList () {
       this.loading = true
 
       if (this.form.timeBegin) {
         this.form.timeBegin = moment(this.form.timeBegin).format('YYYY-MM-DD HH:mm:ss')
+      } else {
+        this.form.timeBegin = ''
       }
+
       if (this.form.timeEnd) {
         this.form.timeEnd = moment(this.form.timeEnd).format('YYYY-MM-DD HH:mm:ss')
+      } else {
+        this.form.timeEnd = ''
       }
 
       getCancelOrderList(this.form).then(res => {
-        this.total = res.total
-        res.list.forEach(item => {
-          let m = this.accountList.find(m => m.id === item.cancel_managerId)
-          if (m) {
-            item.manager = m.nickName
-          }
-          let n = this.accountList.find(n => n.id === item.real_cancel_managerId)
-          if (n) {
-            item.real_manager = n.nickName
-          }
-        })
-        this.tableData = res.list
+        this.total = res.data.total || 0
+        this.tableData = res.data.records || []
       }).finally(() => {
         this.loading = false
       })

+ 63 - 51
src/pages/queryReport/refundStatistic.vue

@@ -11,33 +11,34 @@
       </div>
       <el-form-item
         label="起始时间"
-        prop="startDate">
+        prop="cancelTimeBegin">
         <el-date-picker
-          v-model="form.startDate"
+          v-model="form.cancelTimeBegin"
           type="datetime"
           placeholder="选择日期时间">
         </el-date-picker>
       </el-form-item>
       <el-form-item
         label="结束时间"
-        prop="endDate">
+        prop="cancelTimeEnd">
         <el-date-picker
           default-time="23:59:59"
-          v-model="form.endDate"
+          v-model="form.cancelTimeEnd"
           type="datetime"
           placeholder="选择日期时间">
         </el-date-picker>
       </el-form-item>
       <el-form-item
         label="票种"
-        prop="keyWords1">
+        prop="ticketTypeIdList">
         <el-select
-          v-model="form.keyWords1"
+          v-model="form.ticketTypeIdList"
           clearable
           placeholder="请选择">
           <el-option
             label="全部"
-            value=""></el-option>
+            value=""
+          ></el-option>
           <el-option
             v-for="item in ticketTypeList"
             :key="item.id"
@@ -47,27 +48,21 @@
         </el-select>
       </el-form-item>
       <el-form-item
-        label="操作人"
-        prop="keyWords2">
-        <el-input v-model="form.keyWords2"></el-input>
-      </el-form-item>
-
-      <el-form-item
-        label="退款方式"
-        prop="keyWords3">
-        <el-select v-model="form.keyWords3">
-          <el-option
-            label="全部"
-            value=""></el-option>
+        label="销售来源"
+        prop="otaSourceNameList">
+        <el-select
+          v-model="form.otaSourceNameList"
+          multiple
+          clearable
+          filterable>
           <el-option
-            v-for="item in payChannelOptions"
+            v-for="item in otaSourceList"
             :key="item"
             :label="item"
             :value="item">
           </el-option>
         </el-select>
       </el-form-item>
-
       <div class="btn-wrap">
         <el-button
           @click="reportExport">
@@ -97,19 +92,27 @@
         :data="tableData"
         :row-class-name="totalRowClassName">
         <el-table-column
-          type="index"
-          label="#">
+          prop="otaSourceName"
+          label="销售渠道">
         </el-table-column>
         <el-table-column
           prop="ticketTypeName"
           label="票种">
         </el-table-column>
         <el-table-column
-          prop="cancel_count"
+          prop="unitPrice"
+          label="单价">
+        </el-table-column>
+        <el-table-column
+          prop="cancelCount"
           label="退票数量">
         </el-table-column>
         <el-table-column
-          prop="cancel_price"
+          prop="cancelNum"
+          label="退票人数">
+        </el-table-column>
+        <el-table-column
+          prop="cancelPrice"
           label="退票金额">
         </el-table-column>
       </el-table>
@@ -118,9 +121,8 @@
 </template>
 
 <script>
-import { exportCancelOrderStatistics } from '@/api/queryReport'
-import { getCancelOrderStatistics } from '@/api/order'
-import { getTicketTypeList } from '@/api/ticketType'
+import { getCancelOrderStatistics } from '@/api/queryReport'
+import { getSaleChannelList } from '@/api/order'
 import { totalRowClassName } from '@/utils'
 import moment from 'moment'
 
@@ -128,61 +130,71 @@ export default {
   name: 'refundStatistics',
   data () {
     return {
-      ticketTypeList: [],
       form: {
-        'startDate': new Date(moment().format('YYYY-MM-DD') + ' 00:00:00'),
-        'endDate': new Date(moment().format('YYYY-MM-DD') + ' 23:59:59'),
-        'keyWords1': '', // 票种
-        'keyWords2': '', // 操作人
-        'keyWords3': ''
+        cancelTimeBegin: new Date(moment().format('YYYY-MM-DD') + ' 00:00:00'),
+        cancelTimeEnd: new Date(moment().format('YYYY-MM-DD') + ' 23:59:59'),
+        ticketTypeIdList: [], // 票种
+        otaSourceNameList: []
       },
       tableData: [],
+      otaSourceList: [],
       loading: false
     }
   },
   computed: {
+    ticketTypeList () {
+      const { ticketTypeList } = this.$store.state.app
+      const { orderCategory } = this.form
+      return orderCategory ? ticketTypeList.filter(item => item.category === orderCategory) : ticketTypeList
+    },
     payChannelOptions () {
       return this.$store.getters.payChannelOptions
     }
   },
   created () {
-    const searchParams = JSON.parse(sessionStorage.getItem('统计表-退票统计-查询条件'))
-    if (searchParams) {
-    // 如果存在查询条件,则设置到组件的数据中
-      this.form = searchParams // 记住上次搜索条件
-    }
-    this.getTicketTypeList()
+    this.getSaleChannelList()
     this.getList()
   },
   methods: {
     totalRowClassName,
+    getSaleChannelList () {
+      getSaleChannelList().then(res => {
+        this.otaSourceList = res.data
+      })
+    },
     reset () {
       this.$refs.form.resetFields()
     },
+    setTime () {
+      if (this.form.cancelTimeBegin) {
+        this.form.cancelTimeBegin = moment(this.form.cancelTimeBegin).format('YYYY-MM-DD HH:mm:ss')
+      } else {
+        this.form.cancelTimeBegin = ''
+      }
+
+      if (this.form.cancelTimeEnd) {
+        this.form.cancelTimeEnd = moment(this.form.cancelTimeEnd).format('YYYY-MM-DD HH:mm:ss')
+      } else {
+        this.form.cancelTimeEnd = ''
+      }
+    },
     reportExport () {
-      exportCancelOrderStatistics(this.form).then(() => {
+      this.form.export = true
+      this.setTime()
+      getCancelOrderStatistics(this.form).then(() => {
         this.$message.success('导出成功。')
         this.goToDownload()
       }, () => {
         this.$message.success('导出失败。')
       })
     },
-    // 获取票种列表
-    getTicketTypeList () {
-      return getTicketTypeList({
-        pageNum: 1,
-        pageSize: 999
-      }).then(res => {
-        this.ticketTypeList = res.list
-      })
-    },
     getList () {
       this.loading = true
+      this.setTime()
       getCancelOrderStatistics(this.form).then(res => {
         this.tableData = res.data
       }).finally(() => {
         this.loading = false
-        sessionStorage.setItem('统计表-退票统计-查询条件', JSON.stringify(this.form)) // 下次记住
       })
     }
   }

+ 1 - 1
src/pages/queryReport/salesQuery.vue

@@ -149,7 +149,7 @@
         </el-select>
       </el-form-item>
       <el-form-item
-        label="票种列表"
+        label="票种"
         prop="ticketTypeIdList"
       >
         <el-select

+ 1 - 1
src/pages/systemSetting/smallTicket/ticket.js

@@ -284,7 +284,7 @@ export default {
   'groupIndividual': 1,
   'member_id': -1,
   'ota_order_status': '',
-  'cancel_time': '1970-12-31T16:00:00.000+0000',
+  'cancelTime': '1970-12-31T16:00:00.000+0000',
   'buyerIdentify': '',
   'createTime': '2020-10-29T07:06:18.000+0000',
   'is_invoice_picked': 0,

+ 2 - 2
src/pages/ticketSetting/queueLog/index.vue

@@ -138,10 +138,10 @@
           </template>
         </el-table-column>
         <el-table-column
-          prop="cancel_time"
+          prop="cancelTime"
           label="取消时间">
           <template slot-scope="scope">
-            <span v-if="scope.row.cancel_time">{{ moment(scope.row.cancel_time).format('YYYY-MM-DD HH:mm:ss') }}</span>
+            <span v-if="scope.row.cancelTime">{{ moment(scope.row.cancelTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
           </template>
         </el-table-column>
         <el-table-column

+ 193 - 50
src/pages/ticketSetting/ticket/Dialog.vue

@@ -48,6 +48,7 @@
           </el-form-item>
 
           <el-form-item
+            verify
             label="在售状态"
             prop="isSale"
           >
@@ -65,13 +66,7 @@
             label="销售价格"
             prop="price"
           >
-            <el-input-number
-              controls-position="right"
-              v-model="form.price"
-              :min="0"
-              :step="0.01"
-              :precision="2"
-            ></el-input-number>
+            <el-input v-model="form.price"></el-input>
           </el-form-item>
 
           <!-- <el-form-item
@@ -102,6 +97,7 @@
 
           <el-form-item
             v-if="form.category !== 'member'"
+            verify
             label="日期类型"
             prop="useDateType"
           >
@@ -146,6 +142,7 @@
           </el-form-item> -->
           <el-form-item
             v-if="form.category === 'member'"
+            verify
             label="会员时长类型"
             prop="memberUseDateType"
           >
@@ -163,6 +160,7 @@
 
           <el-form-item
             v-if="!(form.category === 'member' && form.memberUseDateType === 2)"
+            verify
             label="使用天数"
             prop="useDays"
           >
@@ -189,7 +187,7 @@
               placeholder="开始日期"
             >
             </el-date-picker>
-            <span>至</span>
+            <span style="margin:0 10px">至</span>
             <el-date-picker
               :editable="false"
               :clearable="false"
@@ -203,6 +201,7 @@
 
           <el-form-item
             v-if="form.category === 'member'"
+            verify
             label="激活方式"
             prop="memberActiveType"
           >
@@ -273,6 +272,7 @@
 
           <el-form-item
             v-if="form.isSaleDateLimit === 1"
+            verify
             label="售卖时间"
             prop="saleDateStart"
           >
@@ -285,7 +285,7 @@
               placeholder="开始日期"
             >
             </el-date-picker>
-            <span>至</span>
+            <span style="margin:0 10px">至</span>
             <el-date-picker
               :editable="false"
               :clearable="false"
@@ -459,6 +459,7 @@
           </el-form-item>
 
           <el-form-item
+            verify
             label="票种绑定的销售渠道"
             prop="ticketTypeSourceList"
           >
@@ -651,7 +652,7 @@
                     </template>
                   </el-table-column>
                   <el-table-column
-                    width="90"
+                    width="110"
                     class-name="align-item"
                     label="操作">
                     <template slot-scope="scope">
@@ -715,6 +716,18 @@
                     ></el-input-number>
                   </template>
                 </el-table-column>
+                <el-table-column
+                  label="单日限制检票次数"
+                  min-width="90">
+                  <template slot-scope="scope">
+                    <el-input-number
+                      controls-position="right"
+                      :min="-1"
+                      :precision="0"
+                      v-model="scope.row.singleDayLimitTimes"
+                    ></el-input-number>
+                  </template>
+                </el-table-column>
                 <el-table-column
                   width="90"
                   class-name="align-item"
@@ -772,7 +785,7 @@
                     ></el-input-number>
                   </template>
                 </el-table-column>
-                <el-table-column
+                <!-- <el-table-column
                   label="单景点检票次数"
                   min-width="90">
                   <template slot-scope="scope">
@@ -783,16 +796,22 @@
                       v-model="scope.row.scenicLimitTimes"
                     ></el-input-number>
                   </template>
-                </el-table-column>
+                </el-table-column> -->
                 <el-table-column
-                  width="90"
+                  width="210"
                   class-name="align-item"
                   label="操作">
                   <template slot-scope="scope">
                     <div style="display:flex">
                       <span
                         class="el-button el-button--primary el-button--small"
-                        @click="delScenic(scope.$index,'multiple')">
+                        @click="setSceneTimes(scope.$index, scope.row)">
+                        <i class="el-icon-edit-outline"></i>
+                        分配次数
+                      </span>
+                      <span
+                        class="el-button el-button--primary el-button--small"
+                        @click="delScenic(scope.$index, 'multiple')">
                         <i class="el-icon-delete"></i>
                         删除
                       </span>
@@ -823,20 +842,76 @@
         </div>
       </el-form>
     </el-scrollbar>
+    <el-dialog
+      :visible.sync="setTimeVisible"
+      title="分配次数"
+      append-to-body
+      @close="handleGroupTimeClose">
+      <div class="table-box">
+        <el-table
+          border
+          stripe
+          :data="currGroupScenicInfo">
+          <el-table-column
+            label="景点">
+            <template slot-scope="scope">
+              {{ scope.row.scenicName }}
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="单个景点的检票次数"
+            min-width="90">
+            <template slot-scope="scope">
+              <el-input-number
+                controls-position="right"
+                :min="-1"
+                :precision="0"
+                v-model="scope.row.scenicLimitTimes"
+              ></el-input-number>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="单日限制检票次数"
+            min-width="90">
+            <template slot-scope="scope">
+              <el-input-number
+                controls-position="right"
+                :min="-1"
+                :precision="0"
+                v-model="scope.row.singleDayLimitTimes"
+              ></el-input-number>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <div
+        slot="footer"
+        class="dialog-btn-wrap">
+        <el-button
+          @click="handleGroupTimeClose">
+          取消
+        </el-button>
+        <el-button
+          @click="handleGroupTimeSubmit"
+          type="primary">
+          确定
+        </el-button>
+      </div>
+    </el-dialog>
   </el-dialog>
 </template>
 
 <script>
 import { addTicket, updateTicket, queueList, addTicketBatch, updateTicketBatch, delTicketBatch } from '@/api/ticketType'
 import { getLabelName } from '@/utils'
-import { cloneDeep } from 'lodash'
+import { cloneDeep, isNumber } from 'lodash'
 import moment from 'moment'
 
 const defaultForm = {
   category: 'ticket', // 大类
   name: '', // 名称
   isSale: 1, // 在售状态 0为禁售 1为在售 默认为1
-  price: 0, // 窗口价格
+  price: '', // 窗口价格
   onlinePrice: 0, // 线上价格
   highPrice: 0, // 虚拟高价(划线价格)
   memberUseDateType: 1, // 会员时长类型 1【按天】:购买后多少天的有效期 由票种字段use_days生效 。2【按照使用日期】:固定某个时间期内可以用
@@ -885,14 +960,14 @@ export default {
       type: Array,
       default: () => []
     },
-    ticketItem: {
-      type: Object,
-      default: () => {}
-    },
-    dialogType: {
-      type: String,
-      default: ''
-    },
+    // ticketItem: {
+    //   type: Object,
+    //   default: () => {}
+    // },
+    // dialogType: {
+    //   type: String,
+    //   default: ''
+    // },
     scenicList: {
       type: Array,
       default: () => []
@@ -908,6 +983,8 @@ export default {
   },
   data () {
     return {
+      ticketItem: {},
+      dialogType: 'add',
       projectName: process.env.VUE_APP_PROJECT,
       visible: false,
       pickerOptions: {
@@ -935,7 +1012,11 @@ export default {
         preCheckMinutes: -1, // 预检时间
         stopCheckMinutes: -1, // 停止检票时间
         maxSaleNums: -1 // 最大售卖数量
-      }
+      },
+      setTimeVisible: false,
+      groupIndex: -1,
+      currGroupScenicInfo: [],
+      groupScenicMap: new Map()
     }
   },
   watch: {
@@ -997,7 +1078,8 @@ export default {
           if (!item.groupFlag) {
             this.form.singleScenicList.push({
               scenicId: item.scenicId,
-              checkLimitTimes: item.checkLimitTimes
+              checkLimitTimes: item.checkLimitTimes,
+              singleDayLimitTimes: item.singleDayLimitTimes
             })
           } else {
             if (groupFlag !== item.groupFlag) {
@@ -1006,7 +1088,8 @@ export default {
               this.form.groupScenicList.push({
                 scenicId: [item.scenicId],
                 checkLimitTimes: item.checkLimitTimes,
-                scenicLimitTimes: item.scenicLimitTimes
+                scenicLimitTimes: item.scenicLimitTimes,
+                singleDayLimitTimes: item.singleDayLimitTimes
               })
             } else {
               this.form.groupScenicList[groupIndex - 1].scenicId.push(item.scenicId)
@@ -1079,16 +1162,56 @@ export default {
         this.form.groupScenicList.push({
           scenicId: [],
           checkLimitTimes: -1,
+          singleDayLimitTimes: -1,
           scenicLimitTimes: -1
         })
       } else {
         this.form.singleScenicList.push({
           scenicId: '',
           checkLimitTimes: -1,
+          singleDayLimitTimes: -1,
           scenicLimitTimes: -1
         })
       }
     },
+    setSceneTimes (idx, item) {
+      if (!item || !item.scenicId || !item.scenicId.length) {
+        return this.$message.error('请先添加适用景点')
+      }
+
+      this.groupIndex = idx
+      const groupScenic = this.groupScenicMap.get(idx)
+
+      if (groupScenic) {
+        this.currGroupScenicInfo = groupScenic
+      } else {
+        this.currGroupScenicInfo = []
+        item.scenicId.forEach(id => {
+          const scene = this.scenicList.find((scene) => scene.id === id)
+
+          if (scene) {
+            this.currGroupScenicInfo.push({
+              scenicId: scene.id,
+              scenicName: scene.name,
+              scenicLimitTimes: -1,
+              singleDayLimitTimes: -1,
+              checkLimitTimes: item.checkLimitTimes
+            })
+          }
+        })
+      }
+
+      this.setTimeVisible = true
+    },
+    handleGroupTimeClose () {
+      this.currGroupScenicInfo = []
+      this.setTimeVisible = false
+    },
+    handleGroupTimeSubmit () {
+      this.groupScenicMap.set(this.groupIndex, this.currGroupScenicInfo)
+      this.currGroupScenicInfo = []
+      this.setTimeVisible = false
+    },
     // 删除 适用景点-检票次数
     delScenic (index, type) {
       if (type === 'multiple') {
@@ -1148,58 +1271,87 @@ export default {
         }
       })
     },
+    setGroupScenicConfig () {
+      const gsList = []
+      const { groupScenicList } = this.form
+
+      for (let i = 0; i < groupScenicList.length; i++) {
+        const item = groupScenicList[i]
+        const sList = this.groupScenicMap.get(i) || item.scenicId.map(scenicId => {
+          return {
+            scenicId,
+            checkLimitTimes: item.checkLimitTimes,
+            singleDayLimitTimes: item.singleDayLimitTimes || -1,
+            scenicLimitTimes: item.scenicLimitTimes || -1
+          }
+        })
+        gsList.push(sList)
+      }
+
+      this.form.groupScenicList = gsList
+    },
     async submit () {
       this.$refs.form.validate(valid => {
         // 会员不检查景点
+        const {
+          price,
+          useDateStart,
+          useDateEnd,
+          isSaleDateLimit,
+          saleDateStart,
+          saleDateEnd,
+          category,
+          batchConfigList
+        } = this.form
 
         if (valid) {
-          if (this.form.price <= 0) {
+          if (!price || isNaN(Number(price)) || price <= 0) {
             this.$message.error('请填写销售价格')
             return
           }
 
-          if (moment(this.form.useDateStart).isAfter(this.form.useDateEnd)) {
+          if (moment(useDateStart).isAfter(useDateEnd)) {
             this.$message.error('游玩开始时间不可晚于游玩截止时间')
             return
           }
 
-          if (this.form.isSaleDateLimit === 1 && moment(this.form.saleDateStart).isAfter(this.form.saleDateEnd)) {
+          if (isSaleDateLimit === 1 && moment(saleDateStart).isAfter(saleDateEnd)) {
             this.$message.error('起售时间不可晚于停售时间')
             return
           }
 
-          if (moment(this.form.useDateStart).isAfter(this.form.useDateEnd)) {
+          if (moment(useDateStart).isAfter(useDateEnd)) {
             this.$message.error('游玩开始时间不可晚于游玩截止时间')
             return
           }
 
-          if (this.form.isSaleDateLimit === 1 && moment(this.form.saleDateEnd).isAfter(this.form.useDateEnd)) {
+          if (isSaleDateLimit === 1 && moment(saleDateEnd).isAfter(useDateEnd)) {
             this.$message.error('停售时间不可晚于游玩截止时间')
             return
           }
 
-          if (this.form.isSaleDateLimit === 1 && moment(this.form.saleDateStart).isAfter(this.form.useDateStart)) {
+          if (isSaleDateLimit === 1 && moment(saleDateStart).isAfter(useDateStart)) {
             this.$message.error('起售时间不可晚于游玩开始时间')
             return
           }
 
-          if (this.form.category === 'batch') {
-            if (this.form.batchConfigList.length === 0) {
+          if (category === 'batch') {
+            if (batchConfigList.length === 0) {
               this.$message.error('请添加场次时间')
               return
             }
 
-            if (this.form.batchConfigList.some(item => !item.name)) {
+            if (batchConfigList.some(item => !item.name)) {
               this.$message.error('场次名称不能为空')
               return
             }
 
-            if (this.form.batchConfigList.some(item => !item.startTime)) {
+            if (batchConfigList.some(item => !item.startTime)) {
               this.$message.error('场次开始时间不能为空')
               return
             }
 
-            if (this.form.batchConfigList.some(item => !item.endTime)) {
+            if (batchConfigList.some(item => !item.endTime)) {
               this.$message.error('场次结束时间不能为空')
               return
             }
@@ -1222,22 +1374,12 @@ export default {
           // this.form.useDateEnd = this.formatEndTime(this.form.useDateEnd)
           // this.form.requiredField = JSON.stringify(this.form.requiredField)
           // form.useDayOfWeek.join is not a function"
+          this.form.price = Number(price)
           this.form.useDayOfWeek = this.form.useDayOfWeek?.join(',')
           this.form.checkRule = this.form.checkRule.join(',')
           this.form.checkType = this.form.checkType.join(',')
 
-          const groupScenicList = this.form.groupScenicList.map(item => {
-            const sList = item.scenicId.map(scenicId => {
-              return {
-                scenicId,
-                checkLimitTimes: item.checkLimitTimes,
-                scenicLimitTimes: item.scenicLimitTimes
-              }
-            })
-
-            return sList
-          })
-          this.form.groupScenicList = groupScenicList
+          this.setGroupScenicConfig()
 
           switch (this.dialogType) {
             case 'add':
@@ -1249,6 +1391,7 @@ export default {
           }
         } else {
           console.log('error submit!!')
+          this.$message.error('请补充表单内容')
           return false
         }
       })

+ 1 - 1
src/router/index.js

@@ -277,7 +277,7 @@ let routerMap = [
       {
         path: 'visitorStatistic',
         name: 'visitorStatistic',
-        component: () => import('@/pages/visitor/visitorStatistic'),
+        component: () => require('@/pages/visitor/visitorStatistic').default,
         meta: { title: '游客画像', permissionName: 'statistics-center:customer-statistics' }
       },
       {