LaveyD 2 meses atrás
pai
commit
4a7f356708

+ 10 - 0
src/api/ticketType.js

@@ -263,3 +263,13 @@ export function listTransferLog (params) {
 export function signInAfterPass (params) {
   return http.post('/queue/signInAfterPass', { data: params })
 }
+
+// 获取票种排序
+export function getTicketTypeSort () {
+  return http.post('/admin/ticketType/getSort')
+}
+
+// 保存票种排序
+export function saveTicketTypeSort (params) {
+  return http.post('/admin/ticketType/saveSort', { data: params })
+}

+ 11 - 1
src/components/GlobalComponents/OrderDetail.vue

@@ -844,10 +844,20 @@ export default {
       this.record = record
       this.detailVisible = true
     },
+    isValidUrl (url) {
+      try {
+        const raw = String(url || '').trim()
+        if (!raw) return false
+        const parsedUrl = new URL(raw, window.location.origin)
+        return ['http:', 'https:'].includes(parsedUrl.protocol)
+      } catch (error) {
+        return false
+      }
+    },
     // 下载方法
     downloadInvoice (url) {
       console.log(' downloadInvoice', url)
-      if (!url) {
+      if (!this.isValidUrl(url)) {
         this.$message.warning('暂无发票可下载')
         return
       }

+ 22 - 17
src/pages/queryReport/checkStatistic.vue

@@ -168,13 +168,13 @@ export default {
         pageSize: 10
       },
       finalGroup: [
-        { prop: 'otaSourceName', label: '订单渠道', values: 'otaSourceName' },
-        { prop: 'ticketTypeName', label: '票种名称', values: 'ticketTypeName' },
-        { prop: 'unitPrice', label: '单价', values: 'unitPrice' },
-        { prop: 'checkCount', label: '检票数量', values: 'checkCount' },
-        { prop: 'checkNum', label: '检票人数', values: 'checkNum' },
-        { prop: 'checkPrice', label: '检票金额', values: 'checkPrice' },
-        { prop: 'orderDateDay', label: '统计日期', values: 'orderDateDay' }
+        { prop: 'otaSourceName', label: '订单渠道' },
+        { prop: 'ticketTypeName', label: '票种名称' },
+        { prop: 'unitPrice', label: '单价' },
+        { prop: 'checkCount', label: '检票数量' },
+        { prop: 'checkNum', label: '检票人数' },
+        { prop: 'checkPrice', label: '检票金额' },
+        { prop: 'orderDateDay', label: '统计日期' }
       ],
       selectKeys: [], // 默认选中
       tableIndex: 1,
@@ -239,18 +239,23 @@ export default {
 
       if (this.selectKeys.length === 0) {
         this.finalGroup = [
-          // { prop: 'otaSourceName', label: '订单渠道' },
-          // { prop: 'ticketTypeName', label: '票种名称' },
-          // { prop: 'unitPrice', label: '单价' },
-          // { prop: 'checkCount', label: '检票数量' },
-          // { prop: 'checkNum', label: '检票人数' },
-          // { prop: 'checkPrice', label: '检票金额' },
-          // { prop: 'orderDateDay', label: '统计日期' }
+          { prop: 'otaSourceName', label: '订单渠道' },
+          { prop: 'ticketTypeName', label: '票种名称' },
+          { prop: 'unitPrice', label: '单价' },
+          { prop: 'checkCount', label: '检票数量' },
+          { prop: 'checkNum', label: '检票人数' },
+          { prop: 'checkPrice', label: '检票金额' }
         ]
       } else {
-        this.finalGroup = [...this.finalGroup].sort((a, b) =>
-          (this.selectKeys.includes(b.prop) ? 1 : 0) - (this.selectKeys.includes(a.prop) ? 1 : 0)
-        )
+        this.finalGroup = [
+          { prop: 'orderDateDay', label: '统计日期' },
+          { prop: 'otaSourceName', label: '订单渠道' },
+          { prop: 'ticketTypeName', label: '票种名称' },
+          { prop: 'unitPrice', label: '单价' },
+          { prop: 'checkCount', label: '检票数量' },
+          { prop: 'checkNum', label: '检票人数' },
+          { prop: 'checkPrice', label: '检票金额' }
+        ]
       }
 
       if (this.form.checkTimeBegin) {

+ 1 - 1
src/pages/queryReport/refundQuery/RefundQuery.vue

@@ -238,7 +238,7 @@
         ></el-table-column>
         <el-table-column
           prop="ticketNo"
-          width="150"
+          width="160"
           label="票号"
         ></el-table-column>
         <el-table-column

+ 19 - 12
src/pages/queryReport/refundStatistic.vue

@@ -146,14 +146,14 @@ export default {
       },
       groupKeys: [{ value: 'orderDateDay', label: '统计日期' }],
       finalGroup: [
+        // { prop: 'orderDateDay', label: '统计日期' },
         { prop: 'otaSourceName', label: '销售渠道' },
         { prop: 'ticketTypeName', label: '票种' },
         { prop: 'unitPrice', label: '单价' },
         { prop: 'cancelCount', label: '退票数量' },
         { prop: 'cancelNum', label: '退票人数' },
         { prop: 'cancelPrice', label: '退票金额' },
-        { prop: 'cancelSettlementPrice', label: '退票结算金额' },
-        { prop: 'orderDateDay', label: '统计日期' }
+        { prop: 'cancelSettlementPrice', label: '退票结算金额' }
       ],
       selectKeys: [], // 默认选中
       tableData: [],
@@ -265,18 +265,25 @@ export default {
     getList () {
       if (this.selectKeys.length === 0) {
         this.finalGroup = [
-          // { prop: 'otaSourceName', label: '订单渠道' },
-          // { prop: 'ticketTypeName', label: '票种名称' },
-          // { prop: 'unitPrice', label: '单价' },
-          // { prop: 'checkCount', label: '检票数量' },
-          // { prop: 'checkNum', label: '检票人数' },
-          // { prop: 'checkPrice', label: '检票金额' },
-          // { prop: 'orderDateDay', label: '统计日期' }
+          { prop: 'otaSourceName', label: '销售渠道' },
+          { prop: 'ticketTypeName', label: '票种' },
+          { prop: 'unitPrice', label: '单价' },
+          { prop: 'cancelCount', label: '退票数量' },
+          { prop: 'cancelNum', label: '退票人数' },
+          { prop: 'cancelPrice', label: '退票金额' },
+          { prop: 'cancelSettlementPrice', label: '退票结算金额' }
         ]
       } else {
-        this.finalGroup = [...this.finalGroup].sort((a, b) =>
-          (this.selectKeys.includes(b.prop) ? 1 : 0) - (this.selectKeys.includes(a.prop) ? 1 : 0)
-        )
+        this.finalGroup = [
+          { prop: 'orderDateDay', label: '统计日期' },
+          { prop: 'otaSourceName', label: '销售渠道' },
+          { prop: 'ticketTypeName', label: '票种' },
+          { prop: 'unitPrice', label: '单价' },
+          { prop: 'cancelCount', label: '退票数量' },
+          { prop: 'cancelNum', label: '退票人数' },
+          { prop: 'cancelPrice', label: '退票金额' },
+          { prop: 'cancelSettlementPrice', label: '退票结算金额' }
+        ]
       }
 
       this.form.groupByList = [...this.selectKeys] || []

+ 127 - 4
src/pages/sellManage/common/TicketList.vue

@@ -122,6 +122,13 @@
             slot="suffix">
           </i>
         </el-input>
+        <el-button
+          size="small"
+          class="sort-btn"
+          icon="el-icon-sort"
+          title="票种排序"
+          @click="openSortDialog">
+        </el-button>
       </div>
       <div
         :class="['ticket-list', category === 'batch' && 'list-batch']"
@@ -176,14 +183,50 @@
       v-model="ticketInfoVisible">
       <TicketInfo :data="ticketDetail"></TicketInfo>
     </ElDialog>
+
+    <!-- 票种排序弹框 -->
+    <native-dialog
+      title="票种排序"
+      :visible.sync="sortDialogVisible"
+      width="600px"
+      :close-on-click-modal="false">
+      <div v-loading="sortLoading">
+        <draggable
+          v-model="sortList"
+          handle=".sort-item"
+          animation="200">
+          <div
+            class="sort-item"
+            v-for="item in sortList"
+            :key="item.ticketTypeId">
+            <span class="sort-name">{{ item.name }}</span>
+            <el-tag
+              size="small"
+              :type="item.isSale !== 0 ? 'success' : 'info'">
+              {{ item.isSale !== 0 ? '已激活' : '已禁用' }}
+            </el-tag>
+          </div>
+        </draggable>
+      </div>
+      <span
+        slot="footer"
+        class="dialog-footer">
+        <el-button @click="sortDialogVisible = false">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="saveSortList">确 定</el-button>
+      </span>
+    </native-dialog>
   </div>
 </template>
 
 <script>
-import { getTicketTypeList, getTicketTypeByDate } from '@/api/ticketType'
+import { getTicketTypeList, getTicketTypeByDate, getTicketTypeSort, saveTicketTypeSort } from '@/api/ticketType'
+import draggable from 'vuedraggable'
 import { getBatchList } from '@/api/batch'
 import moment from 'moment'
 import ElDialog from '@/components/Dialog'
+import { Dialog as NativeDialog } from 'element-ui'
 import TicketInfo from './TicketInfo'
 import { EventBus } from '@/utils/eventBus'
 // import TagSelector from './TagSelector.vue'
@@ -203,7 +246,9 @@ export default {
   },
   components: {
     ElDialog,
-    TicketInfo
+    NativeDialog,
+    TicketInfo,
+    draggable
   },
   data () {
     return {
@@ -233,7 +278,10 @@ export default {
         { label: '后天', value: moment().add(2, 'days').format('YYYY-MM-DD') }
       ],
       allBatchList: [],
-      currentBatch: {}
+      currentBatch: {},
+      sortDialogVisible: false,
+      sortLoading: false,
+      sortList: []
     }
   },
   computed: {
@@ -561,6 +609,53 @@ export default {
     },
     getLeftNums (item) {
       return item.leftNums <= -1 ? '不限' : item.leftNums
+    },
+    // 打开票种排序弹框
+    async openSortDialog () {
+      this.sortDialogVisible = true
+      this.sortLoading = true
+      try {
+        const sortRes = await getTicketTypeSort()
+        const sortData = sortRes?.data || []
+        // 用排序接口的顺序排列 tableData
+        const sortMap = new Map(sortData.map(s => [s.ticketTypeId, s.sort]))
+        this.sortList = [...this.tableData]
+          .map(item => ({
+            ticketTypeId: item.id,
+            name: item.name,
+            isSale: item.isSale,
+            sort: sortMap.has(item.id) ? sortMap.get(item.id) : 9999
+          }))
+          .sort((a, b) => a.sort - b.sort)
+      } catch (e) {
+        this.sortList = this.tableData.map((item, index) => ({
+          ticketTypeId: item.id,
+          name: item.name,
+          isSale: item.isSale,
+          sort: index
+        }))
+      } finally {
+        this.sortLoading = false
+      }
+    },
+    // 保存票种排序
+    async saveSortList () {
+      const data = this.sortList.map((item, index) => ({
+        ticketTypeId: item.ticketTypeId,
+        sort: index + 1
+      }))
+      try {
+        await saveTicketTypeSort(data)
+        this.$message.success('排序保存成功')
+        this.sortDialogVisible = false
+        // 按新排序更新 tableData
+        const sortMap = new Map(data.map(s => [s.ticketTypeId, s.sort]))
+        this.tableData.sort((a, b) => {
+          return (sortMap.get(a.id) || 9999) - (sortMap.get(b.id) || 9999)
+        })
+      } catch (e) {
+        this.$message.error('排序保存失败')
+      }
     }
   },
   beforeDestroy () {
@@ -654,7 +749,11 @@ export default {
     align-items: center;
 
     .search-input {
-      width: calc(100% - 120px);
+      width: calc(100% - 130px);
+    }
+
+    .sort-btn {
+      margin-left: 2px;
     }
 
     .ticket-list {
@@ -892,4 +991,28 @@ export default {
   max-height: calc(100vh - 400px);
   flex: 1;
 }
+
+.sort-item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 12px 16px;
+  border-bottom: 1px solid #eee;
+  cursor: grab;
+  background: #fff;
+  transition: background 0.2s;
+
+  &:hover {
+    background: #f5f7fa;
+  }
+
+  &:active {
+    cursor: grabbing;
+  }
+
+  .sort-name {
+    font-size: 14px;
+    color: #333;
+  }
+}
 </style>