Эх сурвалжийг харах

窗口端所有功能模块开发调整完毕

shipeng 4 сар өмнө
parent
commit
7924ca9eaf

+ 1 - 1
package.json

@@ -1,7 +1,7 @@
 {
   "name": "ruoyi",
   "version": "3.8.6",
-  "description": "伟大转折点后台管理系统",
+  "description": "伟大转折窗口售票系统",
   "author": "达泽",
   "license": "MIT",
   "scripts": {

+ 7 - 0
src/api/order/orderMr.js

@@ -17,6 +17,13 @@ export function getSelectById(id) {
     method: 'get'
   })
 }
+// 获取 订单日志
+export function getLogList(id) {
+  return request({
+    url: '/order/orderInfo/getOrderLogList?orderId=' + id,
+    method: 'get'
+  })
+}
 
 //  导出
 export function downOrderListXls(params) {

+ 7 - 0
src/api/windowTicketSales/ticketingCollection.js

@@ -8,6 +8,13 @@ export const pageList = (query) => {
     params: query
   })
 }
+export const pageListApi = (query) => {
+  return request({
+    url: '/order/orderInfo/getWinValidPageList',
+    method: 'get',
+    params: query
+  })
+}
 
 // 打印
 export const printApi = (data) => {

+ 9 - 0
src/api/windowTicketSales/ticketingSales.js

@@ -186,4 +186,13 @@ export const lockOrUnLockApi = (query) => {
     method: 'get',
     params: query
   })
+}
+
+// 座位 锁、解锁日志
+export const seatLockLogs = (query) => {
+  return request({
+    url: '/merchant/merchantSeatOccupy/seatOperList',
+    method: 'get',
+    params: query
+  })
 }

+ 37 - 18
src/views/officesale/model/increaseViewers.vue

@@ -172,8 +172,22 @@
                 <el-form-item label="找零金额 :" v-if="ruleForm.paymentType == 2">
                     ¥{{ ruleForm.small }}元
                 </el-form-item> -->
+                <el-form-item label="用户来源 :" prop="source">
+                    <el-radio-group v-model="ruleForm.source" style="width: 90%;">
+                        <el-radio label="23">抖音</el-radio>
+                        <el-radio label="24">大麦</el-radio>
+                        <el-radio label="25">智游遵义</el-radio>
+                        <el-radio label="26">猫眼</el-radio>
+                        <el-radio label="27">携程</el-radio>
+                        <el-radio label="28">美团</el-radio>
+                        <el-radio label="29">踩线</el-radio>
+                        <el-radio label="30">分销活动</el-radio>
+                        <el-radio label="31">员工票</el-radio>
+                        <el-radio label="32">其他</el-radio>
+                    </el-radio-group>
+                </el-form-item>
                 <el-form-item label="订单备注 :" prop="remark">
-                    <el-input style="width: 400px;" type="textarea" :rows="2" maxlength="200" v-model="ruleForm.remark" show-word-limit></el-input>
+                    <el-input style="width: 80%;" type="textarea" :rows="4" maxlength="200" v-model="ruleForm.remark" show-word-limit></el-input>
                 </el-form-item>
             </el-form>
         </div>
@@ -188,7 +202,7 @@
                     payStatus==5 ? '请出示付款码!!!' :
                     payStatus==6 ? '连接扫码器失败!!!' :
                     payStatus==7 ? '用户支付失败或未支付,请重新连接支付!!!' :
-                    payStatus==8 ? '用户支付成功,请点击打印票!!!' :
+                    payStatus==8 ? '用户支付成功,请选择打印机点击打印票!!!' :
                     payStatus==9 ? '支付超时!!!' :
                     payStatus==3 ? '现金支付记录入库失败,请重新提交' : '未知状态' }}
                 </span>
@@ -208,7 +222,7 @@
                         <el-option :label="item.deviceName" :key="item.id" :value="item.id" v-for="(item,index) in printList"></el-option>
                     </el-select>
                     <el-button style="margin-left: 15px" @click="print" type="success">打印门票</el-button>
-                    <el-button style="margin-left: 15px" @click="goTicketingCollections" type="success">跳转取票界面</el-button>
+                    <!-- <el-button style="margin-left: 15px" @click="goTicketingCollections" type="success">跳转取票界面</el-button> -->
                 </div>
                 <!-- 支付超时 9  -->
                 <div v-if="payStatus==9">
@@ -291,9 +305,9 @@ import {
             realPrice: [
                 { required: true, message: '请输入实付金额', trigger: ['blur','change']},
             ],
-            remark: [
-                { required: true, message: '请输入订单备注', trigger: ['blur','change']},
-            ]
+            // remark: [
+            //     { required: true, message: '请输入订单备注', trigger: ['blur','change']},
+            // ]
         },
         moneyAll: '',
         payment: '',
@@ -489,11 +503,12 @@ import {
             // }
             this.$confirm('确认关闭?')
                 .then(_ => {
-                    if(this.orderId){
-                        this.orderInfoCancelFun(true)
-                    }else {
-                        this.dialogVisible = false
-                    }
+                    // if(this.orderId){
+                    //     this.orderInfoCancelFun(true)
+                    // }else {
+                    //     this.dialogVisible = false
+                    // }
+                    this.dialogVisible = false
                 })
                 .catch(_ => {});
         },
@@ -741,18 +756,18 @@ import {
                                     type: 'success'
                                 });
                                 this.loading = false
-                                // this.payStatus = 8
-                                // this.getPrintListApi()
-                                this.dialogVisible = false
-                                this.goTicketingCollections()
+                                this.payStatus = 8
+                                this.getPrintListApi()
+                                // this.dialogVisible = false
+                                // this.goTicketingCollections()
                                 
                             }else {
                                 this.$message('用户已支付!!!');
                                 // 开始 打印
                                 this.loading = false
-                                // this.payStatus = 8
-                                // this.getPrintListApi()
-                                this.goTicketingCollections()
+                                this.payStatus = 8
+                                this.getPrintListApi()
+                                // this.goTicketingCollections()
                             }
                             
                             
@@ -975,6 +990,10 @@ import {
 }
 </script>
 <style scoped lang="scss">
+::v-deep .el-radio {
+    line-height: 2;
+
+}
 .increase-viewers-box {
     width: 100%;
     height: calc( 100vh - 250px );

+ 115 - 14
src/views/officesale/ticketingSales.vue

@@ -151,25 +151,50 @@
                 <!-- 遮罩最好是在绑定了mouseover事件的元素内部,并且不要阻止遮罩的冒泡事件。这样鼠标移到了遮罩上面,依然可以利用冒泡执行父元素的mouseover事件,就不会出现遮罩只能扩大,不能缩小的情况了(亲自试过) -->
                 <div id="moveSelected"></div>
             </div>
-            <div style="margin-top: 5px; margin-left: 30px;display: flex;">
+            <!-- <div style="margin-top: 5px; margin-left: 30px;display: flex;">
                 <div style="flex-shrink: 0;">
-                    <span>已勾选可售座位:{{ seatSelectList.length }}</span>
-                    ,
+                    <span style="margin-right: 15px;">已勾选可售座位:{{ seatSelectList.length }}</span>
                     <span>已勾选锁定座位:{{ seatSelectListNo.length }}</span>
                     <el-button size="mini" type="warning"  @click="clearSeatSelectListAll">清空已选座位</el-button>
                 </div>
-                <div style="width: 100%;display: flex;justify-content: center;height: 30px;">
+                <div style="width: 100%;display: flex;justify-content: center;height: 30px;margin-left: 10px;">
                     <el-button size="mini" v-hasPermi="['officesale:ticketingSales:lock']" type="warning" :loading="lockOrUnLockLoading" @click="lockOrUnLockFun(0)">{{ seatSelectListNo.length>0?'解锁':'锁定' }}</el-button>
-                    <el-button size="mini" v-hasPermi="['officesale:ticketingSales:buy']" type="primary" @click="increaseViewersFun">预约</el-button>
+                    <el-button size="mini" v-hasPermi="['officesale:ticketingSales:buy']" type="primary" @click="increaseViewersFun">预 约</el-button>
+                </div>
+            </div> -->
+            <div class="bottom-warp">
+                <div style="flex-shrink: 0;">
+                    <span style="margin-right: 15px;">已勾选可售座位:{{ seatSelectList.length }}</span>
+                    <!-- <span>已勾选锁定座位:{{ seatSelectListNo.length }}</span> -->
+                    <el-button size="mini" type="warning"  @click="clearSeatSelectListAll">清空已选座位</el-button>
+                    <!-- <el-button size="mini" v-hasPermi="['officesale:ticketingSales:buy']" type="primary" @click="increaseViewersFun">预 约</el-button> -->
+                </div>
+                <div class="selectInfo">
+                    <div class="selectItem" :key="index" v-for="(item, index) in seatSelectList">
+                        <div>
+                            <span>{{ item.name ? item.name : '暂未命名' }}</span>
+                            <span v-if="item.salePrice">¥{{ item.salePrice }}</span>
+                            <span v-else>未配置价格</span>
+                            <!-- <span>{{ setSeatTypeShow(item.seatTypeId) }}</span> -->
+                        </div>
+                        <div>
+                            <!-- <span @click="delSeatSelect(item)">删除</span> -->
+                            <span>
+                                <i class="el-icon-close" @click="delSeatSelect(item)"></i>
+                            </span>
+                        </div>
+                    </div>
                 </div>
             </div>
+            <div style="display: flex;justify-content: center;">
+                <el-button class="btnStyle" size="mini" v-hasPermi="['officesale:ticketingSales:buy']" type="danger" @click="increaseViewersFun">预 约</el-button>
+            </div>
             
         </div>
-        <div class="seat-select-box">
+        <!-- <div class="seat-select-box">
             <div class="seat-select-box-top">
                 <el-tabs v-model="activeName" @tab-click="handleClickTab">
                     <el-tab-pane label="已选座位" name="first"></el-tab-pane>
-                    <!-- <el-tab-pane label="座位图例" name="second"></el-tab-pane> -->
                 </el-tabs>
             </div>
             <div class="seat-select-info" v-if="activeName=='first'">
@@ -195,7 +220,7 @@
                     <span>{{item.name ? item.name : '暂未命名'}}</span>
                 </div>
             </div>
-        </div>
+        </div> -->
       </div>
       <!--  锁座备注  -->
       <lock-seat ref="lockSeat" @querySeatListFun="querySeatListFun" />
@@ -968,16 +993,92 @@ import LockSeat from './model/lockSeat.vue'
   }
   .seat-box {
     width: 100%;
-    height: calc( 100% - 100px ) ;
+    height: 100%;
+    // height: calc( 100% - 100px ) ;
     box-sizing: border-box;
     display: flex;
-    position: relative;
+    // position: relative;
     .seat-list-box {
-        width: calc(100% - 210px);
-        //width: 100%;
-        height: 100%;
+        // width: calc(100% - 210px);
+        width: 100%;
+        // height: 100%;
+        height: calc(100% - 295px);
         box-sizing: border-box;
-        position: relative;
+        // position: relative;
+        .bottom-warp {
+            height: 180px;
+            padding: 10px 20px;
+            margin-top: 5px;
+            border: 1px solid #666;
+            border-radius: 10px;
+            overflow-y: auto;
+            .selectInfo {
+                width: 100%;
+                // overflow: hidden;
+                // overflow-y: auto;
+                display: flex;
+                justify-content: flex-start;
+                flex-wrap: wrap;
+                /* 允许换行 */
+                gap: 10px 25px;
+
+                .selectItem {
+                    width: 120px;
+                    height: 50px;
+                    border: 1px solid #ccc;
+                    margin-top: 5px;
+                    // margin: 5px 12px;
+                    padding: 5px;
+                    border-radius: 5px;
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+                    font-size: 12px;
+
+                    >div:first-child {
+                        width: 80px;
+                        display: flex;
+                        flex-direction: column;
+                        text-align: center;
+
+                        span:first-child {
+                            font-weight: 600;
+                        }
+                    }
+
+                    >div:last-child {
+                        span:first-child {
+                            color: #f56c6c;
+                            cursor: pointer;
+                            font-size: 18px;
+                        }
+                    }
+                }
+
+                .seat-select-color-item {
+                    display: flex;
+                    align-items: center;
+                    margin-bottom: 5px;
+
+                    >span:first-child {
+                        width: 20px;
+                        height: 20px;
+                        flex-shrink: 0;
+                    }
+
+                    >span:last-child {
+                        font-size: 16px;
+                        font-weight: 600;
+                        margin-left: 10px;
+                    }
+                }
+            }
+        }
+        .btnStyle {
+            width: 100px;
+            height: 40px;
+            margin-top: 15px;
+        }
     }
     .seat-select-box {
         width: 200px;

+ 153 - 102
src/views/order/orderMr/dialog/details.vue

@@ -8,12 +8,10 @@
  * @Copyright: Copyright (c) 2016~2023 by Sugar., All Rights Reserved.
 -->
 <template>
-  <el-dialog :title="title" :visible.sync="open" width="96%" append-to-body :close-on-click-modal="false" @close="cancel">
+  <el-dialog :title="title" :visible.sync="open" width="96%" append-to-body :close-on-click-modal="false"
+    @close="cancel">
     <div v-loading="loading" class="dialog dialog-bbb" v-if="form">
-      <div 
-      v-loading="loading_form"
-      element-loading-text="加载详情中..."
-      >
+      <div v-loading="loading_form" element-loading-text="加载详情中...">
         <!--   基础信息   -->
         <div class="title-class" style="margin-top: 0">基础信息</div>
         <el-row>
@@ -39,7 +37,8 @@
             <div class="grid-content bg-purple item-class">票务类型: <span>{{ form.seatTypeName || '' }}</span></div>
           </el-col>
           <el-col :span="12">
-            <div class="grid-content bg-purple item-class">场次: <span>{{ form.performDate }} {{ form.performTimeStart }} --
+            <div class="grid-content bg-purple item-class">场次: <span>{{ form.performDate }} {{ form.performTimeStart }}
+                --
                 {{ form.performTimeEnd }}</span></div>
           </el-col>
           <el-col :span="12">
@@ -68,8 +67,9 @@
           </el-col>
           <el-col :span="12">
             <div class="grid-content bg-purple item-class">
-              实收金额: <span v-if="form.status != 0">¥{{ form.realPrice || form.realPrice == 0 ? form.realPrice : '' }}</span>
-              <span v-if="form.realPrice<0&&resubmit.remark">({{ resubmit.remark }})</span>
+              实收金额: <span v-if="form.status != 0">¥{{ form.realPrice || form.realPrice == 0 ? form.realPrice : ''
+                }}</span>
+              <span v-if="form.realPrice < 0 && resubmit.remark">({{ resubmit.remark }})</span>
             </div>
           </el-col>
           <el-col :span="12">
@@ -81,7 +81,7 @@
             </div>
           </el-col> -->
           <el-col :span="12">
-            <div class="grid-content bg-purple item-class">优惠券额度: 
+            <div class="grid-content bg-purple item-class">优惠券额度:
               <span>{{ form.coupon ? form.coupon.preferentialPrice : "暂无" }}</span>
             </div>
           </el-col>
@@ -89,10 +89,11 @@
             <div class="grid-content bg-purple item-class">支付时间: <span>{{ form.payTime || '' }}</span></div>
           </el-col>
           <el-col :span="12">
-            <div class="grid-content bg-purple item-class" style="display: flex;">支付方式: 
-              <span v-if="form.payWay == 'corporate' && form.ifTeamCredit === 1" style="display: block;margin-left: 5px;">挂账支付</span>
+            <div class="grid-content bg-purple item-class" style="display: flex;">支付方式:
+              <span v-if="form.payWay == 'corporate' && form.ifTeamCredit === 1"
+                style="display: block;margin-left: 5px;">挂账支付</span>
               <span v-else style="display: block;margin-left: 5px;">
-                <dict-tag :options="dict.type.pay_way_type":value="form.payWay" />
+                <dict-tag :options="dict.type.pay_way_type" :value="form.payWay" />
               </span>
             </div>
           </el-col>
@@ -107,7 +108,7 @@
           </el-col>
           <el-col :span="12">
             <div class="grid-content bg-purple item-class" style="display: flex;">OTA订单号: <span
-                style="display: block;margin-left: 5px;">{{ form.otaOrderId||'-' }}</span></div>
+                style="display: block;margin-left: 5px;">{{ form.otaOrderId || '-' }}</span></div>
           </el-col>
           <el-col :span="12">
             <div class="grid-content bg-purple item-class" style="display: flex;">是否成功开票: <span
@@ -115,22 +116,27 @@
           </el-col>
         </el-row>
 
-        <div class="title-class" v-if="resubmit.id">{{form.resubmit && form.resubmit.resubmitType == 2 ? '升舱':'改签'}}信息</div>
-        <el-row  v-if="resubmit.id">
+        <div class="title-class" v-if="resubmit.id">{{ form.resubmit && form.resubmit.resubmitType == 2 ? '升舱' : '改签' }}信息
+        </div>
+        <el-row v-if="resubmit.id">
           <el-col :span="12">
             <div class="grid-content bg-purple item-class">
-              {{form.resubmit && form.resubmit.resubmitType == 2 ? '升舱':'改签'}}费用: <span>{{ resubmit.diffPrice || 0 }}</span>
-              <span v-if="resubmit.diffPrice<0">({{ resubmit.remark }})</span>
+              {{ form.resubmit && form.resubmit.resubmitType == 2 ? '升舱' : '改签' }}费用: <span>{{ resubmit.diffPrice || 0
+                }}</span>
+              <span v-if="resubmit.diffPrice < 0">({{ resubmit.remark }})</span>
             </div>
           </el-col>
           <el-col :span="12">
-            <div class="grid-content bg-purple item-class">{{form.resubmit && form.resubmit.resubmitType == 2 ? '升舱':'改签'}}时间: <span>{{ resubmit.createTime || '' }}</span></div>
+            <div class="grid-content bg-purple item-class">{{ form.resubmit && form.resubmit.resubmitType == 2 ?
+              '升舱':'改签'}}时间: <span>{{ resubmit.createTime || '' }}</span></div>
           </el-col>
           <el-col :span="12">
-            <div class="grid-content bg-purple item-class" v-if="resubmit.diffPrice<0">退款方式: <span>{{ resubmit.refundWay || '原路返回' }}</span></div>
+            <div class="grid-content bg-purple item-class" v-if="resubmit.diffPrice < 0">退款方式: <span>{{ resubmit.refundWay
+                || '原路返回' }}</span></div>
           </el-col>
           <el-col :span="12">
-            <div class="grid-content bg-purple item-class" v-if="resubmit.refundTime">退款时间: <span>{{ resubmit.refundTime || '' }}</span></div>
+            <div class="grid-content bg-purple item-class" v-if="resubmit.refundTime">退款时间: <span>{{ resubmit.refundTime
+                || '' }}</span></div>
           </el-col>
         </el-row>
 
@@ -163,58 +169,74 @@
             </el-table>
           </el-col>
         </el-row>
-      </div>
-      <div class="dialog-bbb_2" v-loading="loading_seta" element-loading-text="加载座位图中...">
-        <div class="seat-tool-box">
-          <span class="demonstration">座位大小</span>
-          <div class="seat-tool-box-slider">
-            <el-slider v-model="scaleNum" :min="30" :max="100"></el-slider>
-          </div>
-          <div style="display: flex;margin-left: 20px;" v-if="seatMapList && JSON.stringify(seatMapList) != '{}'">
-            <div>座位余量:</div>
-            <div :key="index" v-for="(item, index) in seatTypeList" style="margin-left: 10px;align-items: center;">
-              <span :style="{ color: item.color ? item.color : 'none' }">{{ item.name ? (item.name + '(剩余:' + (item.num || 0) + ')')
-                :
-                '暂未命名'}}</span>
+
+        <!-- 座位信息 -->
+        <div class="title-class">座位信息</div>
+        <div class="dialog-bbb_2" v-loading="loading_seta" element-loading-text="加载座位图中...">
+          <div class="seat-tool-box">
+            <span class="demonstration">座位大小</span>
+            <div class="seat-tool-box-slider">
+              <el-slider v-model="scaleNum" :min="30" :max="100" style="width: 80px;"></el-slider>
+            </div>
+            <div style="display: flex;margin-left: 20px;" v-if="seatMapList && JSON.stringify(seatMapList) != '{}'">
+              <div>座位余量:</div>
+              <div :key="index" v-for="(item, index) in seatTypeList" style="margin-left: 10px;align-items: center;">
+                <span :style="{ color: item.color ? item.color : 'none' }">{{ item.name ? (item.name + '(剩余:' +
+                  (item.num || 0)
+                  + ')')
+                  :
+                  '暂未命名'}}</span>
+              </div>
             </div>
           </div>
-        </div>
-        <div class="seat-box" :style="{ '--scaleNum': scaleNum / 100 }">
-          <!-- 选择座位  -->
-          <div class="seat-list-box">
-            <!--  座位排版  -->
-            <div id="seatbox-me" ref="seatbox" class="dialogss">
-              <div class="dialogss-box"
-                :style="{ width: width * (scaleNum / 100) + 'px', margin: justifyContent ? 'auto' : 'unset' }">
-                <div style="width: 100%;position: absolute;" class="seat-box-class clearfix" v-if="seatMapList">
-                  <div class="seat-item-class-box" v-for="(item1) in seatMapListKey" :key="item1.key">
-                    <div class="seat-item-class"
-                      :class="setSeatClass(item)"
-                      v-for="(item, index) in seatMapList[item1.key]"
-                      :style="{ backgroundColor: item.color ? item.color : 'none' }" @click.stop="seatClick(item)"
-                      :key="index">
-                      <p class="text-class">{{ item.status != 1 ? '不可售' : (item.name ? item.name : '暂未命名') }}</p>
+          <div class="seat-box" :style="{ '--scaleNum': scaleNum / 100 }">
+            <!-- 选择座位  -->
+            <div class="seat-list-box">
+              <!--  座位排版  -->
+              <div id="seatbox-me" ref="seatbox" class="dialogss">
+                <div class="dialogss-box"
+                  :style="{ width: width * (scaleNum / 100) + 'px', margin: justifyContent ? 'auto' : 'unset' }">
+                  <div style="width: 100%;position: absolute;" class="seat-box-class clearfix" v-if="seatMapList">
+                    <div class="seat-item-class-box" v-for="(item1) in seatMapListKey" :key="item1.key">
+                      <div class="seat-item-class" :class="setSeatClass(item)"
+                        v-for="(item, index) in seatMapList[item1.key]"
+                        :style="{ backgroundColor: item.color ? item.color : 'none' }" @click.stop="seatClick(item)"
+                        :key="index">
+                        <p class="text-class">{{ item.status != 1 ? '不可售' : (item.name ? item.name : '暂未命名') }}</p>
+                      </div>
                     </div>
                   </div>
                 </div>
-              </div>
 
-            </div>
-            <div style="margin-top: 5px; margin-left: 30px;display: flex;">
-              <div style="flex-shrink: 0;">
-                已勾选:{{ form.quantity || form.quantity == 0 ?
-              form.quantity : '' }}个座位
+              </div>
+              <div style="margin-top: 5px; margin-left: 30px;display: flex;">
+                <div style="flex-shrink: 0;">
+                  已勾选:{{ form.quantity || form.quantity == 0 ?
+                    form.quantity : '' }}个座位
+                </div>
               </div>
             </div>
           </div>
         </div>
+
+      </div>
+      <!-- 订单日志 -->
+      <div class="dialog-bbb_3">
+        <div class="title-class" style="margin-top: 0;">订单日志</div>
+        <div class="row-warp" v-for="item in logList" :key="item.id">
+          <div class="dateBar">{{ item.createTime }}</div>
+          <div class="textBar">{{ item.name }}</div>
+          <div class="textBar">{{ item.createBy }}</div>
+          <div class="textBar">{{ item.operSource }}</div>
+        </div>
+        <el-empty v-if="logList.length == 0" :image-size="200"></el-empty>
       </div>
     </div>
   </el-dialog>
 </template>
 
 <script>
-import { getSelectById } from '@/api/order/orderMr'
+import { getSelectById, getLogList } from '@/api/order/orderMr'
 import { querySeatList } from '@/api/team/applicationMr'
 import { pageList as getSeatType } from '@/api/seatTypeMr/seatTypeMr'
 export default {
@@ -229,13 +251,12 @@ export default {
       form: {
         id: undefined,
       },
-      resubmit:{},
+      resubmit: {},
       performerVisible: false,
       performerList: [],
       refund: false,
       dataList: [],
-
-
+      logList: [],
       merchantTheatreAuditoriumListS: [], // 演出厅
       merchantPerformTimeListS: [], // 场次
       querySeatListS: [], // 座位
@@ -280,6 +301,14 @@ export default {
       this.setList = [];
       this.seatSelectList = [];
       this.getSelectByIdApi(obj);
+      this.getOrderLogList(obj.id);
+    },
+    // 获取订单日志
+    async getOrderLogList(id) {
+      let res = await getLogList(id)
+      if(res.code === 200) {
+        this.logList = res.data;
+      }
     },
     /** 获取详情 */
     async getSelectByIdApi(row) {
@@ -298,35 +327,35 @@ export default {
       }
       try {
         //this.loading = true
-        this.loading_form =  true//  加载表单
-        this.loading_seta =  true //  加载座位
+        this.loading_form = true//  加载表单
+        this.loading_seta = true //  加载座位
         // const id = row.id
         let res = await getSelectById(id)
         let list = []
-        res.data.viewersList.forEach((item,index)=>{
+        res.data.viewersList.forEach((item, index) => {
           let list1 = item.seatIds.split(',')
-          let seatNameList = item.seatName?item.seatName.split(','):[]
-          let nameList = item.nameList?item.nameList.split(','):[]
-          let idcardList = item.idcardList?item.idcardList.split(','):[]
-          let mobileList = item.mobileList?item.mobileList.split(','):[]
-          list1.forEach((item1,index1)=>{
+          let seatNameList = item.seatName ? item.seatName.split(',') : []
+          let nameList = item.nameList ? item.nameList.split(',') : []
+          let idcardList = item.idcardList ? item.idcardList.split(',') : []
+          let mobileList = item.mobileList ? item.mobileList.split(',') : []
+          list1.forEach((item1, index1) => {
             list.push({
               ...item,
-              mobile: mobileList[index1]||'',
-              seatName: seatNameList[index1]||'',
-              idcard: idcardList[index1]||'',
+              mobile: mobileList[index1] || '',
+              seatName: seatNameList[index1] || '',
+              idcard: idcardList[index1] || '',
               seatIds: item1,
-              name: nameList[index1]||''
+              name: nameList[index1] || ''
             })
           })
         })
-        this.resubmit = res.data.resubmit||{};
+        this.resubmit = res.data.resubmit || {};
         this.seatSelectList = list
         this.$set(this, "form", {
           ...res.data,
           viewersList: list
         })
-        this.loading_form =  false//  加载表单
+        this.loading_form = false//  加载表单
         let res1 = await querySeatList({
           auditoriumId: res.data.auditoriumId,
           //seatTypeId: res.data.seatTypeId,
@@ -337,7 +366,7 @@ export default {
         if (this.setList && this.setList.length > 0) {
           this.setSeatMapListCopy(this.setList);
         }
-        this.loading_seta =  false//  加载表单
+        this.loading_seta = false//  加载表单
         this.loading = false
       } catch (error) {
         console.error(error)
@@ -354,6 +383,7 @@ export default {
      */
     cancel() {
       this.open = false;
+      this.logList = [];
     },
     // 设置座位集合
     setSeatMapListCopy(list) {
@@ -423,7 +453,7 @@ export default {
       }
       let flog = false
       this.seatSelectList.forEach((item1, index1) => {
-        if (item1.seatIds.indexOf(item.id) != -1 ) {
+        if (item1.seatIds.indexOf(item.id) != -1) {
           flog = true
         }
       })
@@ -440,16 +470,16 @@ export default {
         });
     },
     /** 座位状态 展示  */
-    setSeatClass(item){
+    setSeatClass(item) {
       let srt =
-      this.setIsSelect(item)?'purchased-status':
-      item.occupyStatus == 0 ? 
-      item.occupyOrderId?'order-occupy-status':
-      'occupy-status' : 
-      item.occupyStatus == 1 ? 'occupy-status-no' : 
-      item.isDisabled || item.status != 1 ? 'disabled-class' : 
-      item.isSelect ? 'select-class' : ''
-      console.log("srt=====",srt)
+        this.setIsSelect(item) ? 'purchased-status' :
+          item.occupyStatus == 0 ?
+            item.occupyOrderId ? 'order-occupy-status' :
+              'occupy-status' :
+            item.occupyStatus == 1 ? 'occupy-status-no' :
+              item.isDisabled || item.status != 1 ? 'disabled-class' :
+                item.isSelect ? 'select-class' : ''
+      console.log("srt=====", srt)
       return srt
     }
   },
@@ -500,24 +530,43 @@ export default {
 .dialog-bbb {
   width: 100%;
   display: flex;
-  --widdd: 700px;
+  --widdd: 480px;
 
   >div:first-child {
-    width: var(--widdd);
+    // width: var(--widdd);
+    width: calc(100% - var(--widdd));
     flex-shrink: 0;
     overflow-y: auto;
     padding: 0 0 10px 0;
     margin-right: 10px;
   }
 
-  .dialog-bbb_2 {
-    width: calc(100% - var(--widdd));
+  .dialog-bbb_3 {
+    width: var(--widdd);
+    // width: calc(100% - var(--widdd));
     height: 100%;
+    overflow-y: auto;
+    .row-warp {
+      margin-bottom: 15px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      .dateBar {
+        width: 140px;
+      }
+      .textBar {
+        flex: 1;
+      }
+
+    }
   }
 }
 
 .dialog-bbb_2 {
+  width: 100%;
+  height: 560px;
   .seat-tool-box {
+    width: 100%;
     height: 20px;
     box-sizing: border-box;
     display: flex;
@@ -531,14 +580,15 @@ export default {
     }
 
     .seat-tool-box-slider {
-      width: 100px;
+      width: 80px;
       margin-left: 10px;
     }
   }
 
   .seat-box {
     width: 100%;
-    height: calc(100% - 50px);
+    // height: calc(100% - 50px);
+    height: 500px;
     box-sizing: border-box;
     display: flex;
     position: relative;
@@ -734,26 +784,27 @@ export default {
       .occupy-status {
         //pointer-events: none;
       }
+
       /** 订单待支付锁定 */
-      .order-occupy-status {
+      .order-occupy-status {}
 
-      }
-      .order-occupy-status:after{
-        content:"";
-        display:block;
-        position:absolute;
-        top:0;
-        left:0;
-        width:100%;
-        height:100%;
-        background-color:rgba(0,0,0,0.3);
-        z-index:-1;
+      .order-occupy-status:after {
+        content: "";
+        display: block;
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        background-color: rgba(0, 0, 0, 0.3);
+        z-index: -1;
         background-image: url('../../../../assets/jinzhi.png');
         background-size: 50% 50%;
         background-position: 50% 50%;
         background-repeat: no-repeat;
         z-index: 99;
       }
+
       .occupy-status-no {
         background-color: #f56c6c !important;
         user-select: none;

+ 4 - 4
src/views/statisticalReport/daily.vue

@@ -142,7 +142,8 @@
       };
     },
     created() {
-      this.$set(this.queryParams,'performDate',moment().format("yyyy-MM-DD"));
+      // this.$set(this.queryParams,'performDate',moment().format("yyyy-MM-DD"));
+      this.$set(this.queryParams,'performDate',moment().add(1, 'days').format('YYYY-MM-DD'));
       this.pagePerformTimeListFun(this.performDate)
       this.getList();
     //   this.ticketListApi();
@@ -158,7 +159,6 @@
         bookingReportCount(this.addDateRange(this.queryParams, this.dateRange))
         .then(response => {
             // this.responseData = response.data;
-            console.log(response,'response');
             
             this.dataList = response.data.rows||[];
             this.total = response.data.total||0;
@@ -222,13 +222,13 @@
         this.$set(this.queryParams, 'seatTypeId', '');
         this.$set(this.queryParams, 'timeId', '');
         // this.queryParams.pageNum = 1;
-        this.$set(this.queryParams,'performDate',moment().format("yyyy-MM-DD"));
+        // this.$set(this.queryParams,'performDate',moment().format("yyyy-MM-DD"));
+        this.$set(this.queryParams,'performDate',moment().add(1, 'days').format('YYYY-MM-DD'));
         this.handleQuery();
       },
       dateChange(e){
         this.queryParams.timeId = '';
         this.pagePerformTimeListFun(e)
-        console.log('dateChange',e)
       },
       async pagePerformTimeListFun(value) {
             // console.log('value',value);

+ 9 - 8
src/views/statistics/index.vue

@@ -15,13 +15,14 @@
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form> -->
+    
+    <!-- v-hasPermi="[item.hasPermi]" -->
     <div class="box-class clearfix">
       <div class="title-type">销售分析</div>
       <div 
-      class="item-class clearfix" 
-      @click="pageLink(item.url)" 
-      v-hasPermi="[item.hasPermi]"
-      v-for="item in itemList" :key="item.id">
+        class="item-class clearfix" 
+        @click="pageLink(item.url)" 
+        v-for="item in itemList" :key="item.id">
         <div class="span-img-class"></div>
         <div class="span-text-class">{{ item.name }}</div>
       </div>
@@ -29,10 +30,9 @@
     <div class="box-class clearfix">
       <div class="title-type">运营分析</div>
       <div 
-      class="item-class clearfix" 
-      @click="pageLink(item.url)" 
-      v-hasPermi="[item.hasPermi]"
-      v-for="item in dataList" :key="item.id">
+        class="item-class clearfix" 
+        @click="pageLink(item.url)" 
+        v-for="item in dataList" :key="item.id">
         <div class="span-img-class"></div>
         <div class="span-text-class">{{ item.name }}</div>
       </div>
@@ -122,6 +122,7 @@ export default {
        float: left;
        cursor: pointer;
        margin-right: 60px;
+       margin-bottom: 25px;
 
        .span-img-class{
          background: url("../../assets/images/statistics-icon.png") no-repeat;

+ 1422 - 0
src/views/windowTicketSales/lock.vue

@@ -0,0 +1,1422 @@
+<template>
+  <div class="app-container app-container-me">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" :rules="rules" label-width="80px">
+      <el-form-item label="演出厅" prop="auditoriumId">
+        <el-select v-model="queryParams.auditoriumId" placeholder="演出厅" clearable style="width: 100%"
+          @change="changeTime($event, 'auditoriumId')">
+          <el-option v-for="dict in merchantTheatreAuditoriumListS" :key="dict.id" :label="dict.name"
+            :value="dict.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="场次时间" prop="performDate">
+        <el-date-picker type="date" placeholder="选择场次时间" v-model="queryParams.performDate"
+          @change="changeTime($event, 'performDate')" value-format="yyyy-MM-dd"></el-date-picker>
+      </el-form-item>
+      <el-form-item label="场次" prop="timeId">
+        <el-select v-model="queryParams.timeId" placeholder="场次" clearable style="width: 100%"
+          @change="changeTime($event, 'timeId')">
+          <el-option v-for="dict in merchantPerformTimeListS" :key="dict.id"
+            :label="dict.timeSnapshot + '(' + dict.performTimeStart + '-' + dict.performTimeEnd + ')'"
+            :value="dict.id" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="票种" prop="goodsId">
+        <el-select v-model="queryParams.goodsId" placeholder="请选择票种" clearable style="width: 100%"
+          @change="changeTime($event, 'goodsId')">
+          <el-option v-for="dict in goodsPageListS" :key="dict.goodsId" :label="dict.goodsName" :value="dict.goodsId"
+            :disabled="dict.status == 1" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button :loading="loading" type="primary" icon="el-icon-search" size="mini"
+          @click="handleQuery">搜索</el-button>
+        <el-button :loading="loading" icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <div class="seat-tool-box">
+      <span class="demonstration">座位大小</span>
+      <div class="seat-tool-box-slider">
+        <el-slider v-model="scaleNum" :min="30" :max="100" @change="scaleNumChange"></el-slider>
+      </div>
+      <div style="display: flex;margin-left: 20px;" v-if="seatMapList && JSON.stringify(seatMapList) != '{}'">
+        <div>各类型座位的剩余数量:</div>
+        <div :key="index" v-for="(item, index) in seatTypeList" style="margin-left: 10px;align-items: center;">
+          <span :style="{ color: item.color ? item.color : 'none' }">{{ item.name ? (item.name + '(剩余:' +
+            (item.num || 0)
+            + ')') : '暂未命名' }}</span>
+        </div>
+      </div>
+    </div>
+    <div class="seat-box" :style="{ '--scaleNum': scaleNum / 100 }">
+      <!-- 选择座位  -->
+      <div class="seat-list-box" v-loading="loading">
+        <!--  座位排版  -->
+        <div id="sm-scroll-box" ref="seatbox" class="dialog" @mousedown="mousedownFun" @mouseleave="mouseleaveFun"
+          @scroll="scrollFun">
+          <div class="dialog-box"
+            :style="{ width: width * (scaleNum / 100) + 'px', margin: justifyContent ? 'auto' : 'unset' }">
+            <div style="width: 100%;position: absolute;" class="seat-box-class clearfix" v-if="seatMapList">
+              <div class="seat-item-class-box" v-for="(item1, index1) in seatMapListKey" :key="item1.key">
+                <div class="seat-item-class seat-box-class-row" style="">{{ index1 != 0 ? ((index1) +
+                  '排') : '' }}</div>
+
+                <div :class="[
+                  'seat-item-class',
+                  showSearStyle(item1, item)
+                ]" v-for="(item, index) in seatMapList[item1.key]"
+                  :style="{ backgroundColor: item.color && !(item.isDisabled || item.status != 1) ? item.color : 'none' }"
+                  @click.stop="seatClick(item)" @mouseenter="lockOrUnLockDeatilFun($event, item)"
+                  @mouseleave="lockOrUnLockDeatilFun1" :dragSelectId="item.id" :index="item1.key + '_' + index"
+                  :key="index">
+                  <p v-if="item1.key != 'my_column'" class="text-class">{{ item.status != 1 ?
+                    '不可售' : (item.name ? item.name : '暂未命名') }}</p>
+                  <p v-else>{{ (index + 1) + '号' }}</p>
+                </div>
+              </div>
+            </div>
+          </div>
+
+
+          <!-- 鼠标拖拽出的遮罩 (定位为 position:absolute)-->
+          <!-- 遮罩最好是在绑定了mouseover事件的元素内部,并且不要阻止遮罩的冒泡事件。这样鼠标移到了遮罩上面,依然可以利用冒泡执行父元素的mouseover事件,就不会出现遮罩只能扩大,不能缩小的情况了(亲自试过) -->
+          <div id="moveSelected"></div>
+        </div>
+        <div class="bottom-warp">
+          <div style="flex-shrink: 0;">
+            <span>已勾选可售座位:{{ seatSelectList.length }}</span>,
+            <span>已勾选锁定座位:{{ seatSelectListNo.length }}</span>
+            <el-button size="mini" type="warning" style="margin: 0 15px;"
+              @click="clearSeatSelectListAll">清空已选座位</el-button>
+            <el-button size="mini" v-hasPermi="['windowTicketSales:ticket:lock']" type="danger"
+              :loading="lockOrUnLockLoading" @click="lockOrUnLockFun(0)">{{
+                seatSelectListNo.length > 0 ? '解 锁' : '锁 定' }}</el-button>
+          </div>
+          <!-- <div style="width: 100%;display: flex;justify-content: center;height: 30px;">
+            <el-button size="mini" v-hasPermi="['windowTicketSales:ticketingSales:lock']" type="warning"
+              :loading="lockOrUnLockLoading" @click="lockOrUnLockFun(0)">{{
+                seatSelectListNo.length > 0 ? '解锁' : '锁定' }}</el-button>
+            <el-button size="mini" v-hasPermi="['windowTicketSales:ticketingSales:buy']" type="primary"
+              @click="increaseViewersFun">购票</el-button>
+          </div> -->
+          <div class="selectInfo">
+            <div class="selectItem" :key="index" v-for="(item, index) in seatSelectList">
+              <div>
+                <span>{{ item.name ? item.name : '暂未命名' }}</span>
+                <span v-if="item.salePrice">¥{{ item.salePrice }}</span>
+                <span v-else>未配置价格</span>
+                <!-- <span>{{ setSeatTypeShow(item.seatTypeId) }}</span> -->
+              </div>
+              <div>
+                <!-- <span @click="delSeatSelect(item)">删除</span> -->
+                <span>
+                  <i class="el-icon-close" @click="delSeatSelect(item)"></i>
+                </span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="seat-select-box">
+        <!-- <div class="seat-select-box-top">
+          <el-tabs v-model="activeName" @tab-click="handleClickTab">
+            <el-tab-pane label="已选座位" name="first"></el-tab-pane>
+          </el-tabs>
+        </div> -->
+        <div class="subtitle">座位操作日志</div>
+        <div class="main-box" v-for="(item, index) in logList" :key="index">
+          <p>{{ item.seatName }}</p>
+          <p>日志:</p>
+          <div class="row-warp" v-for="(ele, index) in item.logList" :key="ele.id">
+            <div class="dateBar">{{ ele.createTime }}</div>
+            <div class="textBar">{{ ele.statusName }}</div>
+            <div class="textBar">{{ ele.updateBy }}</div>
+          </div>
+        </div>
+        <el-empty v-if="logList.length == 0" :image-size="200"></el-empty>
+
+        <!-- <div class="seat-select-info" v-if="activeName == 'first'">
+          <div class="seat-select-item" :key="index" v-for="(item, index) in seatSelectList">
+            <div>
+              <span>{{ item.name ? item.name : '暂未命名' }}</span>
+              <span>{{ setSeatTypeShow(item.seatTypeId) }}</span>
+            </div>
+            <div>
+              <span @click="delSeatSelect(item)">删除</span>
+            </div>
+          </div>
+        </div>
+        <div class="seat-select-info" v-if="activeName == 'second'">
+          <div class="seat-select-color-item" :key="index" v-for="(item, index) in seatTypeList">
+            <span :style="{ backgroundColor: item.color ? item.color : 'none' }"></span>
+            <span>{{ item.name ? item.name : '暂未命名' }}</span>
+          </div>
+        </div> -->
+      </div>
+    </div>
+    <!--  锁座备注  -->
+    <lock-seat ref="lockSeat" @querySeatListFun="querySeatListFun" />
+    <!--  添加观影人  -->
+    <increaseViewers ref="increaseViewers" @clearDialogVisible="clearDialogVisible" />
+
+    <!-- 提示信息  -->
+    <div :style="lockStyle" v-if="isLcokShow" class="lock-style-box">
+      <div><span>锁定人:</span><span>{{ lockObj.auth }}</span></div>
+      <div><span>锁定原因:</span><span>{{ lockObj.remark }}</span></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  querySeatList,
+  merchantPerformTimeList,
+  merchantPerformTimeListNew,
+  lockOrUnLock,
+  merchantTheatreAuditoriumList,
+  goodsPageList,
+  getGoodsPerformApi,
+  lockOrUnLockApi,
+  querySeatListNew,
+  seatLockLogs
+} from '@/api/windowTicketSales/ticketingSales'
+//import increaseViewers from "./model/increaseViewers"
+import increaseViewers from "./model/increaseViewersNew"
+import moment from "moment"
+import { pageList as getSeatType } from '@/api/seatTypeMr/seatTypeMr'
+import selectListMixin from "./mixins/selectList"
+import LockSeat from './model/lockSeat.vue'
+export default {
+  name: "Lock",
+  components: {
+    increaseViewers,
+    LockSeat
+  },
+  mixins: [selectListMixin],
+  dicts: ['channel_type'],
+  data() {
+    return {
+      // 遮罩层
+      loading: false,
+      // 查询参数
+      queryParams: {
+        timeId: '',
+        performDate: null,
+        auditoriumId: null,
+        goodsId: null,
+      },
+      rules: {
+        auditoriumId: [
+          { required: true, message: '请选择演出厅', trigger: ['blur', 'change'] }
+        ],
+        performDate: [
+          { required: true, message: '请选择时间', trigger: ['blur', 'change'] }
+        ],
+        timeId: [
+          { required: true, message: '请选择场次', trigger: ['blur', 'change'] }
+        ],
+        goodsId: [
+          { required: true, message: '请选择票种', trigger: ['blur', 'change'] }
+        ],
+      },
+      merchantTheatreAuditoriumListS: [], // 演出厅
+      merchantPerformTimeListS: [], // 场次
+      querySeatListS: [], // 座位
+      goodsPageListS: [], // 票务
+      goodsPageListSAll: [], // 票务全部
+      setList: [],
+      seatMapList: {},
+      seatMapListKey: [], // key
+      seatSelectList: [],
+      seatSelectListNo: [], // 锁定的座位
+      logList:[], // 锁定座位日志
+
+      lockOrUnLockLoading: false,
+
+      performId: '',// 剧目ID
+      scaleNum: 30,
+
+      width: 0,
+      justifyContent: false,
+      activeName: 'first',
+      seatTypeList: [],
+
+      // 限购条件
+      ifRealUser: 0,// 散客是否实名:0-否 1-是
+      ifRealTeam: 0,// 团购是否实名:0否 1-是
+      oneMany: 0,// 证件要求: 1一证一票,2一证多票
+      personnelNum: 0,// 人员要求:0-表示不限制 其他数字表示限制人数
+
+      isLcokShow: false,
+      lckTime: null,
+      seatId: null,
+      lockStyle: {
+
+      },
+      lockObj: {
+        auth: '',
+        remark: ''
+      },
+      salePrice: null,
+      stockType: null,
+    };
+  },
+  created() {
+    this.merchantTheatreAuditoriumListFun()
+    this.goodsPageListFun()
+    this.getSeatTypeList()
+  },
+  mounted() {
+    this.$set(this.queryParams, 'performDate', moment().format("yyyy-MM-DD"))
+  },
+  watch: {
+      seatSelectList(newVal, oldVal) {
+        if(newVal.length > 0){
+            this.getSeatLockLogs()
+        } else {
+          this.logList = []
+        }
+      },
+      seatSelectListNo(newVal, oldVal) {
+        if(newVal.length > 0){
+            this.getSeatLockLogs()
+        } else {
+          this.logList = []
+        }
+      }
+    },
+  methods: {
+    moment,
+
+    setChanneltype(key) {
+      let srt = ''
+      this.dict.type.channel_type.forEach((item, index) => {
+        if (key == item.value) {
+          srt = item.label
+        }
+      })
+      return srt
+    },
+    /**  票务信息  */
+    async goodsPageListFun() {
+      try {
+        let res = await goodsPageList({
+          pageNum: 1,
+          pageSize: 999,
+          classifyId: 1,
+          goodsType: 2,
+        })
+        if (res.code == 200) {
+          this.goodsPageListSAll = res.data.rows
+          // let list = []
+          // res.data.rows.forEach((item,index)=>{
+          //     if(item.status != 1) {
+          //         list.push(item)
+          //     }
+          // })
+          // this.goodsPageListS = list
+        }
+      } catch (error) {
+
+      }
+    },
+    // 获取 日志
+    async getSeatLockLogs() {
+      let ids = []
+      console.log(this.seatSelectList,'this.seatSelectList');
+      if(this.seatSelectList.length > 0) {
+        ids = this.seatSelectList.map(ele => ele.id)
+      }
+      if(this.seatSelectListNo.length > 0) {
+        ids = this.seatSelectListNo.map(ele => ele.id)
+      }
+      console.log(ids,'ids');
+      this.logList = []
+      let res = await seatLockLogs({
+        auditoriumId: this.queryParams.auditoriumId,
+        timeId: this.queryParams.timeId,
+        seatIds: ids.join(','),
+      })
+      console.log(res,'1111');
+      if (res.code == 200) {
+        this.logList = res.data.rows;
+      }
+    },
+    /**  获取演出厅  */
+    async merchantTheatreAuditoriumListFun() {
+      try {
+        let res = await merchantTheatreAuditoriumList({
+          pageNum: 1,
+          pageSize: 999
+        })
+        if (res.code == 200) {
+          this.merchantTheatreAuditoriumListS = res.data.rows
+          if (this.merchantTheatreAuditoriumListS.length > 0) {
+            this.$set(this.queryParams, 'auditoriumId', this.merchantTheatreAuditoriumListS[0].id)
+            this.changeTime(this.queryParams.auditoriumId, 'auditoriumId')
+          }
+
+        }
+      } catch (error) {
+
+      }
+    },
+    /**  获取场次  */
+    async merchantPerformTimeListFun() {
+      try {
+        let param = JSON.parse(JSON.stringify(this.queryParams));
+        param.status = 1;
+        let res = await merchantPerformTimeListNew(param)
+        if (res.code == 200) {
+          console.log('merchantPerformTimeListS', res.data.rows);
+          this.merchantPerformTimeListS = res.data.list
+
+        }
+      } catch (error) {
+
+      }
+    },
+    /**  座位锁定/解锁  */
+    async lockOrUnLockFun(type) {
+      try {
+        let listS = this.seatSelectListNo.length > 0 ? this.seatSelectListNo : this.seatSelectList
+        if (listS.length <= 0) {
+          this.$message.error(`请选择锁定的座位!!!`);
+          return
+        }
+        if (this.seatSelectListNo.length == 0) {
+          this.$refs.lockSeat.open(this.seatSelectListNo, this.seatSelectList, this.queryParams.auditoriumId, this.queryParams.timeId)
+        } else {
+          this.lockOrUnLockLoading = true
+          let list = []
+          listS.forEach((item, index) => {
+            list.push({
+              "auditoriumId": this.queryParams.auditoriumId,
+              "seatId": item.id,
+              "timeId": this.queryParams.timeId
+            })
+          })
+          let res = await lockOrUnLock({
+            type: this.seatSelectListNo.length > 0 ? 1 : 0,
+            seatList: list
+          })
+          this.lockOrUnLockLoading = false
+          if (res.code) {
+            this.$message({
+              showClose: true,
+              message: res.msg,
+              type: 'success'
+            });
+            this.querySeatListFun(true)
+          }
+        }
+
+      } catch (error) {
+        this.lockOrUnLockLoading = false
+        this.$message({
+          showClose: true,
+          message: "操作失败!!!",
+          type: 'error'
+        });
+        console.error('error===', error)
+      }
+
+    },
+    /**  获取座位  */
+    async querySeatListFun(type) {
+      try {
+        this.loading = true
+        this.performId = ''
+        this.screenTop = 0
+        this.scrollLeft = 0
+        if (type) { // 是否清除已选
+          this.seatSelectList = []
+          this.seatSelectListNo = []
+        }
+        this.seatMapList = {}
+        this.seatList = []
+        let res = await querySeatListNew({
+          ...this.queryParams,
+          channelType: 'window'
+        })
+        if (res.code == 200) {
+          this.querySeatListS = res.data;
+          this.setList = res.data;
+          if (this.setList && this.setList.length > 0) {
+            this.setSeatMapList(this.setList);
+          }
+        }
+        this.loading = false
+      } catch (error) {
+        this.loading = false
+        console.error("error===", error)
+      }
+    },
+    // 设置座位集合
+    setSeatMapList(list) {
+      if (list && list.length > 0) {
+        let listCopy = {}
+        let lisyCopy1 = {}
+        let listNum = JSON.parse(JSON.stringify(this.seatTypeList))
+        listNum.forEach((item, index) => {
+          listNum[index]['num'] = 0
+        })
+        list.forEach(item => {
+          item.isDisabled = item.occupyStatus == 1 || (item.occupyStatus == 0 && item.occupyOrderId) ? true : false //(item.occupyStatus != null && (item.occupyStatus == 0 || item.occupyStatus == 1) ? true : false); // 座位是否已被选择
+          item.isSelect = this.setIsSelect(item);
+          if (item.rowNo) {
+            listNum.forEach((item1, index) => {
+              if (item1.id == item.seatTypeId && item.status == 1 && !item.occupyStatus && item.occupyStatus != 0) {
+                listNum[index]['num'] = listNum[index]['num'] + 1
+              }
+            })
+            if (listCopy['my' + item.rowNo]) {
+              listCopy['my' + item.rowNo].push(item)
+            } else {
+              listCopy['my' + item.rowNo] = [item]
+            }
+          }
+        })
+        this.seatTypeList = JSON.parse(JSON.stringify(listNum))
+        let width = 0
+        let flog = 0
+        let seatMapListKey = []
+        Object.keys(listCopy).forEach((item) => {
+          if (listCopy[item].length > flog) {
+            flog = listCopy[item].length
+          }
+          seatMapListKey.push({
+            key: item,
+            sort: Number(item.replace('my', ''))
+          })
+        })
+        seatMapListKey.sort((a, b) => {
+          return a.sort - b.sort
+        })
+        this.seatMapListKey = seatMapListKey
+        console.log("seatMapListKey=====", seatMapListKey)
+        this.width = 70 * (flog + 1)
+        this.$nextTick(() => {
+          if (this.$refs.seatbox) {
+            var ele = this.$refs.seatbox
+            console.log(ele.getBoundingClientRect().width); // 100
+            if (this.width < ele.getBoundingClientRect().width) {
+              this.justifyContent = true
+            } else {
+              //this.justifyContent = false
+              this.justifyContent = true
+            }
+            //this.$refs.seatbox.scrollTo(this.width/4,0)
+          }
+        })
+
+        console.log("list====", listCopy)
+
+        let columnList = []
+        listCopy[seatMapListKey[0].key].forEach((item, index) => {
+          columnList.push({
+            ...item,
+            occupyStatus: 2,
+            isDisabled: true,
+            status: 0
+          })
+        })
+        this.seatMapListKey.unshift({
+          key: "my_column",
+          sort: -99
+        })
+        listCopy['my_column'] = columnList
+        this.seatMapList = JSON.parse(JSON.stringify(listCopy))
+      }
+    },
+    setIsSelect(item) {
+      if (!this.seatSelectList || this.seatSelectList.length == 0) {
+        return false
+      }
+      let flog = false
+      this.seatSelectList.forEach((item1, index1) => {
+        if (item.id == item1.id) {
+          flog = true
+        }
+      })
+      return flog
+    },
+    /**  选择场次时间  */
+    changeTime(value, type) {
+      // console.log("fsdfsdf----",value,type)
+      if (type == 'timeId') {
+        this.$set(this.queryParams, 'goodsId', '')
+        this.stockType = null
+        if (value) {
+          let flog = false
+          let list2 = []
+          this.merchantPerformTimeListS.forEach((item, index) => {
+            if (item.id == value) {
+              flog = true
+              list2 = item.goodsList
+              this.stockType = item.stockType
+            }
+          })
+          this.goodsPageListS = []
+          setTimeout(() => {
+            this.goodsPageListS = list2
+          }, 500)
+
+        } else {
+          this.goodsPageListS = []
+        }
+      }
+      this.changeTimeCheck(value, type)
+
+    },
+    /**  选择场次时间  */
+    async changeTimeCheck(value, type) {
+      // console.log("fsdfsdf")
+      if (this.queryParams && this.queryParams.timeId && type != 'timeId' && type != 'goodsId') {
+        this.$set(this.queryParams, 'timeId', '')
+        this.$set(this.queryParams, 'goodsId', '')
+        this.merchantPerformTimeListS = []
+        this.goodsPageListS = []
+      }
+      if (this.queryParams.auditoriumId && this.queryParams.performDate && type != 'timeId' && type != 'goodsId') {
+        //  获取场次
+        this.merchantPerformTimeListFun()
+      }
+      if (type == 'goodsId') {
+        //this.$refs.queryForm.clearValidate("goodsId")
+        if (value) {
+          // console.log("dsfsdfdsfds===",value)
+          await this.getGoodsPerformFun(value);
+
+          this.handleQuery()
+        }
+      } else {
+        this.ifRealUser = 0  // 散客是否实名:0-否 1-是
+        this.ifRealTeam = 0   // 团购是否实名:0否 1-是
+        this.oneMany = 1   // 证件要求: 1一证一票,2一证多票
+        this.personnelNum = 0   // 人员要求:0-表示不限制 其他数字表示限制人数
+      }
+      this.seatMapListKey = {}
+      this.performId = ''
+      this.seatSelectList = []
+      this.seatSelectListNo = []
+      this.seatMapList = {}
+      this.seatList = []
+      // this.handleQuery()
+
+    },
+    /**  设置 场次 对应得剧目ID */
+    changePerformId(value) {
+      console.log("value=====", value)
+      this.performId = ''
+      this.merchantPerformTimeListS.forEach((item, index) => {
+        if (item.id == value) {
+          this.performId = item.performId
+        }
+      })
+    },
+    /**  设置 票务 对应价格 */
+    changeSalePrice(value) {
+      console.log("value=====", value)
+      this.salePrice = null
+      this.goodsPageListS.forEach((item, index) => {
+        if (item.goodsId == value) {
+          this.salePrice = item.salePrice
+        }
+      })
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.querySeatListFun(true);
+      // this.$refs.queryForm.validate((valid) => {
+      // if (valid) {
+      //     this.querySeatListFun(true);
+      // } else {
+      //     console.log('error submit!!',valid);
+      //     return false;
+      // }
+      // });
+
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.$refs.queryForm.resetFields()
+      this.performId = ''
+      this.seatSelectList = []
+      this.seatSelectListNo = []
+      this.seatMapList = {}
+      this.seatList = []
+      this.handleQuery();
+
+    },
+
+    // 座位点击事件
+    seatClick(row) {
+      if (row.isDisabled || row.status == 2) {
+        return false
+      }
+      if (row.channelType != 'window') {
+        if (row.channelType) {
+          this.$message.error(`该座位仅限${this.setChanneltype(row.channelType)}渠道购买!!!`);
+          return false
+        } else if (row.isUse == 2) {
+          this.$message.error(`该座位仅限其他渠道购买!!!`);
+          return false
+        }
+      }
+
+      if (this.seatSelectListNo.length > 0 && row.occupyStatus != 0) {
+        this.$message.error('你已选择锁定座位,只能再选择被锁定的座位!!!');
+        return
+      }
+      if (this.seatSelectList.length > 0 && row.occupyStatus == 0) {
+        this.$message.error('此座已被锁定,请先解锁!!!');
+        return
+      }
+      if (row.occupyStatus == 0) {
+        // console.log("weqwrwerewrer")
+        // this.$confirm('此座已被锁定,请先解锁', '提示', {
+        //     confirmButtonText: '确定',
+        //     cancelButtonText: '取消',
+        //     type: 'warning'
+        // }).then(() => {
+        //     this.lockOrUnLockFun([row],1)
+        // }).catch((error) => {
+        //     console.log("error====",error)
+        // });
+        row.isSelect = !row.isSelect
+        if (row.isSelect) {
+          this.seatSelectListNo.push(JSON.parse(JSON.stringify(row)))
+        } else {
+          let list = JSON.parse(JSON.stringify(this.seatSelectListNo))
+          list.forEach((item, index) => {
+            if (item.id == row.id) {
+              this.seatSelectListNo.splice(index, 1)
+            }
+          })
+        }
+      } else if (row.isDisabled || row.status == 2) {
+        return false
+      } else {
+        let flog = false;
+        this.seatSelectList.forEach((item, index) => {
+          if (item.seatTypeId != row.seatTypeId) {
+            flog = true
+          }
+        })
+        if (flog) {
+          this.$message.error('只能选同一类型的座位');
+          return
+        }
+        row.isSelect = !row.isSelect
+        if (row.isSelect) {
+          this.seatSelectList.push(JSON.parse(JSON.stringify(row)))
+        } else {
+          let list = JSON.parse(JSON.stringify(this.seatSelectList))
+          list.forEach((item, index) => {
+            if (item.id == row.id) {
+              this.seatSelectList.splice(index, 1)
+            }
+          })
+        }
+        //this.$forceUpdate()
+      }
+
+    },
+    /** 删除已选座位  */
+    delSeatSelect(row) {
+      console.log(row, 'row222');
+
+      // row.isSelect = !row.isSelect
+      // if(row.isSelect){
+      //     this.seatSelectList.push(JSON.parse(JSON.stringify(row)))
+      // }else {
+      //     let list = JSON.parse(JSON.stringify(this.seatSelectList))
+      //     list.forEach((item,index)=>{
+      //         if(item.id == row.id) {
+      //             this.seatSelectList.splice(index, 1)
+      //         }
+      //     })
+      // }
+      let list = JSON.parse(JSON.stringify(this.seatSelectList))
+      list.forEach((item, index) => {
+        if (item.id == row.id) {
+          this.seatSelectList.splice(index, 1)
+        }
+      })
+      Object.keys(this.seatMapList).forEach((item1, index) => {
+        this.seatMapList[item1].forEach((item, index) => {
+          if (item.id == row.id) {
+            item.isSelect = !item.isSelect
+          }
+        })
+
+      })
+      this.$forceUpdate()
+    },
+    increaseViewersFun() {
+      if (this.seatSelectList.length > 0) {
+        // if(this.ifRealUser != 0 || this.ifRealTeam != 0 ) {
+        //     if(this.personnelNum != 0) {
+        //         if( this.seatSelectList.length != this.personnelNum ) {
+        //             this.$message.error(`票务类型设置了实名要求,选择人数为${ this.personnelNum }人`);
+        //             return
+        //         }
+        //     }
+        // }
+        if (this.personnelNum != 0) {
+          if (this.seatSelectList.length != this.personnelNum) {
+            this.$message.error(`票务类型设置了实名要求,选择人数为${this.personnelNum}人`);
+            return
+          }
+        }
+        this.changePerformId(this.queryParams.timeId)
+        this.changeSalePrice(this.queryParams.goodsId)
+        this.$refs.increaseViewers.initData(this.seatSelectList, {
+          ...this.queryParams,
+          performId: this.performId,
+          ifRealUser: this.ifRealUser,  // 散客是否实名:0-否 1-是
+          ifRealTeam: this.ifRealTeam,   // 团购是否实名:0否 1-是
+          oneMany: this.oneMany,   // 证件要求: 1一证一票,2一证多票
+          personnelNum: this.personnelNum,   // 人员要求:0-表示不限制 其他数字表示限制人数
+          seatTypeId: this.seatSelectList[0].seatTypeId,
+          seatTypeName: this.seatSelectList[0].seatLabel,
+          salePrice: this.salePrice
+        })
+      } else {
+        this.$alert('请先选择座位!!!', '提示', {
+          confirmButtonText: '确定',
+          callback: action => {
+
+          }
+        });
+      }
+
+    },
+    /**  弹窗关闭 */
+    clearDialogVisible() {
+      //this.
+      this.querySeatListFun(true)
+    },
+    /**  选择tab */
+    handleClickTab() {
+
+    },
+    /** 获取座位类型 说明 */
+    getSeatTypeList() {
+      getSeatType({
+        pageNum: 1,
+        pageSize: 999,
+      })
+        .then(response => {
+          this.seatTypeList = response.data.rows;
+        }
+        );
+    },
+    /**   显示座位类型  */
+    setSeatTypeShow(value) {
+      let srt = ''
+      this.seatTypeList.forEach((item, index) => {
+        if (value == item.id) {
+          srt = item.name
+        }
+      })
+
+      return srt
+    },
+
+    //  获取限购标准
+    async getGoodsPerformFun(id) {
+      try {
+        let res = await getGoodsPerformApi({
+          goodsId: id
+        })
+        if (res.code == 200) {
+          this.ifRealUser = res.data.ifRealUser  // 散客是否实名:0-否 1-是
+          this.ifRealTeam = res.data.ifRealTeam   // 团购是否实名:0否 1-是
+          this.oneMany = res.data.oneMany   // 证件要求: 1一证一票,2一证多票
+          this.personnelNum = res.data.personnelNum   // 人员要求:0-表示不限制 其他数字表示限制人数
+        } else {
+          this.ifRealUser = 0  // 散客是否实名:0-否 1-是
+          this.ifRealTeam = 0   // 团购是否实名:0否 1-是
+          this.oneMany = 1   // 证件要求: 1一证一票,2一证多票
+          this.personnelNum = 0   // 人员要求:0-表示不限制 其他数字表示限制人数 
+        }
+
+      } catch (error) {
+        this.ifRealUser = 0  // 散客是否实名:0-否 1-是
+        this.ifRealTeam = 0   // 团购是否实名:0否 1-是
+        this.oneMany = 1   // 证件要求: 1一证一票,2一证多票
+        this.personnelNum = 0   // 人员要求:0-表示不限制 其他数字表示限制人数
+      }
+    },
+    /** 获取锁定人和锁定备注  */
+    async lockOrUnLockDeatilFun(e, item) {
+      try {
+        if (this.lckTime) {
+          clearTimeout(this.lckTime)
+        }
+        if (item.occupyStatus !== 0) {
+          if (item.channelType && item.channelType != 'window') {
+            this.isLcokShow = true
+            this.lockObj = {
+              remark: `该座位仅限${this.setChanneltype(item.channelType)}渠道购买!!!`,
+              auth: ''
+            }
+            this.lockStyle = {
+              position: "fixed",
+              top: (e.y + 10) + 'px',
+              left: (e.x + 10) + 'px',
+              zIndex: 999999
+            }
+            console.log('dsfdsff====', this.lockObj, this.lockStyle)
+            return
+          } else {
+            this.isLcokShow = false
+            return
+          }
+        }
+        if (item.id == this.seatId) { return }
+        this.seatId = item.id
+        this.isLcokShow = false
+        this.lckTime = setTimeout(async () => {
+          let res = await lockOrUnLockApi({
+            auditoriumId: this.queryParams.auditoriumId,
+            timeId: this.queryParams.timeId,
+            seatId: item.id
+          })
+          if (res.code == 200) {
+            this.isLcokShow = true
+            this.lockObj = {
+              remark: res.data.remark,
+              auth: res.data.createBy
+            }
+            this.lockStyle = {
+              position: "fixed",
+              top: (e.y + 10) + 'px',
+              left: (e.x + 10) + 'px',
+              zIndex: 999999
+            }
+          } else {
+            //this.handleClose()
+          }
+        }, 500)
+      } catch (error) {
+        //this.handleClose()
+      }
+    },
+    lockOrUnLockDeatilFun1() {
+      this.isLcokShow = false
+      this.seatId = null
+    },
+    /**  
+     * 座位得样式 
+     * 
+     * occupyStatus: 为null表示未占用,0-锁定 1-占用
+     * status: 状态:0-初始(该状态下不C端显示) 1-可用 2-不可用
+     * channelType: 
+     *  */
+    showSearStyle(item1, item) {
+
+      let srt = ''
+      srt =
+        item1.key == 'my_column' ? 'seat-item-class-column' :
+          item.occupyStatus == 0 ? item.occupyOrderId ? 'order-occupy-status' :
+            item.occupyStatus == 0 && item.isSelect ? 'occupy-status-select occupy-status' :
+              'occupy-status' : item.occupyStatus == 1 ? 'occupy-status-no' :
+            item.isDisabled || item.status != 1 ? 'disabled-class' :
+              item.isSelect ? 'select-class' : ''
+      if (this.stockType == 1) {
+        if (!srt && (item.channelType != 'window' || item.isUse == 2)) {
+          return 'seat_channel_type'
+        }
+      }
+
+      return srt
+    }
+  }
+};
+</script>
+<style>
+.lock-style-box {
+  padding: 10px;
+  border-radius: 10px;
+  position: fixed;
+  z-index: 99999;
+  background-color: rgba(0, 0, 0, 0.5);
+  color: #fff;
+  font-size: 12px;
+}
+</style>
+<style lang="scss" scoped>
+.app-container-me {
+  width: 100%;
+  height: calc(100vh - 120px);
+}
+
+.seat-tool-box {
+  height: 20px;
+  box-sizing: border-box;
+  display: flex;
+  align-items: center;
+
+  span {
+    flex-shrink: 0;
+    font-size: 12px;
+  }
+
+  .seat-tool-box-slider {
+    width: 100px;
+    margin-left: 10px;
+  }
+}
+
+.seat-box {
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  display: flex;
+  position: relative;
+
+  .seat-list-box {
+    width: calc(100% - 310px);
+    //width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+    position: relative;
+
+    .bottom-warp {
+      height: 180px;
+      padding: 10px 20px;
+      margin-top: 5px;
+      border: 1px solid #666;
+      border-radius: 10px;
+      overflow-y: auto;
+
+      .selectInfo {
+        width: 100%;
+        // overflow: hidden;
+        // overflow-y: auto;
+        display: flex;
+        justify-content: flex-start;
+        flex-wrap: wrap;
+        /* 允许换行 */
+        gap: 10px 25px;
+
+        .selectItem {
+          width: 120px;
+          height: 50px;
+          border: 1px solid #ccc;
+          margin-top: 5px;
+          // margin: 5px 12px;
+          padding: 5px;
+          border-radius: 5px;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          font-size: 12px;
+
+          >div:first-child {
+            width: 80px;
+            display: flex;
+            flex-direction: column;
+            text-align: center;
+
+            span:first-child {
+              font-weight: 600;
+            }
+          }
+
+          >div:last-child {
+            span:first-child {
+              color: #f56c6c;
+              cursor: pointer;
+              font-size: 18px;
+            }
+          }
+        }
+
+        .seat-select-color-item {
+          display: flex;
+          align-items: center;
+          margin-bottom: 5px;
+
+          >span:first-child {
+            width: 20px;
+            height: 20px;
+            flex-shrink: 0;
+          }
+
+          >span:last-child {
+            font-size: 16px;
+            font-weight: 600;
+            margin-left: 10px;
+          }
+        }
+      }
+    }
+
+  }
+
+  .seat-select-box {
+    width: 320px;
+    height: calc(100% - 60px);
+    flex-shrink: 0;
+    box-sizing: border-box;
+    padding: 10px;
+    margin-left: 10px;
+    border: 1px solid #ccc;
+    border-radius: 10px;
+    overflow-y: auto;
+
+    .seat-select-info {
+      width: 100%;
+      height: calc(100% - 60px);
+      overflow: hidden;
+      overflow-y: auto;
+
+      .seat-select-item {
+        border: 1px solid #ccc;
+        margin-bottom: 5px;
+        padding: 5px;
+        border-radius: 5px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        font-size: 12px;
+
+        >div:first-child {
+          display: flex;
+          flex-direction: column;
+
+          span:first-child {
+            font-weight: 600;
+          }
+        }
+
+        >div:last-child {
+          span:first-child {
+            color: #f56c6c;
+            cursor: pointer;
+          }
+        }
+      }
+
+      .seat-select-color-item {
+        display: flex;
+        align-items: center;
+        margin-bottom: 5px;
+
+        >span:first-child {
+          width: 20px;
+          height: 20px;
+          flex-shrink: 0;
+        }
+
+        >span:last-child {
+          font-size: 16px;
+          font-weight: 600;
+          margin-left: 10px;
+        }
+      }
+    }
+    .subtitle {
+      margin: 5px 0;
+      text-align: center;
+      font-size: 16px;
+      font-weight: normal;
+
+    }
+    .main-box {
+      width: 100%;
+      p {
+        margin: 0 0 10px ;
+        font-size: 15px;
+        font-weight: 500;
+      }
+      .row-warp {
+        margin-bottom: 10px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        .dateBar {
+          width: 150px;
+        }
+        .textBar {
+          flex: 1;
+        }
+  
+      }
+    }
+  }
+}
+
+.seat-list-box::before {
+  content: "舞台";
+  position: absolute;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 300px;
+  height: 30px;
+  background-color: rgb(204, 204, 204, 0.5);
+  font-size: 18px;
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 0 0 20px 20px;
+  z-index: 99;
+}
+
+.dialog {
+  padding: 30px 10px 10px;
+  width: 100%;
+  height: calc(100% - 240px);
+  box-sizing: border-box;
+  overflow: auto;
+  border-radius: 10px;
+  border: 1px solid #323333;
+  position: relative;
+
+  .dialog-box {
+    position: relative;
+  }
+
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+
+  .title-class {
+    font-size: 16px;
+    font-weight: bold;
+    color: black;
+    margin-bottom: 20px;
+    margin-top: 20px;
+  }
+
+  .item-class {
+    margin-bottom: 20px;
+  }
+
+  .seat-box-class {
+    padding: 5px;
+    transform-origin: 50% 0;
+    transform: scale(var(--scaleNum));
+    box-sizing: border-box;
+
+    /**  是否属于windown座位  */
+    .seat_channel_type {
+      user-select: none;
+    }
+
+    .seat_channel_type:after {
+      content: "";
+      display: block;
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.3);
+      z-index: -1;
+      background-image: url('../../assets/jinxuan_1.png');
+      background-size: 50% 50%;
+      background-position: 50% 50%;
+      background-repeat: no-repeat;
+      z-index: 99;
+    }
+
+    .disabled-class {
+      background-color: #ffffff;
+      border: none !important;
+      user-select: none;
+      // pointer-events: none;
+      cursor: not-allowed !important;
+
+      .text-class {
+        color: #fff !important;
+      }
+    }
+
+    .select-class {
+      //background-color: #e85353 !important;
+      border: 5px solid #1890ff !important;
+      // color: #eceaea !important;
+      position: relative;
+    }
+
+    /** 手动锁定  */
+    .occupy-status:after {
+      content: "";
+      display: block;
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.3);
+      z-index: -1;
+      background-image: url('../../assets/jinzhi_1.png');
+      background-size: 50% 50%;
+      background-position: 50% 50%;
+      background-repeat: no-repeat;
+      z-index: 99;
+    }
+
+    .occupy-status {
+      //pointer-events: none;
+    }
+
+    /**  锁定被选择  */
+    .occupy-status-select {
+      border: 5px solid #ff182f !important;
+    }
+
+    /** 订单待支付锁定 */
+    .order-occupy-status {}
+
+    .order-occupy-status:after {
+      content: "";
+      display: block;
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.3);
+      z-index: -1;
+      background-image: url('../../assets/jinzhi.png');
+      background-size: 50% 50%;
+      background-position: 50% 50%;
+      background-repeat: no-repeat;
+      z-index: 99;
+    }
+
+    .occupy-status-no {
+      background-color: #f56c6c !important;
+      user-select: none;
+      // pointer-events: none;
+      cursor: not-allowed !important;
+      position: relative;
+    }
+
+    /* .occupy-status-no:after{
+            content:"";
+            display:block;
+            position:absolute;
+            top:0;
+            left:0;
+            width:100%;
+            height:100%;
+            background-color:rgba(0,0,0,0.3);
+            z-index:-1;
+            background-image: url('../../assets/jinzhi_1.png');
+            background-size: 50% 50%;
+            background-position: 50% 50%;
+            background-repeat: no-repeat;
+            z-index: 99;
+        } */
+    .seat-item-class-box {
+      width: 100%;
+      display: flex;
+      flex-wrap: nowrap;
+      justify-content: center;
+      margin: auto 0;
+      text-align: center;
+    }
+
+    .seat-item-class {
+      flex-shrink: 0;
+      display: block;
+      float: left;
+      width: 60px;
+      height: 60px;
+      margin: 5px;
+      border: 1px solid #4c4d4d;
+      border-radius: 3px;
+      cursor: pointer;
+      position: relative;
+      user-select: none;
+      // transform-origin: 50% 50%;
+      // transform: scale(var(--scaleNum));
+      z-index: 999;
+
+      &:hover {
+        opacity: 0.6;
+      }
+
+      .text-class {
+        font-size: 12px;
+        padding: 5px;
+        line-height: 16px;
+        margin: 0;
+        color: #000;
+      }
+    }
+  }
+
+  .seat-box-class-row {
+    display: flex !important;
+    align-items: center;
+    user-select: none;
+    cursor: not-allowed !important;
+    border: none !important;
+    font-weight: 600;
+    font-size: 24px;
+  }
+
+  .seat-item-class-column {
+    display: flex !important;
+    align-items: center;
+    justify-content: center;
+    user-select: none;
+    cursor: not-allowed !important;
+    border: none !important;
+    font-weight: 600;
+    font-size: 24px;
+  }
+}
+
+.dialog::-webkit-scrollbar {
+  width: 10x !important;
+  height: 10px !important;
+}
+
+.dialog::-webkit-scrollbar {
+  width: 10px;
+  height: 10px;
+  opacity: 0.5;
+}
+
+.dialog::-webkit-scrollbar-thumb {
+  border-radius: 15px;
+  //background-color: #0257aa;
+}
+
+#moveSelected {
+  position: absolute;
+  background-color: blue;
+  opacity: 0.3;
+  border: 1px dashed #d9d9d9;
+  top: 0;
+  left: 0;
+}
+</style>

+ 63 - 21
src/views/windowTicketSales/ticketingCollection.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="app-container app-container-me" :style="{'--q-height':qHeight}">
       <div class="app-container-query" ref="queryFormBox">
-        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
-          <el-form-item label="订单号" label-width="80px">
+        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="110px">
+          <el-form-item label="订单号">
             <el-input
               v-model="queryParams.orderId"
               placeholder="请输入订单号"
@@ -11,7 +11,7 @@
               @keyup.enter.native="handleQuery"
             />
           </el-form-item>
-          <el-form-item label="取票码" label-width="80px">
+          <el-form-item label="取票码">
             <el-input
               v-model="queryParams.qrcodeNo"
               placeholder="请输入取票码"
@@ -20,7 +20,7 @@
               @keyup.enter.native="handleQuery"
             />
           </el-form-item>
-          <el-form-item label="购票人手机号:" label-width="110px" prop="saleMobile">
+          <el-form-item label="购票人手机号:" prop="saleMobile">
             <el-input
               v-model="queryParams.saleMobile"
               placeholder="请输入购票人手机号"
@@ -29,7 +29,7 @@
               @keyup.enter.native="handleQuery"
             />
           </el-form-item>
-          <el-form-item label="身份证号:" label-width="120px" prop="idcard">
+          <el-form-item label="身份证号:" prop="idcard">
             <el-input
               v-model="queryParams.idcard"
               placeholder="请输入身份证号"
@@ -40,7 +40,7 @@
               <el-button slot="append" :loading="idcardLoading" size="mini" type="primary" @click="readCert">{{ idcardLoading ? '识别中':'识别' }}</el-button>
             </el-input>
           </el-form-item>
-          <el-form-item label="座位号" label-width="80px">
+          <el-form-item label="座位号">
             <el-input
               v-model="queryParams.seatName"
               placeholder="请输入座位号"
@@ -124,7 +124,7 @@
                 <el-button
                   size="mini"
                   type="text"
-                  @click="handleOpen([scope.row])"
+                  @click="handleOpenPrint([scope.row])"
                   v-hasPermi="['windowTicketSales:ticketingCollection:print']"
                 >打印门票</el-button>
               </template>
@@ -152,7 +152,15 @@
         title="批量打印顺序"
         :visible.sync="multipleSelectionVisible"
         width="90%"
-        :before-close="()=>{ multipleSelectionVisible = false}">
+        :before-close="()=>{ multipleSelectionVisible = false}"
+      >
+        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="80px" class="demo-ruleForm">
+          <el-form-item label="打印机" prop="region">
+            <el-select v-model="ruleForm.region" placeholder="选择打印机">
+              <el-option v-for="(item,index) in printList" :label="item.deviceName" :key="item.id" :value="item.id" ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
         <el-table 
           ref="tabless" 
           v-loading="loading" 
@@ -210,7 +218,7 @@
   
   <script>
   
-  import { pageList,printApi } from '@/api/windowTicketSales/ticketingCollection'
+  import { pageListApi,printApi } from '@/api/windowTicketSales/ticketingCollection'
   import { pageList as getPrintListApi } from "@/api/device/pda";
   const https = require('https');
   const axios = require('axios');
@@ -264,13 +272,13 @@
       };
     },
     created() {
-      console.log("params====",this.$route)
+      // console.log("params====",this.$route)
       if(this.$route.query&&this.$route.query.orderId) {
         this.$set(this.queryParams,'orderId',this.$route.query.orderId)
         this.getList()
       }
       //this.getList();
-      //this.getPrintListApi()
+      this.getPrintListApi()
     },
     mounted() {
       this.resizeObserver = new ResizeObserver(entries => {
@@ -291,7 +299,7 @@
       /** 查询列表 */
       getList() {
         this.loading = true;
-        pageList(this.queryParams)
+        pageListApi(this.queryParams)
         .then(response => {
             let list = response.data.rows;
             // list.forEach((item,index)=>{
@@ -302,7 +310,12 @@
             this.dataList = list
             this.total = response.data.total;
             this.loading = false;
-            console.log("this.multipleSelection=====",this.multipleSelection)
+            // 数据更新后执行全选
+            this.$nextTick(() => {
+              this.$refs.tables.toggleAllSelection();
+              console.log("this.multipleSelection=====",this.multipleSelection)
+            });
+            
           }
         ).catch(()=>{
           this.dataList = []
@@ -362,16 +375,17 @@
           this.$refs[formName].resetFields();
         },
         handleSelectionChange(val,row) {
-          console.log("val====",val,row)
+          // console.log("val====",val,row)
           this.multipleSelection = val;
         },
 
         openMultipleSelectionVisible(){
-          console.log("sdfasgadfgadfgadfgadfg")
+          // console.log("sdfasgadfgadfgadfgadfg")
           this.multipleSelectionTabel = JSON.parse(JSON.stringify(this.multipleSelection))
           this.multipleSelectionVisible = true
         },
-        handleOpen(list=[]){
+        // 单个打印 行操作
+        handleOpenPrint(list=[]) {
           if(!list||list.length==0) return
           let idList = []
           list.forEach((item,index)=>{
@@ -388,6 +402,30 @@
           })
           this.dialogVisible = true
         },
+        // 批量打印
+        handleOpen(list=[]) {
+          // console.log(list,'list');
+          if(!list||list.length==0) return
+          if(!this.ruleForm.region) {
+            this.$message.warning('请选择打印机!')
+            return
+          }
+          let idList = []
+          list.forEach((item,index)=>{
+            idList.push({
+              viewerId: item.id,
+              index: index
+            })
+          }) 
+          this.viewerList = idList;
+          this.print(this.viewerList);
+          // this.getPrintListApi()
+          // this.$set(this.ruleForm, 'region', '');
+          // this.$nextTick(()=>{
+          //   this.$refs.ruleForm.clearValidate('region')
+          // })
+          // this.dialogVisible = true
+        },
         handleClose(){
           
           this.dialogVisible = false
@@ -398,6 +436,10 @@
           pageSize: 999,})
           .then(response => {
               this.printList = response.data.rows;
+              this.$set(this.ruleForm, 'region', '');
+              // this.$nextTick(()=>{
+              //   this.$refs.ruleForm.clearValidate('region')
+              // })
           }).catch((error)=>{
             console.log("error===",error)
           }
@@ -426,7 +468,7 @@
                   throw new Error(res)
                 }
               } catch (error) {
-                this.dialogVisible = false
+                // this.dialogVisible = false
                 this.dialogVisibleLoading = false
                 console.error("error=====",error)
               }
@@ -476,10 +518,10 @@
           ignoreSSL.post(url, 
             { ...data }
             ).then(()=>{
-            this.dialogVisible = false
+            // this.dialogVisible = false
             this.dialogVisibleLoading = false
           }).catch(()=>{
-            this.dialogVisible = false
+            // this.dialogVisible = false
             this.dialogVisibleLoading = false
           })
           // 在 axios 请求时,选择性忽略 SSL
@@ -531,10 +573,10 @@
           
           this.idcardLoading = false
           //return result;
-            console.log(result,obj)
+            // console.log(result,obj)
         },
         sortChangeFun (row) {
-          console.log("row=====",row)
+          // console.log("row=====",row)
           if(this.dataList.length == 0) return
           let list = JSON.parse(JSON.stringify(this.dataList))
           if(row.order == 'descending') {