MONSTER-ygh před 1 rokem
rodič
revize
de56510d6b

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

@@ -0,0 +1,108 @@
+import request from '@/utils/request'
+
+// 座位列表
+export const querySeatList = (query) => {
+  return request({
+    url: '/merchant/merchantAuditoriumSeat/querySeatList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 根据厅ID和日期查询场次
+export const merchantPerformTimeList = (query) => {
+    return request({
+      url: '/merchant/merchantPerformTime/list',
+      method: 'get',
+      params: query
+    })
+  }
+
+  // 订单提交
+export const orderInfoSubmit = (query) => {
+    return request({
+      url: '/order/orderInfo/submit',
+      method: 'post',
+      data: query
+    })
+  }
+
+
+  // 订单支付码支付
+export const gotoMicroPay = (query) => {
+    return request({
+      url: '/order/orderInfo/gotoMicroPay',
+      method: 'post',
+      data: query
+    })
+  }
+
+  // 订单现金支付
+  export const gotoCashPay = (query) => {
+    return request({
+      url: '/order/orderInfo/gotoCashPay',
+      method: 'post',
+      data: query
+    })
+  }
+  // 支付查询
+
+  export const payQuery = (query) => {
+    return request({
+      url: '/order/orderInfo/payQuery',
+      method: 'post',
+      data: query
+    })
+  }
+
+//  获取 演出厅
+
+export const merchantTheatreAuditoriumList = (query) => {
+  return request({
+    url: '/merchant/merchantTheatreAuditorium/list',
+    method: 'get',
+    params: query
+  })
+}
+
+//  座位锁定/解锁
+
+export const lockOrUnLock = (query) => {
+  return request({
+    url: '/merchant/merchantSeatOccupy/lockOrUnLock',
+    method: 'post',
+    data: query
+  })
+}
+
+//  价格查询
+
+export const selectRegion = (query) => {
+  return request({
+    url: '/merchant/merchantTheatreAuditorium/selectRegion',
+    method: 'post',
+    data: query
+  })
+}
+
+
+// 票务查询
+
+export const goodsPageList = (query) => {
+  return request({
+    url: '/goods/goods/pageList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 取消订单
+
+
+export const orderInfoCancel = (query) => {
+  return request({
+    url: '/order/orderInfo/cancel',
+    method: 'post',
+    data: query
+  })
+}

binární
src/assets/jinzhi.png


+ 12 - 4
src/views/venue/performanceHallMr/dialog/seatTemplateEdit.vue

@@ -39,7 +39,7 @@
       <el-button @click="cancel">取消</el-button>
       <el-button
         type="primary"
-        @click="submitForm"
+        @click="submitFormCopy"
         v-loading.fullscreen.lock="loading"
         element-loading-text="提交中..."
         element-loading-spinner="el-icon-loading"
@@ -173,12 +173,18 @@ export default {
           }
         );
     },
+    saveSeat(list,style){
+      this.submitForm(list,style)
+    },
+    submitFormCopy(){
+      this.$refs.seatManagementTable.saveSeat()
+    },
     /**
      * 保存
      * @date 2023-11-22
      * @returns {any}
      */
-    submitForm() {
+    submitForm(list,style) {
       let that = this;
       this.$refs["form"].validate(async (valid) => {
         if (valid) {
@@ -192,7 +198,8 @@ export default {
             const { code } = await saveAndEdit({ 
               id: this.auditoriumId, 
               rows: this.seatMap.row, 
-              cols: this.seatMap.col 
+              cols: this.seatMap.col,
+              style: style
             });
             if (code === 200) {
               let postList = []
@@ -200,7 +207,8 @@ export default {
                 postList.push(this.colSeatMap[codeKey])
               }
               /**  保存座位  */
-              const { code } = await seatSaveAndEdit(postList);
+              //const { code } = await seatSaveAndEdit(postList);
+              const { code } = await seatSaveAndEdit(list);
               if (code === 200) {
                 that.$message.success("操作成功!");
                 that.$emit("getList");

+ 2 - 2
src/views/venue/performanceHallMr/index.vue

@@ -131,8 +131,8 @@
 
 import { merchantPageList, deleteById } from '@/api/performanceHallMr/performanceHallMr'
 import addAndEdit from "./dialog/addAndEdit.vue";
-import seatTemplateEdit from "./dialog/seatTemplateEdit";
-// import seatTemplateEdit from "./dialog/seatTemplateEditOld";
+//import seatTemplateEdit from "./dialog/seatTemplateEdit";
+import seatTemplateEdit from "./dialog/seatTemplateEditOld";
 import programmeAddAndEdit from "./dialog/programmeAddAndEdit";
 
 export default {

+ 1343 - 0
src/views/venue/performanceHallMr/model/seatManagementTable copy.vue

@@ -0,0 +1,1343 @@
+<template>
+    <div class="sm">
+        <div style="width: 1300px;">
+            <div style="display: flex;align-items: center;">
+                <span style="margin-right: 5px;font-size: 14px;">放大/缩小:</span> 
+                <div style="width: 100px;">
+                    <el-slider input-size="mini" v-model="whNum" :min="16" :max="60"></el-slider>
+                </div>
+            </div>
+            <div>
+
+            </div>
+        </div>
+        <div class="sm-box">
+            <div class="sm-scroll-box">
+                <el-table
+                    v-dragSelect="{
+                        selectClass: ['.row-item'],
+                        change: dragSelectChange,
+                        lostItem: dragLostItemChange,
+                        reSelect: reSelect
+                    }"
+                    :data="tableData"
+                    width="100%"
+                    height="100%"
+                    ref="table" 
+                    row-key="id"
+                    class="exchange_table"
+                    :style="{
+                        '--row-w': whNum+'px',
+                        '--row-h': whNum+'px',
+                    }"
+                    :data-source="ranking_goods"
+                    :cell-class-name="tableCellClassName"
+                    @cell-dblclick="cellDblclick"
+                    
+                    >
+                        <el-table-column 
+                        type="index"
+                        fixed=left
+                        label="#"
+                        align="center"
+                        v-if="tableHeader.length!=0"
+                        :width="50">
+                            <template slot-scope="scope">
+                                <span>{{ scope.$index + 1 }}#</span>
+                            </template>
+                        </el-table-column>
+                        <el-table-column
+                        v-for="(item,index) in tableHeader"
+                        :prop="item.key"
+                        :label="item.title"
+                        :width="((whNum+7.5)*item.length)+'px'"
+                        align="center"
+                        >
+                        <template slot-scope="scope">
+                            <div class="row-item-box" :style='{display: "flex",flexWrap: "nowrap",justifyContent: item.align}'>
+                                <div 
+                                class="row-item"
+                                v-for="(item1,index1) in scope.row[item.key]" 
+                                :key="item1.style.id"
+                                dragSelectType="div"
+                                :dragSelectId="item1.style.id"
+                                :style="{backgroundColor: item1.delFlag !=0?'#ccc':item1.color}"
+                                >
+                                    <i style="line-height: 15px;">{{ item1.columnNo }}</i>
+                                    <i style="line-height: 15px;">{{ item1.name }}</i>
+                                    <i style="line-height: 15px;">vip</i>
+                                </div>
+                            </div>
+                        </template>
+                        </el-table-column>
+                </el-table>
+            </div>
+            <!--  编辑页  -->
+            <div class="table-tool">
+                <div class="table-tool-tab">
+                    <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-tab-pane label="批量处理" name="batch"></el-tab-pane>
+                    </el-tabs>
+                </div>
+                <!--  创建区域  -->
+                <div 
+                v-if="activeName == 'first'"
+                class="qu-first-box">
+                    <div class="qu-first-form">
+                        <el-form :model="ruleForm" size="mini" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
+                            <el-form-item label="座位总排数">
+                                <el-input v-model="rowAll">
+                                    <el-button slot="append" @click="createTableList">创建排数</el-button>
+                                </el-input>
+                            </el-form-item>
+                            <el-form-item label="区域名称" prop="name">
+                                <el-input v-model="ruleForm.name"></el-input>
+                            </el-form-item>
+                            <el-form-item label="座位排列" prop="region">
+                                <el-select v-model="ruleForm.region" placeholder="请选择座位排练">
+                                    <el-option label="靠左" value="flex-start"></el-option>
+                                    <el-option label="居中" value="center"></el-option>
+                                    <el-option label="靠右" value="flex-end"></el-option>
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item>
+                                <el-button size="mini" type="primary" @click="submitForm('ruleForm')">创建区域</el-button>
+                                <el-button size="mini" @click="resetForm('ruleForm')">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                    <div class="qu-first-info">
+                        <div class="qu-first-info-title">
+                            <span>已创建的区域</span>
+                            <span>(注:从左至右排序如下)</span>
+                        </div> 
+                        <div class="qu-first-info-list">
+                            <transition-group>
+                                <div 
+                                class="qu-first-info-item"
+                                v-for="(item,index) in tableHeader"
+                                :key="index"
+                                v-dragging="{item: item, list:tableHeader}"
+                                >
+                                    <span>{{ item.title }}</span>
+                                    <div>
+                                        <span @click="editTableHeader(item,index)">编辑</span>
+                                        <span @click="delTableHeader(item,index)">删除</span>
+                                    </div>
+                                </div>
+                            </transition-group>
+                            
+                        </div>
+                    </div>
+                </div>
+                <!--  座位管理 -->
+                <div v-if="activeName == 'second'" class="qu-second-box">
+                    <div class="qu-second-select">
+                        <span>当前选择的是:</span> 
+                        <span v-if="currentRow">{{ currentRow }}排</span>
+                        <span v-if="currentRow">--</span>  
+                        <span v-if="currentLabel">{{ currentLabel }}区</span>  
+                    </div>
+                    <div class="qu-second-form">
+                        <el-form :model="ruleForm1" size="mini" :rules="rules1" ref="ruleForm1" label-width="80px" class="demo-ruleForm">
+                            <el-form-item label="创建方式" prop="resource">
+                                <el-radio-group v-model="ruleForm1.resource">
+                                    <el-radio :label="1">单个</el-radio>
+                                    <el-radio :label="2">批量</el-radio>
+                                </el-radio-group>
+                            </el-form-item>
+                            <el-form-item label="座位类型" prop="seatTypeId">
+                                <el-select 
+                                v-model="ruleForm1.seatTypeId"
+                                placeholder="请选择座位排练">
+                                    <el-option 
+                                    v-for="(item,index) in seatTypeList"
+                                    :key="item.id"
+                                    :label="item.name" 
+                                    :value="item.id"></el-option>
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item label="座位名称" prop="name">
+                                <el-input v-model="ruleForm1.name"></el-input>
+                            </el-form-item>
+                            <el-form-item style="margin-bottom: 0px"  v-if="ruleForm1.resource == 2 " label="座位区间" prop="name">
+                                <div style="display: flex;">
+                                    <el-form-item label="" label-width="0" prop="name">
+                                        <el-input v-model="ruleForm1.colMin" placeholder="最小座位号"></el-input>
+                                    </el-form-item>
+                                    <span style="white-space: nowrap;">--</span>
+                                    <el-form-item label="" prop="name">
+                                        <el-input v-model="ruleForm1.colMax"  placeholder="最大座位号"></el-input>
+                                    </el-form-item>
+                                </div>
+                            </el-form-item>
+                            
+                            <el-form-item>
+                                <el-button size="mini" type="primary" @click="addSeat('ruleForm1')">创建座位</el-button>
+                                <el-button size="mini" @click="resetForm1('ruleForm1')">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </div>  
+                    <div class="qu-second-info">
+                        <div class="qu-second-info-title">
+                            <span>该区已创建的座位</span>
+                            <span>(注:从左至右排序如下)</span>
+                        </div> 
+                        <div class="qu-second-info-tool">
+                            <span>快速排序:</span>
+                            <i @click="seatSortingFun('rise')">升序</i>
+                            <i @click="seatSortingFun('fall')">降序</i>
+                            <i @click="seatSortingFun('symmetry')">奇偶对称</i>
+                            <i @click="seatSortingFun('reversal')">反转</i>
+                        </div> 
+                        <div class="qu-second-info-list">
+                            <div 
+                            class="qu-second-info-item"
+                            v-for="(item,index) in currentTabelList">
+                                <span>{{ item.name }}</span>
+                            </div>
+                        </div>
+                    </div>                 
+                </div>
+
+                <!-- 批量操作  -->
+                <div v-if="activeName == 'batch'" class="qu-batch-box">
+                    <div class="qu-batch-form">
+                        <el-form :model="queryParams" ref="queryForm" size="mini" label-width="50px">
+                            <el-form-item label="排号" prop="menuName" >
+                                <el-input
+                                v-model="queryParams.menuName"
+                                placeholder="排号"
+                                clearable
+                                @keyup.enter.native="handleQuery"
+                                />
+                            </el-form-item>
+                            <el-form-item label="区域" prop="status">
+                                <div style="display: flex;">
+                                    <el-select v-model="queryParams.status" placeholder="区域" clearable>
+                                    <el-option
+                                        v-for="item in tableHeader"
+                                        :key="item.key"
+                                        :label="item.title"
+                                        :value="item.key"
+                                    />
+                                    <el-option
+                                        label="未绑定"
+                                        :value="-1"
+                                    />
+                                    </el-select>
+                                    <el-button style="margin-left: 5px;" type="primary" size="mini" @click="handleQuery">搜索</el-button>
+                                    <el-button size="mini" @click="resetQuery">重置</el-button>
+                                </div>
+                                
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                    <div class="qu-batch-tool">
+                        <el-button type="primary" size="mini" @click="openFormDialogVisible">修改区域</el-button>
+                        <el-button type="danger" size="mini" @click="batchDisable">批量禁用</el-button>
+                        
+                    </div>
+                    <div class="qu-batch-table">
+                        <el-table
+                            size="mini"
+                            :data="batchTableList"
+                            @selection-change="handleSelectionChange"
+                            style="width: 100%"
+                            height="100%"
+                            >
+                            <el-table-column
+                            type="selection"
+                            align="center"
+                            width="40">
+                            </el-table-column>
+                            <el-table-column
+                            prop="name"
+                            align="center"
+                            label="名称">
+                            </el-table-column>
+                            <el-table-column
+                            align="center"
+                            label="区域">
+                                <template slot-scope="scope">
+                                    <span>{{ scope.row.style && scope.row.style.keyLabel }}</span>
+                                </template>
+                            </el-table-column>
+                        </el-table>
+                    </div>
+                </div>
+
+            </div>
+        </div>
+
+        <!--  编辑区域   -->
+        <el-dialog
+            :title="formDialogVisibleTitle"
+            :visible.sync="formDialogVisible"
+            width="30%"
+            append-to-body
+            >
+            <el-form 
+            :model="formAll" 
+            :rules="formRules" 
+            ref="formAll" 
+            label-width="100px" >
+                <div v-if="formAllType=='region'">
+                    <el-form-item label="区域名称" prop="title">
+                        <el-input v-model="formAll.title"></el-input>
+                    </el-form-item>
+                    <el-form-item label="座位排练" prop="align">
+                        <el-select v-model="formAll.align" placeholder="请选择座位排练">
+                            <el-option label="靠左" value="flex-start"></el-option>
+                            <el-option label="居中" value="center"></el-option>
+                            <el-option label="靠右" value="flex-end"></el-option>
+                        </el-select>
+                    </el-form-item>
+                </div>
+                <div v-if="formAllType=='bindingregion'">
+                    <el-form-item label="区域" prop="status">
+                        <div style="display: flex;">
+                            <el-select v-model="queryParams.status" placeholder="区域" clearable>
+                                <el-option
+                                    v-for="item in tableHeader"
+                                    :key="item.key"
+                                    :label="item.title"
+                                    :value="item.key"
+                                />
+                            </el-select>
+                            <el-button style="margin-left: 5px;" type="primary" size="mini" @click="handleQuery">搜索</el-button>
+                            <el-button size="mini" @click="resetQuery">重置</el-button>
+                        </div>
+                    </el-form-item>
+                </div>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="formDialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="chekeFormAll('formAll')">确 定</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+ 
+<script>
+import Sortable from "sortablejs";
+import dragSelect from 'ty-drag-select';
+export default {
+    name: 'sysIndex',
+    components: {},
+    data() {
+        return {
+            // 页面渲染的数据
+            seatList: [],
+            seatTypeList: [
+                {
+                    "id": "899466154989936640",
+                    "createBy": "admin",
+                    "createTime": "2023-12-26 11:24:13",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-26 11:24:13",
+                    "delFlag": 0,
+                    "name": "贵宾席-OTA测试",
+                    "color": "#EB3286"
+                },
+                {
+                    "id": "899466065307328512",
+                    "createBy": "admin",
+                    "createTime": "2023-12-26 11:23:51",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-26 11:23:51",
+                    "delFlag": 0,
+                    "name": "普通席-OTA测试",
+                    "color": "#AE3BE7"
+                },
+                {
+                    "id": "898175951457316864",
+                    "createBy": "admin",
+                    "createTime": "2023-12-22 21:57:24",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-22 21:57:24",
+                    "delFlag": 0,
+                    "name": "VIP票",
+                    "color": "#FF0000"
+                },
+                {
+                    "id": "898175913469505536",
+                    "createBy": "admin",
+                    "createTime": "2023-12-22 21:57:15",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-22 21:57:15",
+                    "delFlag": 0,
+                    "name": "贵宾票",
+                    "color": "#FFD000"
+                },
+                {
+                    "id": "898175825946963968",
+                    "createBy": "admin",
+                    "createTime": "2023-12-22 21:56:54",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-22 21:56:54",
+                    "delFlag": 0,
+                    "name": "普通票",
+                    "color": "#0BB8B8"
+                },
+                {
+                    "id": "898175718375649280",
+                    "createBy": "admin",
+                    "createTime": "2023-12-22 21:56:29",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-26 11:23:02",
+                    "delFlag": 0,
+                    "name": "普通座位-测试",
+                    "color": "#DE5421"
+                },
+                {
+                    "id": "898175647802290176",
+                    "createBy": "admin",
+                    "createTime": "2023-12-22 21:56:12",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-22 21:56:35",
+                    "delFlag": 0,
+                    "name": "贵宾座位-测试",
+                    "color": "#2FBB60"
+                },
+                {
+                    "id": "898175609768341504",
+                    "createBy": "admin",
+                    "createTime": "2023-12-22 21:56:03",
+                    "updateBy": "admin",
+                    "updateTime": "2023-12-24 20:17:00",
+                    "delFlag": 0,
+                    "name": "VIP座位-测试",
+                    "color": "#002FFF"
+                }
+            ],
+            tableHeader: [
+                // { title: '左1',key: 'zuo',align: 'flex-end' },
+                // { title: '过道2',key: 'zuo11',align: 'center' },
+                // { title: '中3',key: 'zhong',align: 'center' },
+                // { title: '过道4',key: 'zuo22',align: 'center' },
+                // { title: '右5',key: 'you',align: 'flex-start' },
+                // { title: '右6',key: 'you',align: 'flex-start' },
+                // { title: '右7',key: 'you',align: 'flex-start' },
+
+                // { title: '右8',key: 'you',align: 'flex-start' },
+                // { title: '右9',key: 'you',align: 'flex-start' },
+            ],
+            tableData: [
+                // {
+                //     id: this.currentRow+"_"+this.currentProperty+"_"+i,
+                //     name: this.ruleForm1.name.replace('${row}',this.currentRow).replace('${col}',i),
+                //     status: this.ruleForm1.seatTypeId,
+                //     rowNo: this.currentRow,
+                //     colNo: i,
+                //     sort: i,
+                //     style: {key: this.currentProperty}
+                // }
+            ], // 全部的座位 表格形式
+            tableDataAll: [
+                // {
+                //     "id": "899524164202352651",
+                //     "delFlag": 0,
+                //     "auditoriumId": "899466305364123648",
+                //     "name": "",
+                //     "rowNo": 2,
+                //     "columnNo": 9,
+                //     "seatTypeId": "899466154989936640",
+                //     "seatLabel": "贵宾席-OTA测试",
+                //     "priority": 1,
+                //     "status": 1,
+                //     "sortId": 11,
+                //     "color": "#EB3286"
+                // }
+            ], // 全部的座位
+            widthAll: '100%',
+            heightAll: '100%',
+            width: 26,
+            height: 26,
+            spacing: 10,
+            whNum: 26,
+
+
+            sortable: null,
+            ranking_goods: [],
+
+            
+            // tool
+            rowAll: null,
+            activeName: 'second',
+            
+            // 创建区域
+            ruleForm: {},
+            rules: {
+                name: [
+                    { required: true, message: '请输入活动名称', trigger: ['blur','change'] }
+                ],
+                region: [
+                    { required: true, message: '请选择活动区域', trigger: ['blur','change'] }
+                ],
+            },
+
+            /**   创建座位  开始 */
+            // 创建座位
+            ruleForm1: {
+                name: '${row}排${col}座'
+            },
+            rules1: {
+                resource: [
+                    { required: true, message: '请选择创建方式', trigger: ['blur','change'] }
+                ],
+                name: [
+                    { required: true, message: '请选择座位名称', trigger: ['blur','change'] }
+                ],
+                seatTypeId: [
+                    { required: true, message: '请输入座位类型', trigger: ['blur','change'] }
+                ],
+            },
+            currentRow: null, // 当前选择的单元格行
+            currentRegion: null, // 当前选择的单元格列
+            currentLabel: null, // 当前选择的单元格列 名称
+            currentProperty: null, // 当前选择的key
+            currentTabelList: [], // 当前单元格的座位列表
+            /**   创建座位  结束 */
+
+            /** 批量操作   */
+            batchTableList: [],
+            multipleSelection: [],  //  批量操作选中的
+            queryParams: {},
+
+            /** 编辑区域 开始  */
+            formDialogVisibleTitle: '',
+            formDialogVisible: false, // 弹窗
+            formAll: {},
+            formRules: {},
+            formAllType: '', // region 区域
+            /** 编辑区域 结束  */
+        };
+    },
+    mounted() {
+        //this.initData()
+        // this.initDataCopy()
+        // setTimeout(() => {
+        //   let tbody = document.getElementsByClassName('exchange_table')[0].getElementsByTagName('tbody');
+        //   tbody[0] && (tbody[0].className += ' box-table');
+        //   this.initSortTable();
+        // }, 1000)
+        // 拖拽事件
+        this.columnDrop() 
+
+        this.$dragging.$on("dragged", (result) => {
+            // 将排序后的结果重新赋值
+            this.tableHeader = [].concat(JSON.parse(JSON.stringify(result.value.list)))
+        });
+
+    },
+    methods: {
+        //初始化排序
+        initSortTable() {
+            let that = this;
+            this.sortable = new Sortable(document.getElementsByClassName('box-table')[0], {
+            animation: 150,
+            handle: '.drag-btn',
+            onEnd: (e) => {
+                // 获取排序之后的data数据
+                that.ranking_goods.splice(e.newIndex, 0, that.ranking_goods.splice(e.oldIndex, 1)[0]);
+                var newArray = that.ranking_goods.slice(0);
+                that.ranking_goods = []
+                that.$nextTick(function () {
+                that.ranking_goods = newArray
+                })
+            }
+            })
+
+        },
+
+        /**  初始化数据  */
+        initData(){
+            
+        },
+        /** tab 切换 右侧工具 */
+        handleClickTab(item){
+            console.log("item====",item,this.activeName)
+            if(this.activeName == 'batch') { // 批量操作
+                this.batchTableList = this.tableDataAll
+            }
+        },
+        /**  创建区域  开始 */
+        submitForm(formName) {
+            this.$refs[formName].validate((valid) => {
+            if (valid) {
+                let key = 'zuo_'+this.tableHeader.length
+                this.tableHeader.push({
+                    title: this.ruleForm.name,
+                    key,
+                    align: this.ruleForm.region,
+                    length: 0,
+                    width:0,
+                })
+                this.resetForm('ruleForm')
+                if(this.rowAll) {
+                    this.createTableList()
+                }
+            } else {
+                console.log('error submit!!');
+                return false;
+            }
+            });
+        },
+        resetForm(formName) {
+            this.$refs[formName].resetFields();
+        },
+        // 删除区域
+        delTableHeader(params,index){
+            let flog = false
+            this.tableDataAll.forEach((item,index)=>{
+                if(item.style && item.style.key == params.key) {
+                    flog = true
+                }
+            })
+            if(flog){
+                this.$message.error('区域存在座位,请将座位移到别的区域再删除!');
+            }else{
+                this.$confirm(`确定删除${params.title}区域`, '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    callback: action => {
+                        this.tableHeader.splice(index,1)
+                    }
+                });
+            }
+        },
+        // 编辑区域
+        editTableHeader(item,index){
+            this.formAllType = 'region'
+            this.formDialogVisibleTitle = "编辑区域"
+            this.formDialogVisible = true
+            this.$set(this,'formAll',JSON.parse(JSON.stringify({
+                index: index,
+                ...item
+            })))
+        },
+        // 验证表单
+        chekeFormAll(formName){
+            this.$refs[formName].validate((valid) => {
+                if (valid) {
+                    if(this.formAllType == 'region'){
+                        this.submitFormAll()
+                    }else if(this.formAllType == 'bindingregion'){
+                        this.batchBindingArea()
+                    }
+                } else {
+                    console.log('error submit!!');
+                    return false;
+                }
+            });
+        },
+        // 
+        submitFormAll(){
+            let index = this.formAll.index
+            this.$set(this.tableHeader[index],'title',this.formAll.title)
+            this.$set(this.tableHeader[index],'align',this.formAll.align)
+            // let list = []
+            // this.tableDataAll.forEach((item,index)=>{
+            //     if(item.style.key == this.formAll.key) {
+            //         list.push({
+            //             ...item,
+            //             style: {
+            //                 item.sty
+            //             }
+            //         })
+            //     }else {
+
+            //     }
+            // })
+            this.formDialogVisible = false
+        },
+        /**  创建区域  结束 */
+
+        /**
+        *  创建排数
+        */
+        createTableList(){
+            let list = JSON.parse(JSON.stringify(this.tableData))
+            for(let i = 0;i<this.rowAll;i++) {
+                if(this.tableHeader && this.tableHeader.length){
+                    let obj = {
+                        id: "row_"+i
+                    }
+                    this.tableHeader.forEach((item,index)=>{
+                        obj[item.key] = []
+                    })
+                    if(list[i] && JSON.stringify(list[i]) != '{}') {
+                        list[i] = Object.assign(obj,list[i])
+                    }else {
+                        list.push(obj)
+                    }
+                }else if(!list[i]){
+                    list.push({})
+                }
+            }
+            this.tableData = JSON.parse(JSON.stringify(list))
+            console.log("this.tableData===",this.tableData)
+        },
+        /**  创建区域  结束 */
+
+
+        /**  创建座位  开始  */
+        tableCellClassName({row, column, rowIndex, columnIndex}){
+            //注意这里是解构
+            //利用单元格的 className 的回调方法,给行列索引赋值
+            row.index=rowIndex;
+            column.index=columnIndex;
+        },
+        /**  点击某个单元格   */
+        cellDblclick(row, column, cell, event){
+            this.currentRow = row.index + 1
+            this.currentRegion = column.index
+            this.currentLabel = column.label
+            this.currentProperty = column.property
+            console.log('this.tableData===', this.tableData)
+            console.log("this.tableData111=====",this.currentRow,this.currentProperty,this.tableData[this.currentRow-1][this.currentProperty])
+
+            let list = this.tableData[this.currentRow-1][this.currentProperty]
+            this.currentTabelList = list && list.length>0 ? JSON.parse(JSON.stringify(list)) : []
+            console.log("row, column, cell, event===",row, column, cell, event)
+        },
+        /**  点击  创建座位   */
+        addSeat(formName) {
+            this.$refs[formName].validate((valid) => {
+            if (valid) {
+                if(!this.currentRow){
+                    this.$message({
+                        showClose: true,
+                        message: '请先选择某个区域,左键双击选择!!!',
+                        type: 'error'
+                    });
+                    return
+                }
+                let color = ''
+                let seatLabel = ''
+                this.seatTypeList.forEach((item,index)=>{
+                    if(this.ruleForm1.seatTypeId == item.id) {
+                        color = item.color
+                        seatLabel = item.seatLabel
+                    }
+                })
+                if(this.ruleForm1.resource == 2){ // 批量
+                    let list = []
+                    let min = Number(this.ruleForm1.colMin)
+                    let max = Number(this.ruleForm1.colMax)
+                    if(min>max){
+                        this.$message({
+                            showClose: true,
+                            message: '座位区间输入错误,应该前数小于后数!!!',
+                            type: 'error'
+                        });
+                        return
+                    }
+                    if(!this.checkRepeatSeat(min,max)){
+                        this.$message({
+                            showClose: true,
+                            message: '座位区间出现重复!!!',
+                            type: 'error'
+                        });
+                        return
+                    }
+                    for(let i = min;i<=max;i++) {
+                        list.push({
+                            id: this.currentRow+"_"+this.currentProperty+"_"+i,
+                            name: this.ruleForm1.name.replace('${row}',this.currentRow).replace('${col}',i),
+                            status: this.ruleForm1.seatTypeId,
+                            style: {
+                                key: this.currentProperty, // 所属区域的key
+                                keyLabel: this.currentLabel, // 所属区域的名称
+                                sort: 0,
+                                id: this.currentRow+"_"+this.currentProperty+"_"+i,
+                            },
+                            rowNo: this.currentRow,
+                            columnNo: i,
+                            seatTypeId: this.ruleForm1.seatTypeId,
+                            seatLabel: seatLabel,
+                            color: color,// 座位类型对应的颜色
+                            delFlag: 0,
+                        })
+                    }
+                    this.tableDataAll = this.tableDataAll.concat(JSON.parse(JSON.stringify(list)))
+                    this.$set(this.tableData[this.currentRow-1],this.currentProperty,this.tableData[this.currentRow-1][this.currentProperty].concat(list))
+                    this.currentTabelList = JSON.parse(JSON.stringify(this.tableData[this.currentRow-1][this.currentProperty]))
+                }else { // 单个
+                    console.log("this.tableData=====",this.tableData)
+                    console.log("this.tableData111=====",this.currentRow,this.currentProperty,this.tableData[this.currentRow-1][this.currentProperty])
+                    let index = this.tableData[this.currentRow-1][this.currentProperty].length
+                    let obj = {
+                        id: this.currentRow+"_"+this.currentProperty+"_"+(index+1),
+                        name: this.ruleForm1.name,
+                        status: this.ruleForm1.seatTypeId,
+                        rowNo: this.currentRow,
+                        sort: index+1,
+
+                        style: {
+                            key: this.currentProperty, // 所属区域的key
+                            keyLabel: this.currentLabel, // 所属区域的名称
+                            sort: 0,
+                            id: this.currentRow+"_"+this.currentProperty+"_"+(index+1),
+                        },
+                        rowNo: this.currentRow,
+                        columnNo: index+1,
+                        seatTypeId: this.ruleForm1.seatTypeId,
+                        seatLabel: seatLabel,
+                        color: color,// 座位类型对应的颜色
+                        delFlag: 0,
+                    }
+                    this.tableData[this.currentRow-1][this.currentProperty].push(obj)
+                    this.tableDataAll.push(JSON.parse(JSON.stringify(obj)))
+                    this.currentTabelList = JSON.parse(JSON.stringify(this.tableData[this.currentRow-1][this.currentProperty]))
+                }
+                this.countRegionW()
+                
+            } else {
+                console.log('error submit!!');
+                return false;
+            }
+            });
+        },
+        /**  检测座位 是否存在重复 */
+        checkRepeatSeat(min,max){
+            let list = this.tableData[this.currentRow-1][this.currentProperty]
+            if(!list||list.length<=0){ return true }
+            let flog = true
+            list.forEach((item)=>{
+                if(item.columnNo<=max&&item.columnNo>=min) {
+                    flog = false
+                }
+            })
+            return flog
+        },
+        /**  清除创建座位的表单 */
+        resetForm1(formName) {
+            this.$refs[formName].resetFields();
+        },
+
+        // 计算区域的宽度
+        countRegionW(){
+            let list = JSON.parse(JSON.stringify(this.tableHeader))
+            for(let i = 0; i < list.length; i++) {
+                for(let j = 0;j < this.tableData.length; j++) {
+                    if(this.tableData[j][list[i].key] && this.tableData[j][list[i].key].length){
+                        if(list[i].length<this.tableData[j][list[i].key].length){
+                            list[i].length = this.tableData[j][list[i].key].length
+                        }
+                    }
+                }
+            }
+            console.log("list=====111",list)
+            this.tableHeader = [].concat(list)
+        },
+        /**  创建座位  结束  */
+
+
+        //列拖拽
+        columnDrop() {
+            // 阻止默认行为
+            document.body.addEventListener("drop", (event) => {
+                event.preventDefault();
+                event.stopPropagation();
+            });
+            const wrapperTr = document.querySelector(".el-table__header-wrapper tr");
+            this.sortable = Sortable.create(wrapperTr, {
+                animation: 180,
+                delay: 0,
+                onEnd: (evt) => {
+                    const oldItem = this.dropCol[evt.oldIndex];
+                    this.dropCol.splice(evt.oldIndex, 1);
+                    this.dropCol.splice(evt.newIndex, 0, oldItem);
+                },
+            });
+        },
+
+        dragSelectChange(e){
+            console.log("e===",e)
+            if(e && e.div) {
+                let  list = JSON.parse(JSON.stringify(e.div))
+                console.log("e===",new Set(list))
+            }
+            
+        },
+        dragLostItemChange(){},
+        reSelect() {
+
+        },
+
+        /**  批量操作 */
+
+        // 批量选择
+        handleSelectionChange(val){
+            this.multipleSelection = val;
+        },
+        // 编辑区域
+        openFormDialogVisible(){
+            this.formAllType = 'bindingregion'
+            this.formDialogVisibleTitle = "批量修改区域"
+            this.formDialogVisible = true
+            this.$set(this,'formAll',JSON.parse(JSON.stringify({
+                status: null,
+            })))
+        },
+        // 批量绑定区域
+        batchBindingArea() {
+            let list = []
+            let currentLabel = ''
+            
+            this.tableHeader.forEach((item)=>{
+                if(item.key == this.formAll.status) {
+                    currentLabel = item.title
+                }
+            })
+            let listId = []
+            this.multipleSelection.forEach((item)=>{
+                listId.push(item.id)
+            })
+            this.multipleSelection.forEach((item)=>{
+                list.push({
+                    ...item,
+                    style: {
+                        ...item.style,
+                        key: this.formAll.status, // 所属区域的key
+                        keyLabel: currentLabel, // 所属区域的名称
+                    }
+                })
+            })
+        },
+        // 批量禁用
+        batchDisable() {
+
+        },
+
+        /** 删选 */
+        handleQuery(){
+           
+            if(!this.queryParams.menuName&&!this.queryParams.status){
+                this.batchTableList = this.tableDataAll
+                console.log("list====",this.queryParams)
+            }else {
+                let list = []
+                this.tableDataAll.forEach((item,index)=>{
+                    if(this.queryParams.menuName&&this.queryParams.status) {
+                        if(item.rowNo==this.queryParams.menuName && item.style.key == this.queryParams.status) {
+                            list.push(item)
+                        }
+                    }else if(this.queryParams.menuName){
+                        if(item.rowNo==this.queryParams.menuName) {
+                            list.push(item)
+                        }
+                    }else {
+                        if(item.style.key == this.queryParams.status) {
+                            list.push(item)
+                        }
+                    }
+                })
+                console.log("list====",list,this.queryParams)
+                this.batchTableList = list
+            }  
+             
+        },
+        resetQuery(){
+            this.queryParams = {}
+
+        },
+
+        /** 座位排序  */
+        seatSortingFun(type){
+            let list = JSON.parse(JSON.stringify(this.currentTabelList))
+            if(type=='rise') { // 升序
+                list.sort(function(x,y){
+                    let num1 = x.columnNo
+                    let num2 = y.columnNo
+                    return num1 - num2
+                })
+            }
+            if(type=='fall') { // 降序
+                list.sort(function(x,y){
+                    let num1 = x.columnNo
+                    let num2 = y.columnNo
+                    return num2 - num1
+                })
+            }
+            if(type=='symmetry') { // 奇偶对称
+                let odd = []
+                let even = []
+                list.forEach((item,index)=>{
+                    if(item.columnNo%2==0){
+                        even.push(item)
+                    }else {
+                       odd.push(item)
+                    }
+                })
+
+                odd.sort(function(x,y){
+                    let num1 = x.columnNo
+                    let num2 = y.columnNo
+                    return num2 - num1
+                })
+                even.sort(function(x,y){
+                    let num1 = x.columnNo
+                    let num2 = y.columnNo
+                    return num1 - num2
+                })
+                list = odd.concat(even)
+            }
+            if(type=='reversal'){
+                list.reverse()
+            }
+            this.$set(this.tableData[this.currentRow-1],this.currentProperty,list)
+            this.currentTabelList = JSON.parse(JSON.stringify(this.tableData[this.currentRow-1][this.currentProperty]))
+        }
+    }
+};
+</script>
+ 
+<style scoped lang="scss">
+
+.sm {
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+    padding-top: 20px;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+}
+
+.sm-box {
+    width: 1300px;
+    height: 600px; 
+    box-sizing: border-box;
+    display: flex;
+    justify-content: center;
+    --row-w: 26px;
+    --row-h: 26px;
+}
+.sm-scroll-box {
+    width: 1000px;
+    height: 100%;
+    border: 1px solid #ccc;
+    box-sizing: border-box;
+    background-color: aqua;
+}
+
+.row-item-box {
+    border: 1px dashed #ccc;
+    width: 100%;
+    height: 100%;
+    align-items: center;
+    padding: 5px;
+}
+
+.row-item-box:hover {
+    background-color: rgba(64, 158, 255,0.3);
+}
+
+.row-item {
+    width: var(--row-w);
+    height: var(--row-h);
+    margin-left: 5px;
+    border: 1px solid #ccc;
+    display: flex;
+    flex-direction: column;
+    flex-shrink: 0;
+    font-size: 12px;
+    align-items: center;
+    box-sizing: border-box;
+    justify-content: center;
+    overflow: hidden;
+    i {
+        color: #fff;
+    }
+}
+
+.row-item:first-child {
+    margin-left: 0;
+} 
+
+.el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf {
+    border-bottom: none !important;
+}
+
+
+.table-tool {
+    width: calc( 100% - 1000px );
+    height: 100%;
+    padding: 0 10px;
+    box-sizing: border-box;
+    border: 1px solid #ccc;
+}
+.table-tool-tab {
+    height: 40px;
+}
+
+.qu-first-box {
+    width: 100%;
+    height: 100%;
+    .qu-first-row {
+        display: flex;
+        align-items: center;
+    }
+
+    .qu-first-form {
+        width: 100%;
+        height: 200px;
+        overflow: hidden;
+        padding-top: 10px;
+        box-sizing: border-box;
+        border-bottom: 1px solid #ccc;
+    }
+
+    .qu-first-info {
+        width: 100%;
+        height: calc( 100% - 200px );
+        overflow: hidden;
+        .qu-first-info-title {
+            width: 100%;
+            height: 25px;
+            display: flex;
+            align-items: flex-end;
+            padding-bottom: 5px;
+            span:first-child{
+                font-size: 16px;
+            }
+            span:last-child{
+                font-size: 12px;
+                margin-left: 10px;
+            }
+        }
+
+        .qu-first-info-list {
+            width: 100%;
+            height: calc( 100% - 30px );
+            box-sizing: border-box;
+            padding-right: 5px;
+            overflow: hidden;
+            overflow-y: auto;
+            .qu-first-info-item {
+                width: 100%;
+                height: 40px;
+                box-sizing: border-box;
+                border: 1px solid #ccc;
+                margin-bottom: 5px;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                font-size: 16px;
+                border-radius: 10px;
+                >span {
+                    width: 100%;
+                    height: 100%;
+                    display: flex;
+                    align-items: center;
+                    padding: 0 20px;
+                    font-weight: 600;
+                }
+                >div {
+                    display: flex;
+                    span {
+                        display: flex;
+                        padding: 0 10px;
+                        height: 100%;
+                        align-items: center;
+                        font-size: 12px;
+                        white-space: nowrap;
+                    }
+                    span:first-child {
+                        color: #409eff;
+                    }
+                    span:last-child {
+                        color: #f56c6c;
+                    }
+                }
+            }
+        }
+        .qu-first-info-list::-webkit-scrollbar {
+            width: 2px;
+        }
+        .qu-first-info-list::-webkit-scrollbar-track {
+            background-color: #ccc;
+        }
+    }
+}
+
+.qu-second-box {
+    width: 100%;
+    height: 100%;
+    .qu-second-select{
+        width: 100%;
+        height: 25px;
+        display: flex;
+        align-items: flex-end;
+        padding-bottom: 5px;
+        span:nth-child(1){
+            font-size: 16px;
+        }
+        span:not(:first-child){
+            font-size: 18px;
+            margin-left: 10px;
+            font-weight: 600;
+        }
+    }
+
+    .qu-second-row {
+        display: flex;
+        align-items: center;
+    }
+
+    .qu-second-form {
+        width: 100%;
+        height: 240px;
+        overflow: hidden;
+        padding-top: 10px;
+        box-sizing: border-box;
+        border-bottom: 1px solid #ccc;
+    }
+
+    .qu-second-info {
+        width: 100%;
+        height: calc( 100% - 320px );
+        overflow: hidden;
+        .qu-second-info-title {
+            width: 100%;
+            height: 25px;
+            display: flex;
+            align-items: flex-end;
+            padding-bottom: 5px;
+            span:first-child{
+                font-size: 14px;
+                font-weight: 600;
+            }
+            span:last-child{
+                font-size: 12px;
+                margin-left: 10px;
+            }
+        }
+        .qu-second-info-tool {
+            width: 100%;
+            height: 25px;
+            display: flex;
+            align-items: center;
+            padding-bottom: 5px;
+            span:first-child{
+                font-size: 14px;
+                font-weight: 600;
+            }
+            i {
+                font-size: 12px;
+                margin-left: 10px;
+                background-color: #1890FF;
+                color: #fff;
+                padding: 5px;
+                transform: scale(0.9);
+                border-radius: 5px;
+                cursor: pointer;
+            }
+            
+        }
+        .qu-second-info-list {
+            width: 100%;
+            height: calc( 100% - 60px );
+            box-sizing: border-box;
+            padding-right: 5px;
+            overflow: hidden;
+            overflow-y: auto;
+            .qu-second-info-item {
+                width: 100%;
+                height: 40px;
+                box-sizing: border-box;
+                border: 1px solid #ccc;
+                margin-bottom: 5px;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                font-size: 16px;
+                border-radius: 10px;
+                >span {
+                    width: 100%;
+                    height: 100%;
+                    display: flex;
+                    align-items: center;
+                    padding: 0 20px;
+                    font-weight: 600;
+                }
+                >div {
+                    display: flex;
+                    span {
+                        display: flex;
+                        padding: 0 10px;
+                        height: 100%;
+                        align-items: center;
+                        font-size: 12px;
+                        white-space: nowrap;
+                    }
+                    span:first-child {
+                        color: #409eff;
+                    }
+                    span:last-child {
+                        color: #f56c6c;
+                    }
+                }
+            }
+        }
+        .qu-second-info-list::-webkit-scrollbar {
+            width: 2px;
+        }
+        .qu-second-info-list::-webkit-scrollbar-track {
+            background-color: #ccc;
+        }
+    }
+}
+
+
+.qu-batch-box {
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+
+    .qu-batch-form {
+        height: 90px;
+        box-sizing: border-box;
+    }
+    .qu-batch-tool {
+        height: 40px;
+        box-sizing: border-box;
+    }
+    .qu-batch-table {
+        height: calc( 100% - 180px );
+        box-sizing: border-box;
+    }
+}
+
+
+::v-deep .exchange_table {
+  th {
+    padding: 0 !important;
+    height: 10px;
+    line-height: 10px;
+  }
+  td {
+    padding: 0 !important;
+    height: 30px;
+    line-height: 30px;
+  }
+  .cell {
+    height: 100%;
+  }
+
+  td.el-table__cell, th.el-table__cell.is-leaf {
+        border-bottom: none !important;
+    }
+}
+
+
+</style>

+ 2 - 1
src/views/venue/performanceHallMr/model/seatManagementTable.vue

@@ -1026,7 +1026,8 @@ export default {
         /**   保存座位   */
         saveSeat() {
             console.log('this.tableDataAll',this.tableDataAll)
-            this.$emit('saveSeat',this.tableDataAll)
+            
+            //this.$emit('saveSeat',this.tableDataAll)
         }
     }
 };

+ 840 - 0
src/views/windowTicketSales/model/increaseViewers.vue

@@ -0,0 +1,840 @@
+<template>
+    <el-dialog
+    title="添加观影人"
+    :visible.sync="dialogVisible"
+    width="90%"
+    :before-close="handleClose">
+    <div
+    v-loading="loading" 
+    :element-loading-text="loadingText"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)"
+    class="increase-viewers-box">
+        <div class="increase-viewers-info">
+            <el-table
+            :data="viewerList"
+            border
+            style="width: 100%">
+                <el-table-column
+                type="index"
+                width="50">
+                </el-table-column>
+                <el-table-column
+                    label="姓名"
+                    width="180">
+                    <template slot-scope="scope">
+                        <div>
+                            <span v-if="actionIndex != scope.row.id">{{ scope.row.name }}</span>
+                            <el-input v-else v-model="tableForm.name" placeholder="请输入姓名"></el-input>
+                        </div>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    label="身份证号"
+                    width="240">
+                    <template slot-scope="scope">
+                        <div>
+                            <span v-if="actionIndex != scope.row.id">{{ scope.row.idcard }}</span>
+                            <el-input
+                                v-else
+                                v-model="tableForm.idcard"
+                                placeholder="请输入身份证号"
+                                clearable
+                                style="width: 240px;"
+                                @keyup.enter.native="handleQuery"
+                            >
+                                <el-button slot="append" :loading="idcardLoading" size="mini" type="primary" @click="readCert">{{ idcardLoading ? '识别中':'识别' }}</el-button>
+                            </el-input>
+                        </div>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    label="座位类型">
+                    <template slot-scope="scope">
+                        <span>{{ scope.row.seatTypeName }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    prop="date"
+                    label="座位号">
+                    <template slot-scope="scope">
+                        <span>{{ scope.row.seatName }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    prop="date"
+                    label="价格(元)">
+                    <template slot-scope="scope">
+                        <span>{{ scope.row.salePrice }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    label="人员类别"
+                    width="180">
+                    <template slot-scope="scope">
+                        <div>
+                            <span v-if="actionIndex != scope.row.id">{{ scope.row.identity }}</span>
+                            <el-select
+                                v-else
+                                v-model="tableForm.identity"
+                                placeholder="请选择人员类别"
+                                clearable
+                                style="width: 100%"
+                            >
+                                <el-option
+                                v-for="dict in personnelType"
+                                :key="dict.id"
+                                :label="dict.name"
+                                :value="dict.id"
+                                />
+                            </el-select>
+                        </div>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    label="应付金额(元)">
+                    <template slot-scope="scope">
+                        <span>{{ scope.row.realPrice }}</span>
+                        <!-- <div>
+                            <span v-if="actionIndex != scope.row.id">{{ scope.row.realPrice }}</span>
+                            <el-input v-else v-model="tableForm.realPrice" placeholder="请输入应付金额(元)"></el-input>
+                        </div> -->
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    label="备注"
+                    width="180">
+                    <template slot-scope="scope">
+                        <div>
+                            <span v-if="actionIndex != scope.row.id">{{ scope.row.remark }}</span>
+                            <el-input v-else v-model="tableForm.remark" placeholder="请输入备注"></el-input>
+                        </div>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    label="操作"
+                    width="180">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        v-if="actionIndex == scope.row.id"
+                        @click="handleSeva(scope.$index, scope.row)">保存</el-button>
+                        <el-button
+                        :disabled="!!actionIndex"
+                        size="mini"
+                        v-if="actionIndex != scope.row.id"
+                        @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
+                        <el-button
+                        size="mini"
+                        type="danger"
+                        @click="handleDelete(scope.$index, scope.row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+        <div style="padding: 10px 0 20px;">合计:l累计观影人员{{ viewerList.length }}人,应付总额¥{{ moneyAll }}(元)</div>
+        <div>
+            <el-form 
+            :model="ruleForm" 
+            :rules="rules" 
+            ref="ruleForm11" 
+            label-width="100px" 
+            class="demo-ruleForm"
+            size="mini"
+            >
+                
+                <el-form-item label="用户来源:" prop="source">
+                    <el-radio-group v-model="ruleForm.source">
+                        <el-radio label="7">窗口</el-radio>
+                        <el-radio label="2">美团</el-radio>
+                        <el-radio label="3">携程</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item v-if="ruleForm.resource && ruleForm.resource != 1" label="核销码/订单码" prop="orderIdOrQrCode">
+                    <el-input style="width: 200px;" v-model="ruleForm.orderIdOrQrCode"></el-input>
+                </el-form-item>
+                <el-form-item label="支付方式:" prop="paymentType">
+                    <el-radio-group v-model="ruleForm.paymentType">
+                        <el-radio label="1">扫码</el-radio>
+                        <el-radio label="2">现金</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="应付金额:">
+                    ¥{{ moneyAll }}元
+                </el-form-item>
+                <el-form-item v-if="ruleForm.paymentType == 2" label="实付金额:" prop="realPrice">
+                    <el-input @input="setRealPrice" style="width: 200px;" v-model="ruleForm.realPrice"></el-input>
+                </el-form-item>
+                <el-form-item label="找零金额:" v-if="ruleForm.paymentType == 2">
+                    ¥{{ ruleForm.small }}元
+                </el-form-item>
+            </el-form>
+        </div>
+        <!--  支付过程 控制  -->
+        <div v-if="payStatus" class="increase-viewers-pay-status">
+            <div class="increase-viewers-pay-status-info">
+                <span>提示</span>
+                <span>
+                    {{ payStatus==1 ? '生成订单失败!!!' : 
+                    payStatus==2 ? '生成订单生成成功,请点击调取扫码盒子' : 
+                    payStatus==4 ? '扫码支付失败!!!' :
+                    payStatus==5 ? '请出示付款码!!!' :
+                    payStatus==6 ? '连接扫码器失败!!!' :
+                    payStatus==7 ? '用户支付失败或未支付,请重新连接支付!!!' :
+                    payStatus==8 ? '用户支付成功,请点击打印票!!!' :
+                    payStatus==3 ? '' : '未知状态' }}
+                </span>
+                <!-- 重新生成订单 1  -->
+                <el-button v-if="payStatus==1" @click="orderInfoSubmitFun()" type="primary">重新生成订单</el-button>
+                <!-- 扫码支付 2 -->
+                <el-button v-if="payStatus==2" @click="vbar_open(orderId)" type="success">扫码支付</el-button>
+                <!-- 扫码支付 4 -->
+                <el-button v-if="payStatus==4" @click="vbar_open(orderId)" type="success">重新扫码支付</el-button>
+                <!-- 重新支付 3 -->
+                <el-button v-if="payStatus==3" @click="gotoCashPayFun(orderId)" type="success">重新支付</el-button>
+                <!-- 重新支付 6  7 -->
+                <el-button v-if="payStatus==6 || payStatus==7" @click="vbar_open(orderId)" type="success">重新连接扫码支付</el-button>
+                <!-- 打印 8  -->
+                <div v-if="payStatus==8">
+                    <el-select v-model="printListId" placeholder="选择打印机">
+                        <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>
+                </div>
+            </div>
+        </div>
+    </div>
+    
+    <span slot="footer" class="dialog-footer">
+        <el-button @click="handleClose()">取 消</el-button>
+        <el-button v-if="!orderId" :loading="loading" type="primary" @click="submitForm('ruleForm11')">确定支付</el-button>
+    </span>
+    </el-dialog>
+</template>
+<script>
+import { 
+  querySeatList,
+  merchantPerformTimeList,
+  orderInfoSubmit,
+  gotoMicroPay,
+  gotoCashPay,
+  payQuery,
+  selectRegion,
+  orderInfoCancel,
+  lockOrUnLock,
+  merchantTheatreAuditoriumList
+ } from '@/api/windowTicketSales/ticketingSales'
+ import { pageList as getPrintListApi } from "@/api/device/pda";
+ import { printApi } from '@/api/windowTicketSales/ticketingCollection'
+ const https = require('https');
+ const axios = require('axios');
+  export default {
+    data() {
+      return {
+        loading: false,
+        loadingText: '',
+        dialogVisible: false,
+        actionIndex: false,
+        tableForm: {
+            name: '', // 姓名
+            mobile: '', // 电话
+            idcard: '', // 身份证
+            identity: '', // 观影人身份
+            remark: '', // 备注信息
+            salePrice: '', // 原价
+            realPrice: '', // 实付金额
+            seatId: '', // 座位ID
+            seatName: '', // 座位名称
+            seatType: '', // 座位类型
+        },
+        ruleForm: {
+            performId: "", // 剧目ID
+            retailId: "", // 分销ID
+            goodsList: [], // 商品列表
+            auditoriumId: "", // 演出厅ID
+            performTimeId: "1", // 场次时段ID
+            seatTypeId: "", // 座位类型ID
+            source: '', // 订单来源
+            purchaser: {},// 购票人信息
+            viewerList: [], // 观影人列表
+            orderIdOrQrCode: '',
+            paymentType: '', // 支付方式
+            small: '',// 实付金额
+        },
+        viewerList: [], // 观影人列表
+        rules: {
+            source: [
+                { required: true, message: '请选择用户来源', trigger: ['blur','change']},
+            ],
+            orderIdOrQrCode: [
+                { required: true, message: '请输入核销码/订单码', trigger: ['blur','change']},
+            ],
+            paymentType: [
+                { required: true, message: '请选择支付方式', trigger: ['blur','change']},
+            ],
+            realPrice: [
+                { required: true, message: '请输入核销码/订单码', trigger: ['blur','change']},
+            ],
+        },
+        moneyAll: '',
+        payment: '',
+        payStatus: null, // 支付状态
+        orderId: null,
+        websocket_connected: false, // 是否已连接
+        websocketCtrl: null,
+        websocketData: null,
+
+        idcardLoading: false,
+        personnelType: [
+            { id: "0" , name:'无' },
+            { id: "1", name:'现役军人' },
+            { id: "2" , name:'警察' },
+            { id: "3" , name:'消防员' },
+            { id: "4" , name:'残疾军人' }
+        ],
+        payTime: null, // 支付等待时间
+        printListId: null,
+        printList: []
+      };
+      
+    },
+    methods: {
+        async initData(list,params){
+            this.websocketClear()
+            this.idcardLoading = false
+            this.ruleForm = {
+                performId: "", // 剧目ID
+                retailId: "", // 分销ID
+                goodsList: [], // 商品列表
+                auditoriumId: "", // 演出厅ID
+                performTimeId: "1", // 场次时段ID
+                seatTypeId: "", // 座位类型ID
+                source: '', // 订单来源
+                purchaser: {},// 购票人信息
+                viewerList: [], // 观影人列表
+                orderIdOrQrCode: '',
+                paymentType: '', // 支付方式
+                small: '',// 实付金额
+            }
+            this.payStatus = null
+            this.orderId = null
+            this.websocket_connected = false
+            this.dialogVisible = true
+            this.loading = true
+            this.actionIndex = null
+            this.viewerList = []
+            let perform = await this.selectRegionFun(params)
+            console.log("perform===",perform)
+            // let perform = {
+            //     money: 1,
+            //     name: '普通票'
+            // }
+            let listCopy = []
+            let listCopy1 = []
+            list.forEach((item,index)=>{
+                listCopy.push({
+                    id: index+1,
+                    name: '', // 姓名
+                    mobile: '', // 电话
+                    idcard: '', // 身份证
+                    identity: '', // 观影人身份
+                    remark: '', // 备注信息
+                    salePrice: perform.money, // 原价
+                    realPrice: perform.money, // 实付金额
+                    seatId: item.id, // 座位ID
+                    seatName: item.name?item.name:'暂无命名', // 座位名称
+                    seatType: perform.seatTypeId, // 座位类型
+                    seatTypeId: perform.seatTypeId,
+                    seatTypeName: perform.seatTypeName,
+                })
+            })
+            //this.goodsList = 
+            this.viewerList = JSON.parse(JSON.stringify(listCopy))
+            this.setMoneyAll()
+            
+            console.log(this.viewerList)
+            this.loading = false
+            this.$nextTick(()=>{
+                this.$refs.ruleForm11.clearValidate()
+            })
+        },
+        /**  获取票务信息  */
+        async selectRegionFun(params){
+            try {
+                this.loadingText = "获取票务信息中..."
+                let res = await selectRegion({
+                    "auditoriumId": params.auditoriumId, // 演艺厅ID
+                    "goodsId": params.goodsId, // 商品ID
+                    "performId": params.performId, // 上一界面节目ID
+                    "performTimeId": params.timeId, // 时段ID
+                    "retailId": "" // 分销ID
+                })
+                if(res.code == 200) {
+                    if(res.data.regionPriceList &&res.data.regionPriceList.length>0){
+                        let obj = res.data.regionPriceList[0]
+                        this.ruleForm.performId = obj.performId
+                        this.ruleForm.goodsList = [
+                            {
+                                goodsId: obj.goodsId,
+                                salePeice: obj.salePrice,
+                                saleNum: 1,
+                            }
+                        ]
+                        this.ruleForm.auditoriumId = obj.auditoriumId
+                        this.ruleForm.performId = obj.performId
+                        this.ruleForm.performTimeId = res.data.performTimeId
+                        this.ruleForm.seatTypeId = obj.seatTypeId
+                        return {
+                            money: obj.salePrice,
+                            //name: obj.goodsName,
+                            seatTypeId: obj.seatTypeId,
+                            seatTypeName: obj.seatTypeName,
+                        }
+                    }else {
+                        this.$message.error('存在座位未设置价格,请选择其他票!!!');
+                        this.loading = false
+                        this.dialogVisible = false
+                    }
+                    console.log("res====",res)
+                }else {
+                    this.$message.error(res.msg);
+                    this.loading = false
+                    this.dialogVisible = false
+                }
+            } catch (error) {
+                console.error("error=====",error)
+                this.$message.error('价格查询出错');
+                this.loading = false
+                this.dialogVisible = false
+            }
+        },
+        /** 退出窗口 */
+        handleClose(done) {
+            // if(this.payStatus==8) {
+            //     this.$message.error('请daying');
+            //     return
+            // }
+            this.$confirm('确认关闭?')
+                .then(_ => {
+                    if(this.orderId){
+                        orderInfoCancel({
+                            orderId: this.orderId
+                        }).then((res)=>{
+                            if(res.code==200) {
+                                this.$emit('clearDialogVisible')
+                                this.dialogVisible = false
+                            }
+                        }).catch(()=>{
+                            this.$message.error('订单关闭失败!!!');
+                        })
+                    }else {
+                        this.dialogVisible = false
+                    }
+                })
+                .catch(_ => {});
+        },
+        handleSeva(index, row) {    
+            if(!this.tableForm.name){
+                this.$message.error('请输入姓名!!!');
+                return
+            }
+            if(!this.tableForm.idcard){
+                this.$message.error('请输入身份证号!!!');
+                return 
+            }
+            if(this.tableForm.identity){
+                if(!this.tableForm.remark){
+                    this.$message.error('请输入备注!!!');
+                    return 
+                }
+            }
+            this.$set(this.viewerList,index,JSON.parse(JSON.stringify(this.tableForm)))
+            this.actionIndex = null
+            this.setMoneyAll()
+        },
+        handleEdit(index, row) {
+            this.actionIndex = row.id
+            this.tableForm = JSON.parse(JSON.stringify(row))
+            
+            console.log(index, row);
+        },
+        handleDelete(index, row) {
+            console.log(index, row);
+        },
+        setMoneyAll(){
+            let moneyAll = 0
+            this.viewerList.forEach((item,index) => {
+                console.log("item.realPrice====",item.realPrice)
+                if(item.realPrice && !isNaN(Number(item.realPrice))) {
+                    moneyAll = moneyAll + Number(item.realPrice)
+                }
+            })
+            console.log("dsfsfdsf",moneyAll)
+            this.moneyAll = moneyAll? moneyAll: ''
+        },
+        setRealPrice(value) {
+            if(value && !isNaN(value)) {
+                this.$set(this.ruleForm,'small',Number(value) - this.moneyAll )
+            }
+        },
+        submitForm(formName) {
+            this.$refs[formName].validate((valid) => {
+            if (valid) {
+                this.orderInfoSubmitFun()
+            } else {
+                console.log('error submit!!');
+                return false;
+            }
+            });
+        },
+        resetForm(formName) {
+            this.$refs[formName].resetFields();
+        },
+        /**  生成订单  */
+        async orderInfoSubmitFun(){
+            this.loading = true
+            try {
+                this.orderId = null
+                this.loadingText = "生成订单中..."
+                let res = await orderInfoSubmit({
+                    ...this.ruleForm,
+                    viewerList: this.viewerList
+                })
+                if(res.code == 200){
+                    this.orderId = res.data.orderId
+                    if(this.ruleForm.paymentType == 2) {
+                        this.gotoCashPayFun()
+                    }else {
+                        this.loading = false
+                        this.payStatus = 2
+                    }
+                }else{
+                    this.$message.error('生成订单失败!!!');
+                    this.loading = false
+                    this.payStatus = 1
+                }
+            } catch (error) {
+                this.$message.error('生成订单失败!!!');
+                this.loading = false
+                this.payStatus = 1
+            }
+        },
+        
+         /** 调取 订单支付码支付  */
+         async gotoMicroPayFun(orderId,code){
+            this.loading = true
+            try {
+                this.loadingText = "订单支付中..."
+                this.payStatus = ''
+                let res = await gotoMicroPay({
+                    "orderId": orderId, // 订单编号-提交订单返回
+                    "authCode": code // 微信扫码支付-支付码
+                })
+                if(res.code == 200){
+                    this.websocketClear()
+                    if(this.payTime){
+                        clearInterval(this.payTime)
+                    }
+                    this.payTime = setInterval(()=>{
+                        this.payQueryFun(this.orderId)
+                    },1500)
+                }else{
+                    this.$message.error('支付失败!!!');
+                    this.payStatus = ''
+                    this.loading = false
+                    this.payStatus = 6
+                }
+            } catch (error) {
+                this.$message.error('支付失败!!!');
+                this.loading = false
+                this.payStatus = 6
+            }
+        },
+
+         /**  订单现金支付  */
+         async gotoCashPayFun(orderId){
+            this.loading = true
+            try {
+                this.loadingText = "订单支付中..."
+                let res = await gotoCashPay({
+                    "orderId": orderId // 订单编号-提交订单返回
+                })
+                if(res.code == 200){
+                    if(this.payTime){
+                        clearInterval(this.payTime)
+                    }
+                    this.payTime = setInterval(()=>{
+                        this.payQueryFun(this.orderId)
+                    },1500)
+                }else{
+                    this.$message.error('支付失败!!!');
+                    this.loading = false
+                    this.payStatus = 3
+                }
+            } catch (error) {
+                this.$message.error('支付失败!!!');
+                this.loading = false
+                this.payStatus = 3
+            }
+        },
+
+         /**  查看支付 状态  */
+         async payQueryFun(orderId){
+            this.loading = true
+            try {
+                this.loadingText = "订单支付中..."
+                this.payStatus = ''
+                let res = await payQuery({
+                    orderId: orderId
+                })
+                if(res.code == 200){
+                    if(res.data) {
+                        if(res.data.payStatus == 0) {
+                            if(this.payTime){
+                                clearInterval(this.payTime)
+                            }
+                            this.$message.error('用户未支付!!!');
+                            this.loading = false
+                            this.payStatus = 7
+                        }else if(res.data.payStatus == 1) {
+                            if(this.payTime){
+                                clearInterval(this.payTime)
+                            }
+                            this.$message('用户已支付!!!');
+                            // 开始 打印
+                            this.loading = false
+                            this.payStatus = 8
+                            this.getPrintListApi()
+                        }else if(res.data.payStatus == 2) {
+
+                        }else if(res.data.payStatus == 3) {
+                            if(this.payTime){
+                                clearInterval(this.payTime)
+                            }
+                            this.$message.error('用户支付失败!!!');
+                            this.loading = false
+                            this.payStatus = 7
+                        }else if(res.data.payStatus == 4) {
+                            if(this.payTime){
+                                clearInterval(this.payTime)
+                            }
+                            this.$message.error('支付退款!!!');
+                            this.loading = false
+                            this.payStatus = 7
+                        }
+                    }
+                    
+                }else{
+                    this.$message.error('支付失败!!!');
+                    this.loading = false
+                    this.payStatus = 7
+                }
+                
+            } catch (error) {
+                this.$message.error('支付失败!!!');
+                this.loading = false
+                this.payStatus = 7
+            }
+        },
+
+        /**  连接VBarServer  */
+        vbar_open() {
+            this.loading = true
+            this.loadingText = "连接扫码盒子中!!!"
+            this.payStatus =  null
+            this.websocketClear()
+            console.log('sdfdsfsd')
+            if (!this.websocket_connected) {
+                var host = "ws://localhost:2693";
+                this.websocketCtrl = new WebSocket(host,'ctrl');
+                this.websocketData = new WebSocket(host,'data');
+                this.websocketData.onopen = (evt) => {
+                    console.log('sdasdasd====',evt)
+                    this.loading = false
+                    this.payStatus = 5
+                    this.websocket_connected = true;
+                    this.websocket_open_state(evt);
+                }
+                this.websocketData.onerror = (evt) => {
+                    console.log('sdasdasd11111====',evt)
+                    this.payStatus = 6
+                    //this.vbar_open()
+                }
+
+                this.websocketData.onmessage = (evt) => {
+                    console.log("接受消息====",evt)
+                    this.websocket_decode(evt.data);
+                }
+            }
+
+            //setTimeout(this.vbar_open(), 3000);
+        },
+        /**  连接结果 */
+        websocket_open_state(message){
+            //document.getElementById('wsocket').value = "已连接";
+        },
+        //接收扫码结果处理
+        websocket_decode(code){
+            console.log()
+            if(this.orderId && this.payStatus==5 &&code) {
+                this.gotoMicroPayFun(this.orderId,code)
+            }
+        },
+        /** 关闭通讯 */
+        websocketClear(){
+            if(this.websocketCtrl){
+                this.websocketCtrl.close()
+            }
+            if(this.websocketData){
+                this.websocketData.close()
+            }
+            this.websocket_connected = false
+        },
+        /**  读取身份证 */
+        readCert(){
+            this.idcardLoading = true
+            var result = "";
+            try {
+                let xmlHttp = new XMLHttpRequest();
+                let Protocol = window.location.protocol.split(':')[0];
+                //获取当前协议,并且分割字符串,得到http或者https
+                if (Protocol === 'https'){
+                    //创建请求 第一个参数是代表以post方式发送;第二个是请求端口和地址;第三个表示是否异步
+                    xmlHttp.open("POST", "http://127.0.0.1:18889/api/readCert?ReadSN=" + 0, false);	  //readCert读卡,生成正反面仿复印件	
+                }else {
+                    //创建请求 第一个参数是代表以post方式发送;第二个是请求端口和地址;第三个表示是否异步
+                    xmlHttp.open("POST", "http://127.0.0.1:18889/api/readCert?ReadSN=" + 0, false);	  //readCert读卡,生成正反面仿复印件	
+                }
+                //发送请求
+                xmlHttp.send();
+                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
+                    result = xmlHttp.responseText;
+                    xmlHttp.readyState = 1;
+                }
+            } catch (e) {
+                console.error("e====",e)
+            }
+            let obj = JSON.parse(result)
+            if(obj.resultContent && obj.resultContent.certNumber){
+                this.$set(this.tableForm,"idcard",obj.resultContent.certNumber)
+                this.$set(this.tableForm,"name",obj.resultContent.partyName)
+            }else {
+                this.$message.error('读取失败!!!');
+            }
+            
+            this.idcardLoading = false
+            //return result;
+             console.log(result,obj)
+        },
+        /** 查询打印机列表 */
+        getPrintListApi() {
+          getPrintListApi({deviceType:5,pageNum: 1,
+          pageSize: 999,})
+          .then(response => {
+              this.printList = response.data.rows;
+          }).catch((error)=>{
+            console.log("error===",error)
+          }
+          );
+        },
+        // 打印 
+        async print(list = []){
+            if(!this.printListId) {
+                this.$message.error('请选择打印机!!');
+                return
+            }
+            this.loading = true
+              this.loadingText = '打印中...'
+              this.payStatus = ''
+              try {
+                let res = await printApi({
+                  orderId: this.orderId,
+                  source: 2,
+                  deviceId: this.printListId
+                })
+                if(res.code == 200) {
+                  let url = res.data.linkIp
+                  let printInfo = res.data.printInfo
+                  this.connectPrint(url,printInfo)
+                }else {
+                  throw new Error(res)
+                }
+              } catch (error) {
+                this.loading = false
+                 this.payStatus = 8
+                console.error("error=====",error)
+              }
+          
+        },
+        /**  连接打印机  */
+        connectPrint(url,data){
+          // 创建忽略 SSL 的 axios 实例
+          const ignoreSSL = axios.create({
+            httpsAgent: new https.Agent({  
+              rejectUnauthorized: false
+            }),
+            withCredentials: true, // 跨域请求时发送Cookie
+            timeout: 60000, // 请求超时
+            headers: {
+              "Content-Type": "application/json; charset=UTF-8;"
+            }
+          });
+          ignoreSSL.post(url, 
+            { ...data }
+            ).then(()=>{
+            this.dialogVisible = false
+            this.loading = false
+          }).catch(()=>{
+            this.loading = false
+            this.payStatus = 8
+            // this.dialogVisible = false
+            // this.loading = false
+          })
+          // 在 axios 请求时,选择性忽略 SSL
+          // const agent = new https.Agent({  
+          //   rejectUnauthorized: false
+          // });
+          // axios.post(
+          //   url, 
+          //   { httpsAgent: agent,...data }
+          //   ).then(()=>{
+          //   this.dialogVisible = false
+          //   this.loading = false
+          // })
+          // .catch(()=>{
+          //   this.dialogVisible = false
+          //   this.loading = false
+          // })
+        },
+    }
+}
+</script>
+<style scoped lang="scss">
+.increase-viewers-box {
+    width: 100%;
+    height: calc( 100vh - 250px );
+    box-sizing: border-box;
+    overflow: hidden;
+    overflow-y: auto;
+    position: relative;
+}
+.increase-viewers-pay-status {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    z-index: 999999;
+    background-color: rgba(0,0,0,0.3);
+    top: 0;
+    left: 0;
+    .increase-viewers-pay-status-info {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        color: #fff;
+    } 
+} 
+
+</style>

+ 563 - 8
src/views/windowTicketSales/ticketingSales.vue

@@ -1,11 +1,566 @@
 <template>
-    <!--  票务售票  -->
-    <div>
-        票务售票
+    <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"
+          >
+            <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"
+            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"
+          >
+            <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"
+          >
+            <el-option
+              v-for="dict in goodsPageListS"
+              :key="dict.id"
+              :label="dict.goodsName"
+              :value="dict.id"
+              :disabled="dict.status==1 || dict.goodsPerform.channelWindow != 0"
+            />
+          </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-box">
+        <!-- 选择座位  -->
+        <div class="seat-list-box">
+            <!--  座位排版  -->
+            <div v-loading="loading" class="dialog">
+                <div class="seat-box-class clearfix" v-if="seatMapList">
+                    <div
+                    class="seat-item-class-box" 
+                    v-for="(item1, index1) in Object.keys(seatMapList)" 
+                    :key="index1"
+                    >
+                        <div 
+                        class="seat-item-class" 
+                        :class="item.occupyStatus==0?'occupy-status': item.isDisabled || item.status == 2 ? 'disabled-class' : item.isSelect ? 'select-class' : ''"
+                         v-for="(item, index) in seatMapList[item1]" 
+                         @click.stop="seatClick(item)" 
+                         :key="index">
+                            <p class="text-class">{{item.name ? item.name : '暂未命名'}}</p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div style="margin-top: 5px; margin-left: 30px;display: flex;">
+                <div style="flex-shrink: 0;">
+                    已勾选:{{ seatSelectList.length }}个座位
+                </div>
+                <div style="width: 100%;display: flex;justify-content: center;height: 30px;">
+                    <el-button size="mini" type="warning" :loading="lockOrUnLockLoading" @click="lockOrUnLockFun(seatSelectList,0)">锁定</el-button>
+                    <el-button size="mini" type="primary" @click="increaseViewersFun">购票</el-button>
+                </div>
+            </div>
+        </div>
+        <!-- <div class="seat-select-box">
+            <div class="seat-select-info">
+                <div 
+                class="seat-select-item"
+                :key="index" 
+                v-for="(item,index) in seatSelectList">
+                    <span>{{item.name ? item.name : '暂未命名'}}</span>
+                </div>
+            </div>
+        </div> -->
+      </div>
+      <!--  添加观影人  -->
+      <increaseViewers ref="increaseViewers" @clearDialogVisible="clearDialogVisible" />
     </div>
-</template>
-<script>
-    export default {
-        
+  </template>
+  
+  <script>
+  import { 
+  querySeatList,
+  merchantPerformTimeList,
+  lockOrUnLock,
+  merchantTheatreAuditoriumList,
+  goodsPageList,
+ } from '@/api/windowTicketSales/ticketingSales'
+ import increaseViewers from "./model/increaseViewers"
+  export default {
+    name: "distributionapplication",
+    components: {
+        increaseViewers
+    },
+    data() {
+      return {
+        // 遮罩层
+        loading: false,
+        // 查询参数
+        queryParams: {
+            timeId: null,
+            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: [], // 票务
+        setList: [],
+        seatMapList: [],
+        seatSelectList: [],
+
+        lockOrUnLockLoading: false,
+
+        performId: '',// 剧目ID
+      };
+    },
+    created() {
+        this.merchantTheatreAuditoriumListFun()
+        this.goodsPageListFun()
+    },
+    methods: {
+        /**  票务信息  */
+        async goodsPageListFun(){
+            try {
+                let res = await goodsPageList({
+                    pageNum: 1,
+                    pageSize: 999,
+                    classifyId: 1,
+                    goodsType: 2,
+                })
+                if(res.code == 200){
+                    this.goodsPageListS = res.data.rows
+                    // let list = []
+                    // res.data.rows.forEach((item,index)=>{
+                    //     if(item.status != 1) {
+                    //         list.push(item)
+                    //     }
+                    // })
+                    // this.goodsPageListS = list
+                }
+            } catch (error) {
+                
+            }
+        },
+        /**  获取演出厅  */
+        async merchantTheatreAuditoriumListFun(){
+            try {
+                let res = await merchantTheatreAuditoriumList({
+                    pageNum: 1,
+                    pageSize: 999
+                })
+                if(res.code == 200){
+                    this.merchantTheatreAuditoriumListS = res.data.rows
+                }
+            } catch (error) {
+                
+            }
+        },
+        /**  获取场次  */
+        async merchantPerformTimeListFun(){
+            try {
+                let res = await merchantPerformTimeList({
+                    ...this.queryParams
+                })
+                if(res.code == 200){
+                    this.merchantPerformTimeListS = res.data.rows
+                }
+            } catch (error) {
+                
+            }
+        },
+        /**  座位锁定/解锁  */
+        async lockOrUnLockFun(listS,type){
+            try {
+                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: type,
+                    seatList: list
+                })
+                this.lockOrUnLockLoading = false
+                if(res.code) {
+                    this.$message({
+                        showClose: true,
+                        message: res.msg,
+                        type: 'success'
+                    });
+                    this.querySeatListFun()
+                }
+                
+            } 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 = ''
+                if(type) { // 是否清除已选
+                    this.seatSelectList = []
+                }
+                this.seatMapList = {}
+                this.seatList = []
+                let res = await querySeatList({
+                    ...this.queryParams
+                })
+                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 = {}
+                list.forEach(item => {
+                    item.isDisabled = (item.occupyStatus != null && (item.occupyStatus == 0 || item.occupyStatus == 1) ? true : false); // 座位是否已被选择
+                    item.isSelect = this.setIsSelect(item);
+                    if(item.rowNo){
+                        if(listCopy['my'+item.rowNo]){
+                            listCopy['my'+item.rowNo].push(item)
+                        }else {
+                            listCopy['my'+item.rowNo] = [item] 
+                        }
+                    }
+                })
+                // Object.keys(listCopy).forEach((item)=>{
+                //     lisyCopy[item]
+                // })
+                console.log("list====",listCopy)
+                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){
+            if(this.queryParam && this.queryParam.timeId) {
+                this.$set(this.queryParam,'timeId',null)
+            }
+            if(this.queryParams.auditoriumId&&this.queryParams.performDate){
+                this.merchantPerformTimeListFun()
+            }
+            this.performId = ''
+            this.seatSelectList = []
+            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
+                }
+            })
+        },
+        /** 搜索按钮操作 */
+        handleQuery() {
+            this.$refs.queryForm.validate((valid) => {
+            if (valid) {
+                this.querySeatListFun();
+            } else {
+                console.log('error submit!!');
+                return false;
+            }
+            });
+            
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            this.$refs.queryForm.resetFields()
+            this.handleQuery();
+        },
+
+        // 座位点击事件
+        seatClick(row) {
+            console.log(row)
+            if(row.occupyStatus == 0){
+                console.log("weqwrwerewrer")
+                this.$confirm('此座已被锁定,请先解锁', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    this.lockOrUnLockFun([row],1)
+                }).catch((error) => {
+                    console.log("error====",error)
+                });
+            }else if(row.isDisabled){
+                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()
+            }
+            
+        },
+        increaseViewersFun(){
+            if(this.seatSelectList.length>0){
+                this.changePerformId(this.queryParams.timeId)
+                this.$refs.increaseViewers.initData(this.seatSelectList,{
+                    ...this.queryParams,
+                    performId:this.performId
+                })
+            }else {
+                this.$alert('请先选择座位!!!', '提示', {
+                    confirmButtonText: '确定',
+                    callback: action => {
+                        
+                    }
+                });
+            }
+            
+        },
+        /**  弹窗关闭 */
+        clearDialogVisible(){
+            //this.
+            this.querySeatListFun(true)
+        }
+    }   
+  };
+  </script>
+  <style lang="scss" scoped>
+  .app-container-me {
+    width: 100%;
+    height: calc( 100vh - 120px );
+  }
+  .seat-box {
+    width: 100%;
+    height: calc( 100% - 80px ) ;
+    box-sizing: border-box;
+    display: flex;
+    .seat-list-box {
+        //width: calc(100% - 200px);
+        width: 100%;
+        height: 100%;
+        box-sizing: border-box;
     }
-</script>
+    .seat-select-box {
+        width: 200px;
+        height: 100%;
+        flex-shrink: 0;
+        box-sizing: border-box;
+        .seat-select-info {
+            width: 100%;
+            height: 100%;
+            overflow: hidden;
+            overflow-y: auto;
+            .seat-select-item {}
+        }
+    }
+  }
+  .dialog {
+    padding: 0 30px;
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+    overflow: auto;
+    border-radius: 10px;
+    border: 1px  solid #323333;
+    .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;
+      
+      box-sizing: border-box;
+      .disabled-class{
+        background-color: #aaabad;
+        user-select: none;
+        pointer-events: none;
+      }
+      .select-class{
+        //background-color: #e85353 !important;
+        border: 2px 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.png');
+        background-size: 50% 50%;
+        background-position: 50% 50%;
+        background-repeat: no-repeat;
+        z-index: 99;
+    }
+      .occupy-status {
+        //pointer-events: none;
+      }
+      .seat-item-class-box {
+        width: 100%;
+        display: flex;
+        flex-wrap: nowrap;
+      }
+      .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;
+        &:hover{
+          opacity: 0.6;
+        }
+  
+        .text-class{
+          font-size: 12px;
+          padding: 5px;
+          line-height: 16px;
+          margin: 0;
+        }
+      }
+    }
+  }
+  </style>