Browse Source

Merge branch 'master' of http://dzgogs.hw.hongweisoft.com/great_transition/great_webui

gcz 1 year ago
parent
commit
96aadab28f
39 changed files with 3596 additions and 529 deletions
  1. 2 0
      package.json
  2. 10 0
      src/api/order/orderMr.js
  3. 9 0
      src/api/ticketMr/ticketMr.js
  4. 10 7
      src/api/userMr/userMr.js
  5. 21 0
      src/api/windowTicketSales/ticketingCollection.js
  6. 28 0
      src/main.js
  7. 1 1
      src/utils/request.js
  8. 7 0
      src/views/device/printer/dialog/dataBox.vue
  9. 1 0
      src/views/device/printer/index.vue
  10. 10 6
      src/views/distribution/detailMr/index.vue
  11. 51 5
      src/views/distribution/personnelMr/dialog/addAndEdit.vue
  12. 20 11
      src/views/distribution/personnelMr/index.vue
  13. 3 3
      src/views/distribution/ticketMr/index.vue
  14. 3 0
      src/views/finance/refundMr/dialog/details.vue
  15. 8 3
      src/views/finance/refundMr/dialog/orderDetails.vue
  16. 3 2
      src/views/finance/refundMr/index.vue
  17. 1 1
      src/views/order/groupBuyingMr/dialog/details.vue
  18. 150 9
      src/views/order/groupBuyingMr/index.vue
  19. 6 36
      src/views/order/orderMr/dialog/details.vue
  20. 156 51
      src/views/order/orderMr/index.vue
  21. 2 2
      src/views/order/writeOffMr/index.vue
  22. 1 1
      src/views/otaMr/dialog/dataEdit.vue
  23. 2 2
      src/views/statistics/index.vue
  24. 6 8
      src/views/system/selfServeAdvertis/index.vue
  25. 13 2
      src/views/team/applicationMr/dialog/applicationDetails.vue
  26. 5 1
      src/views/team/applicationMr/dialog/orderDetails.vue
  27. 3 3
      src/views/team/ticketMr/index.vue
  28. 267 0
      src/views/ticket/ticketMr/dialog/FreightMgrIndexMi.js
  29. 161 1
      src/views/ticket/ticketMr/dialog/addAndEdit.vue
  30. 6 0
      src/views/ticket/ticketMr/dialog/details.vue
  31. 8 7
      src/views/userMr/dialog/dataBox.vue
  32. 9 4
      src/views/userMr/index.vue
  33. 80 361
      src/views/venue/performanceHallMr/dialog/seatTemplateEdit.vue
  34. 682 0
      src/views/venue/performanceHallMr/dialog/seatTemplateEditOld.vue
  35. 3 2
      src/views/venue/performanceHallMr/index.vue
  36. 1375 0
      src/views/venue/performanceHallMr/model/seatManagementTable.vue
  37. 451 0
      src/views/windowTicketSales/ticketingCollection.vue
  38. 11 0
      src/views/windowTicketSales/ticketingInquiry.vue
  39. 11 0
      src/views/windowTicketSales/ticketingSales.vue

+ 2 - 0
package.json

@@ -44,6 +44,7 @@
     "@smallwei/avue": "^3.2.20",
     "@sscfaith/avue-form-design": "^1.5.6",
     "ant-design-vue": "^1.7.8",
+    "awe-dnd": "^0.3.4",
     "axios": "0.24.0",
     "beautifier": "^0.1.7",
     "china-area-data": "^5.0.1",
@@ -68,6 +69,7 @@
     "quill": "1.3.7",
     "screenfull": "5.0.2",
     "sortablejs": "1.10.2",
+    "ty-drag-select": "^1.0.42",
     "voca": "^1.4.0",
     "vue": "2.6.12",
     "vue-barcode": "^1.3.0",

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

@@ -27,3 +27,13 @@ export function downOrderListXls(params) {
     params
   });
 }
+
+
+// 打印
+export const printApi = (data) => {
+  return request({
+    url: '/order/orderInfo/ticketout',
+    method: 'post',
+    data: data
+  })
+}

+ 9 - 0
src/api/ticketMr/ticketMr.js

@@ -51,3 +51,12 @@ export function getSelectById(id) {
     method: 'get'
   })
 }
+
+// 获取行政区划
+export function basePositionApi(data) {
+  return request({
+    url: '/system/basePosition/list',
+    method: 'get',
+    params:data
+  })
+}

+ 10 - 7
src/api/userMr/userMr.js

@@ -12,25 +12,28 @@ export const pageList = (query) => {
 // 取消认证状态
 export function updateAuthStatus(data) {
   return request({
-    url: '/member/memberInfo/updateAuthStatus?id=' + data.id,
-    method: 'get'
+    url: '/member/memberInfo/updateAuthStatus',
+    method: 'get',
+    params: data
   })
 }
 
 // 加入黑名单
 export function addBlackList(data) {
   return request({
-    url: '/member/memberInfo/addBlackList?id=' + data.id,
-    method: 'get'
+    url: '/member/memberInfo/blackList',
+    method: 'get',
+    params: data
   })
 }
 
 
 // ID获取详情
-export function getSelectById(id) {
+export function getSelectById(data) {
   return request({
-    url: '/merchant/merchantTheatre/selectById?id=' + id,
-    method: 'get'
+    url: '/member/memberInfo/detail',
+    method: 'get',
+    params: data
   })
 }
 

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

@@ -0,0 +1,21 @@
+import request from '@/utils/request'
+
+// 分页查询
+export const pageList = (query) => {
+  return request({
+    url: '/order/orderInfo/getValidPageList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 打印
+export const printApi = (data) => {
+  return request({
+    url: '/order/orderInfo/ticketout',
+    method: 'post',
+    data: data
+  })
+}
+
+

+ 28 - 0
src/main.js

@@ -92,6 +92,34 @@ let options = {
 Vue.use(options);
 // 打印设计结束
 
+<<<<<<< HEAD
+// 打印设计开始
+import Antd from 'ant-design-vue';
+import 'ant-design-vue/dist/antd.css';
+Vue.use(Antd);
+
+import {hiPrintPlugin} from './index'
+Vue.use(hiPrintPlugin)
+hiPrintPlugin.disAutoConnect();
+
+// import Storage from 'vue-ls'
+let options = {
+  namespace: 'hiPrint-',
+  name: 'ls',
+  // storage: 'local',
+};
+// Vue.use(Storage, options);
+Vue.use(options);
+// 打印设计结束
+
+import VueDND from 'awe-dnd'
+ 
+Vue.use(VueDND)
+
+import dragSelect from 'ty-drag-select'
+
+Vue.use(dragSelect)
+
 /**
  * If you don't want to use mock-server
  * you want to use MockJs for mock api

+ 1 - 1
src/utils/request.js

@@ -17,7 +17,7 @@ const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分
   baseURL: process.env.VUE_APP_BASE_API,
   // 超时
-  timeout: 20000
+  timeout: 200000
 })
 
 // request拦截器

+ 7 - 0
src/views/device/printer/dialog/dataBox.vue

@@ -35,6 +35,10 @@
           <el-input v-if="type!=3" v-model="form.deviceAddress" placeholder="请输入所在位置" />
           <span v-else>{{ form.deviceAddress }}</span>
         </el-form-item>
+        <el-form-item label="连接IP:" prop="connectIp">
+          <el-input v-if="type!=3" v-model="form.connectIp" placeholder="请输入连接IP" />
+          <span v-else>{{ form.connectIp }}</span>
+        </el-form-item>
         <el-form-item label="设备类型:" prop="deviceType">
           <dict-tag :options="dict.type.device_sys_type" :value="form.deviceType"/>
         </el-form-item>
@@ -81,6 +85,9 @@ export default {
         deviceAddress: [
           { required: true, message: "请输入所在位置", trigger: ["change","blur"] },
         ],
+        connectIp: [
+          { required: true, message: "请输入连接IP", trigger: ["change","blur"] },
+        ]
       },
     };
   },

+ 1 - 0
src/views/device/printer/index.vue

@@ -18,6 +18,7 @@
       <el-table-column label="设备名称" align="center" prop="deviceName" />
       <el-table-column label="设备编码" align="center" prop="deviceNo" />
       <el-table-column label="所在位置" align="center" prop="deviceAddress" />
+      <el-table-column label="连接IP" align="center" prop="connectIp" />
       <el-table-column label="设备类型" align="center" prop="deviceType">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.device_sys_type" :value="scope.row.deviceType"/>

+ 10 - 6
src/views/distribution/detailMr/index.vue

@@ -74,7 +74,11 @@
     <el-table ref="tables" v-loading="loading" :data="dataList" border>
       <el-table-column label="序号" align="center" type="index" width="60"></el-table-column>
       <el-table-column label="分销商名称" align="center" prop="personsName" />
-      <el-table-column label="分销商类型" align="center" prop="personType" />
+      <el-table-column label="分销商类型" align="center" prop="personType">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.distribution_type" :value="scope.row.personType"/>
+        </template>
+      </el-table-column>
       <el-table-column label="金额(元)" align="center" prop="type">
         <template slot-scope="scope">
           <span v-if="scope.row.balance">¥{{ scope.row.balance }}</span>
@@ -110,7 +114,7 @@ import { pageList, downOrderListXls } from '@/api/distribution/detailsMr'
 import { exportExcel } from '@/utils/exportexcel'
 export default {
   name: "agreement",
-  dicts: ['agreement_type'],
+  dicts: ['distribution_type'],
   data() {
     return {
       // 遮罩层
@@ -153,8 +157,8 @@ export default {
         5: '支付宝',
       },
       incomeExpensesList: [
-        {id: 1, name: '收入', value: '收入'},
-        {id: 2, name: '支出', value: '支出'},
+        {id: 1, name: '收入', value: 1},
+        {id: 2, name: '支出', value: 2},
       ],
       businessTypeList: [
         {id: 1, name: '佣金收益', value: '佣金收益'},
@@ -203,10 +207,10 @@ export default {
     /** 重置按钮操作 */
     resetQuery() {
       this.dateRange = [];
-      this.$set(this.queryParams, 'id', '');
       this.$set(this.queryParams, 'time', []);
       this.$set(this.queryParams, 'serialContent', '');
-      this.$set(this.queryParams, 'incomeExpenses', '');
+      this.$set(this.queryParams, 'personsName', '');
+      this.$set(this.queryParams, 'serialType', '');
       this.queryParams.pageNum = 1;
       this.handleQuery();
     },

+ 51 - 5
src/views/distribution/personnelMr/dialog/addAndEdit.vue

@@ -67,7 +67,6 @@
             reserve-keyword
             placeholder="请选择上级分销人员"
             :remote-method="remoteMethod"
-            @change=""
             :loading="parentNameLoading">
             <el-option
               v-for="item in parentNameList"
@@ -149,7 +148,7 @@ export default {
         contact: [{ required: true, message: "请输入负责人", trigger: ["change","blur"] }],
         mobile: [{ required: true, message: "请输入账号/联系电话", trigger: ["change","blur"] }],
         allowWithdraw: [{ required: true, message: "请选择是否可提现", trigger: ["change","blur"] }],
-        parentId: [{ required: true, message: "请选择上级分销人员", trigger: ["change","blur"] }],
+        //parentId: [{ required: true, message: "请选择上级分销人员", trigger: ["change","blur"] }],
         salePerson: [{ required: true, message: "请输入销售人员名称", trigger: ["change","blur"] }],
       },
       uploadObj: {
@@ -158,7 +157,8 @@ export default {
       },
 
       parentNameLoading: false,
-      parentNameList: []
+      parentNameList: [],
+      parentId: null,
     };
   },
   methods: {
@@ -170,7 +170,9 @@ export default {
      */
     openDialog(title, obj) {
       this.open = true;
+      this.parentId = null
       this.reset();
+      this.parentNameList = []
       if (obj){
         this.title = "编辑分销人员";
         this.getSelectByIdApi(obj);
@@ -186,6 +188,10 @@ export default {
       const id = row.id
       getSelectById(id).then(response => {
         const obj = response.data;
+        this.parentId = obj.id
+        if(row.parentId && obj.parentId != 0){
+          this.getList({id:row.parentId})
+        }
         this.$nextTick(() => {
           this.$set(this.form, 'id', obj.id);
           this.$set(this.form, 'name', obj.name);
@@ -194,8 +200,11 @@ export default {
           this.$set(this.form, 'mobile', obj.mobile);
           this.$set(this.form, 'allowWithdraw', obj.allowWithdraw);
           this.$set(this.form, 'parentName', obj.parentName);
+          this.$set(this.form, 'parentId', obj.parentId && obj.parentId != 0 ? obj.parentId : null);
+          this.$set(this.form, 'salePerson', obj.salePerson);
         });
       });
+      
     },
     /**
      * 保存
@@ -207,7 +216,10 @@ export default {
         if (valid) {
           try {
             this.loading = true;
-            const { code } = await saveAndEdit({ ...this.form });
+            const { code } = await saveAndEdit({ 
+              ...this.form,
+              parentId: this.form.parentId && this.form.parentId != 0 ? this.form.parentId : 0
+             });
             if (code === 200) {
               this.$message.success("操作成功!");
               this.$emit("getList");
@@ -232,6 +244,8 @@ export default {
       this.$set(this.form, 'contact', '');
       this.$set(this.form, 'mobile', '');
       this.$set(this.form, 'password', '');
+      this.$set(this.form, 'parentId', '');
+      this.$set(this.form, 'salePerson', '');
     },
     /**
      * 关闭弹框
@@ -302,7 +316,39 @@ export default {
           })
           .then(response => {
               this.parentNameLoading = false;
-              this.parentNameList = response.data.rows;
+              let list = []
+              console.log("list===",this.parentId)
+              response.data.rows.forEach((item,index)=>{
+                if(this.parentId != item.id) {
+                  list.push(item)
+                }
+              })
+              this.parentNameList = [].concat(list);
+              this.parentNameLoading = false;
+            }
+          ).catch ((error)=>{
+            console.error('error===',error)
+            this.parentNameLoading = false;
+          })
+        } else {
+          this.parentNameList = [];
+        }
+      },
+      getList(query) {
+        if (query !== '') {
+          this.parentNameLoading = true;
+          pageList({
+            ...query
+          })
+          .then(response => {
+              this.parentNameLoading = false;
+              let list = []
+              response.data.rows.forEach((item,index)=>{
+                if(this.parentId != item.id) {
+                  list.push(item)
+                }
+              })
+              this.parentNameList = [].concat(list);
               this.parentNameLoading = false;
             }
           ).catch ((error)=>{

+ 20 - 11
src/views/distribution/personnelMr/index.vue

@@ -159,20 +159,24 @@
     <el-dialog
       title="推广码"
       :visible.sync="visibleStatus"
-      width="500px"
+      width="400px"
       :destroy-on-close="true"
       :close-on-click-modal="false"
     >
-      <div id="capture" style="width: 400px; height: 500px; position: relative;background-size: cover;background-repeat: no-repeat" :style="{backgroundImage:'url('+newObj.posterImg+')'}">
-        <el-image
-          style="width: 180px; height: 180px; position: absolute; bottom: 0; right: 0;"
-          :src="newObj.url"
-          fit="cover"
-        />
-      </div>
+      <div style="display: flex;justify-content: center;">
+        <div id="capture" style="width: 300px; height: 544px; position: relative;background-size: cover;background-repeat: no-repeat;box-shadow: 0px 0px 20px 2px rgba(221,221,221,0.5);border-radius: 10px;" :style="{backgroundImage:'url('+newObj.posterImg+')'}">
+          <el-image
+            style="width: 80px; height: 80px; position: absolute; bottom: 10px; right: 10px;"
+            :src="newObj.url"
+            fit="fill"
+          />
+        </div>
+      </div>  
+    
       <div slot="footer" class="dialog-footer">
         <el-button @click="visibleStatus = false">取 消</el-button>
-        <el-button type="primary" @click="getShareImgBase64(newObj)">下 载</el-button>
+        <el-button :loading="getShareImgBase64Loading" type="primary" @click="getShareImgBase64(newObj)">
+          {{ getShareImgBase64Loading ? '下载中':'下 载' }}</el-button>
       </div>
     </el-dialog>
 
@@ -271,7 +275,7 @@ export default {
       let regNumber=/^(([1-9]\d*)|([0][.]{1}[0-9]{0,2}[1-9]+)|([1-9]\d*[.]{1}[0-9]+))$/g;
       if (value === '') {
         callback(new Error('请输入数值!!!'));
-      }  else if (value === 0) {
+      }  else if (value == 0) {
         callback();
       } else if (!regNumber.test(value)) {
         callback(new Error('只能输入>=0的数值!!!'));
@@ -332,6 +336,7 @@ export default {
       },
       setRules: [],
       setLoading: false,
+      getShareImgBase64Loading: false,
     };
   },
   created() {
@@ -515,6 +520,7 @@ export default {
     // 推广码 base64
     getShareImgBase64() {
       return new Promise((resolve) => {
+        this.getShareImgBase64Loading = true
         setTimeout(() => {
           // #capture 就是我们要获取截图对应的 DOM 元素选择器
           html2canvas(document.querySelector('#capture'), {
@@ -525,7 +531,10 @@ export default {
             const imgData = canvas.toDataURL('image/jpeg', 1.0);
             this.codeDownload(imgData);
             resolve(imgData);
-          });
+            this.getShareImgBase64Loading = false
+          }).catch(()=>{
+            this.getShareImgBase64Loading = false
+          })
         }, 300); // 这里加上 300ms 的延迟是为了让 DOM 元素完全渲染完成后再进行图片的生成
       });
     },

+ 3 - 3
src/views/distribution/ticketMr/index.vue

@@ -37,17 +37,17 @@
       <el-table-column label="座位类型" align="center" prop="seatTypeName" />
       <el-table-column label="销售价" align="center" prop="brokerageTotal">
         <template slot-scope="scope">
-          <span v-if="scope.row.originalSalePrice">¥{{ scope.row.originalSalePrice }}</span>
+          <span v-if="scope.row.originalSalePrice || scope.row.originalSalePrice==0">¥{{ scope.row.originalSalePrice }}</span>
         </template>
       </el-table-column>
       <el-table-column label="分销价" align="center" prop="withdrawTotal">
         <template slot-scope="scope">
-          <span v-if="scope.row.salePrice">¥{{ scope.row.salePrice }}</span>
+          <span v-if="scope.row.salePrice || scope.row.salePrice==0">¥{{ scope.row.salePrice }}</span>
         </template>
       </el-table-column>
       <el-table-column label="佣金" align="center" prop="withdrawTotal">
         <template slot-scope="scope">
-          <span v-if="scope.row.brokeragePrice">¥{{ scope.row.brokeragePrice }}</span>
+          <span v-if="scope.row.brokeragePrice || scope.row.brokeragePrice==0">¥{{ scope.row.brokeragePrice }}</span>
         </template>
       </el-table-column>
       <el-table-column label="状态" align="center">

+ 3 - 0
src/views/finance/refundMr/dialog/details.vue

@@ -36,6 +36,9 @@
         <el-col :span="24">
           <div class="grid-content bg-purple item-class">状态: <span>{{ statusList[form.status] }}</span></div>
         </el-col>
+        <el-col :span="24" v-if="form.status == 2">
+          <div class="grid-content bg-purple item-class">驳回原因: <span style="color: red;">{{ form.errReason }}</span></div>
+        </el-col>
       </el-row>
     </div>
 

+ 8 - 3
src/views/finance/refundMr/dialog/orderDetails.vue

@@ -45,7 +45,8 @@
           <div class="grid-content bg-purple item-class">场次: <span>{{form.performDate}}   {{ form.performTimeStart }} -- {{ form.performTimeEnd }}</span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">购票渠道: <span>{{ sourceList[form.source] || '' }}</span></div>
+          <!-- <div class="grid-content bg-purple item-class">购票渠道: <span>{{ sourceList[form.source] || '' }}</span></div> -->
+          <div class="grid-content bg-purple item-class" style="display: flex;">购票渠道: <span style="display: block;margin-left: 5px;"><dict-tag :options="dict.type.order_form_type" :value="form.source"/></span></div>
         </el-col>
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">购票数量: <span>{{ form.viewerNum || '' }}</span></div>
@@ -63,10 +64,12 @@
           <div class="grid-content bg-purple item-class">支付时间: <span>{{ form.payTime || '' }}</span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">支付方式: <span>{{ payList[form.payStatus] || '' }}</span></div>
+          <!-- <div class="grid-content bg-purple item-class">支付方式: <span>{{ payList[form.payStatus] || '' }}</span></div> -->
+          <div class="grid-content bg-purple item-class" style="display: flex;">支付方式: <span style="display: block;margin-left: 5px;"><dict-tag :options="dict.type.pay_way_type" :value="form.payWay"/></span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">订单状态: <span>{{ statusList[form.status] || '' }}</span></div>
+          <!-- <div class="grid-content bg-purple item-class">订单状态: <span>{{ statusList[form.status] || '' }}</span></div> -->
+          <div class="grid-content bg-purple item-class" style="display: flex;">订单状态: <span style="display: block;margin-left: 5px;"><dict-tag :options="dict.type.order_status_type" :value="form.status"/></span></div>
         </el-col>
       </el-row>
 
@@ -104,6 +107,7 @@
 import { getSelectById } from '@/api/order/orderMr'
 export default {
   name: "orderDetails",
+  dicts: ['order_form_type','order_status_type','pay_way_type'],
   data() {
     return {
       title: "编辑",
@@ -160,6 +164,7 @@ export default {
       const id = row.orderId
       getSelectById(id).then(response => {
         this.form = response.data;
+
       });
     },
     /**

+ 3 - 2
src/views/finance/refundMr/index.vue

@@ -3,7 +3,7 @@
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="退款单号">
         <el-input
-          v-model="queryParams.refundTransactionId"
+          v-model="queryParams.refundId"
           placeholder="请输入退款单号"
           clearable
           style="width: 240px;"
@@ -211,10 +211,11 @@ export default {
     /** 重置按钮操作 */
     resetQuery() {
       this.dateRange = [];
-      this.$set(this.queryParams, 'refundTransactionId', '');
+      this.$set(this.queryParams, 'refundId', '');
       this.$set(this.queryParams, 'orderId', '');
       this.$set(this.queryParams, 'refundMobile', '');
       this.$set(this.queryParams, 'status', '');
+      this.$set(this.queryParams, 'transactionId', '');
       this.queryParams.pageNum = 1;
       this.handleQuery();
     },

+ 1 - 1
src/views/order/groupBuyingMr/dialog/details.vue

@@ -45,7 +45,7 @@
           <div class="grid-content bg-purple item-class">团购单价: <span v-if="form.price">¥{{ form.price || '' }}/人</span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">预约时间: <span v-if="form.preformStartTime">{{ form.preformStartTime || '' }}</span></div>
+          <div class="grid-content bg-purple item-class">预约时间: <span v-if="form.performDate">{{ form.performDate + "  " || '' }}{{ form.performTimeStart +'  --'  || '' }}{{ form.performTimeEnd || '' }}</span></div>
         </el-col>
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">报名时间: <span>{{ form.applyTime || '' }}</span></div>

+ 150 - 9
src/views/order/groupBuyingMr/index.vue

@@ -3,7 +3,7 @@
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="订单号">
         <el-input
-          v-model="queryParams.orderId"
+          v-model="queryParams.id"
           placeholder="请输入订单号"
           clearable
           style="width: 240px;"
@@ -21,7 +21,7 @@
       </el-form-item>
       <el-form-item label="团队类型">
         <el-select
-        v-model="queryParams.teamType"
+        v-model="queryParams.teamTypeId"
         placeholder="团队类型"
         clearable
         style="width: 240px"
@@ -112,6 +112,12 @@
             @click="openDetails(scope.row)"
             v-hasPermi="['groupBuyingMr:groupBuyingMr:details']"
           >详情</el-button>
+          <el-button
+              size="mini"
+              type="text"
+              @click="handleOpen([scope.row])"
+              v-hasPermi="['orderMr:orderMr:print']"
+            >打印小票</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -127,6 +133,24 @@
     <!-- 详情 -->
     <details-dia ref="detailsDia" :dict="dict" @getList="getList"></details-dia>
 
+
+    <el-dialog
+        title="选择小票机"
+        :visible.sync="dialogVisible"
+        width="30%"
+        :before-close="handleClose">
+        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
+          <el-form-item label="小票机" prop="region">
+            <el-select v-model="ruleForm.region" placeholder="选择小票机">
+              <el-option :label="item.deviceName" :key="item.id" :value="item.id" v-for="(item,index) in printList"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <span slot="footer" class="dialog-footer">
+          <el-button @click="dialogVisible = false">取 消</el-button>
+          <el-button type="primary" :loading="dialogVisibleLoading" @click="print(viewerList)">{{ dialogVisibleLoading?'打印中...':'打印' }}</el-button>
+        </span>
+      </el-dialog>
   </div>
 </template>
 
@@ -135,6 +159,11 @@
 import { pageList } from '@/api/order/groupBuyingMr'
 import detailsDia from "./dialog/details.vue";
 
+import { printApi } from '@/api/order/orderMr'
+import { pageList as getPrintListApi } from "@/api/device/pda";
+
+const https = require('https');
+const axios = require('axios');
 export default {
   name: "agreement",
   dicts: ['agreement_type', 'team_type'],
@@ -219,7 +248,19 @@ export default {
       ],
       visibleStatus: false,
       newObj: {},
-      visibleType: ''
+      visibleType: '',
+
+
+      viewerList: [],
+        printList: [],
+        dialogVisible: false,
+        ruleForm: {},
+        rules: {
+          region: [
+            { required: true, message: '请选择打印机', trigger: ['change','blur' ]}
+          ],
+        },
+        dialogVisibleLoading: false,
     };
   },
   created() {
@@ -244,21 +285,21 @@ export default {
     handleQuery() {
       this.queryParams.pageNum = 1;
       if(this.queryParams.time){
-        this.queryParams.payBeginTime = this.queryParams.time[0];
-        this.queryParams.payEndTime = this.queryParams.time[1];
+        this.queryParams.beginTime = this.queryParams.time[0];
+        this.queryParams.endTime = this.queryParams.time[1];
       }
       this.getList();
     },
     /** 重置按钮操作 */
     resetQuery() {
       this.dateRange = [];
-      this.$set(this.queryParams, 'orderId', '');
+      this.$set(this.queryParams, 'id', '');
       this.$set(this.queryParams, 'status', '');
-      this.$set(this.queryParams, 'teamType', '');
+      this.$set(this.queryParams, 'teamTypeId', '');
       this.$set(this.queryParams, 'teamName', '');
       this.$set(this.queryParams, 'performName', '');
-      this.$set(this.queryParams, 'payBeginTime', '');
-      this.$set(this.queryParams, 'payEndTime', '');
+      this.$set(this.queryParams, 'beginTime', '');
+      this.$set(this.queryParams, 'endTime', '');
       this.$set(this.queryParams, 'time', '');
       this.queryParams.pageNum = 1;
       this.handleQuery();
@@ -267,6 +308,106 @@ export default {
     openDetails(row, type) {
       this.$refs["detailsDia"].openDialog("详情", row, type);
     },
+    handleOpen(list=[]){
+          if(!list||list.length==0) return
+          let idList = []
+          list.forEach((item,index)=>{
+            idList.push(item.id)
+          }) 
+          this.viewerList = idList
+          this.getPrintListApi()
+          this.$set(this.ruleForm, 'region', '');
+          this.$nextTick(()=>{
+            this.$refs.ruleForm.clearValidate('region')
+          })
+          this.dialogVisible = true
+        },
+        handleClose(){
+          this.dialogVisible = false
+        },
+        /** 查询打印机列表 */
+        getPrintListApi() {
+          getPrintListApi({deviceType:5,pageNum: 1,
+          pageSize: 999,})
+          .then(response => {
+              this.printList = response.data.rows;
+            }
+          );
+        },
+        /**  选择打印机  */
+        selectPrint(){
+
+        },
+        // 打印 
+        async print(list = []){
+          this.$refs.ruleForm.validate(async (valid) => {
+            if (valid) {
+              this.dialogVisibleLoading = true
+              try {
+                let res = await printApi({
+                  //viewerList:list,
+                  orderId: list[0],
+                  source: 2,
+                  deviceId: this.ruleForm.region
+                })
+                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.dialogVisible = false
+                this.dialogVisibleLoading = false
+                console.error("error=====",error)
+              }
+            } else {
+              console.log('error submit!!');
+              return false;
+            }
+          });
+          
+        },
+        /**  连接打印机  */
+        connectPrint(url,data){
+          // let xhr = new XMLHttpRequest();
+          // xhr.onreadystatechange = ()=>{
+          // if(xhr.readyState == 4){ // 监听请求完成
+          //     if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){
+          //       console.log(xhr.responseText)
+          //       this.dialogVisible = false
+          //       this.dialogVisibleLoading = false
+          //     }else{
+          //       console.log('请求失败')
+          //       this.dialogVisible = false
+          //       this.dialogVisibleLoading = false
+          //     }
+          //   }
+          // }
+          // xhr.open("post", url, true); // 异步请求
+          // xhr.send(JSON.stringify(data));
+
+          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.dialogVisibleLoading = false
+          }).catch(()=>{
+            this.dialogVisible = false
+            this.dialogVisibleLoading = false
+          })
+        }
   }
 };
 </script>

+ 6 - 36
src/views/order/orderMr/dialog/details.vue

@@ -63,10 +63,10 @@
           <div class="grid-content bg-purple item-class">支付时间: <span>{{ form.payTime || '' }}</span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">支付方式: <span>{{ payWayList[form.payWay] || '' }}</span></div>
+          <div class="grid-content bg-purple item-class" style="display: flex;">支付方式: <span style="display: block;margin-left: 5px;"><dict-tag :options="dict.type.pay_way_type" :value="form.payWay"/></span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">订单状态: <span>{{ statusList[form.status] || '' }}</span></div>
+          <div class="grid-content bg-purple item-class" style="display: flex;">订单状态: <span style="display: block;margin-left: 5px;"><dict-tag :options="dict.type.order_status_type" :value="form.status"/></span></div>
         </el-col>
       </el-row>
 
@@ -104,7 +104,7 @@
 import { getSelectById } from '@/api/order/orderMr'
 export default {
   name: "detailsDia",
-  dicts: ['order_form_type'],
+  dicts: ['order_form_type','order_status_type','pay_way_type'],
   data() {
     return {
       title: "编辑",
@@ -117,38 +117,6 @@ export default {
       performerVisible: false,
       performerList: [],
       refund: false,
-      statusList: {
-        0: '待支付',
-        2: '超时取消',
-        3: '待使用',
-        4: '退款中',
-        5: '己退款',
-        6: '退款失败',
-        7: '己使用',
-        8: '己超期',
-        9: '关闭',
-      },
-      payList: {
-        0: '未支付',
-        1: '已支付',
-        2: '支付中',
-        3: '支付失败',
-        4: '支付退款',
-      },
-      payWayList: {
-        'cahsh': '现金',
-        'wecaht.applet': '微信小程序支付',
-        'alipay': '支付宝OTA',
-        'wecaht.h5': '微信公众号支付',
-        'meituan': '美团支付',
-      },
-      sourceList: {
-        1: '小程序',
-        2: '公众号',
-        3: '美团',
-        4: '携程',
-        5: '团购',
-      },
       dataList: []
     };
   },
@@ -161,13 +129,15 @@ export default {
      */
     openDialog(title, obj, type) {
       this.open = true;
+      this.form = {}
       this.getSelectByIdApi(obj);
     },
     /** 获取详情 */
     getSelectByIdApi(row) {
       const id = row.id
       getSelectById(id).then(response => {
-        this.form = response.data;
+        this.$set(this,"form",response.data)
+        //this.form = response.data;
       });
     },
     /**

+ 156 - 51
src/views/order/orderMr/index.vue

@@ -44,12 +44,12 @@
           clearable
           style="width: 100%"
         >
-          <el-option
-            v-for="dict in statusMapList"
-            :key="dict.value"
-            :label="dict.name"
-            :value="dict.value"
-          />
+            <el-option
+              v-for="dict in dict.type.order_status_type"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
         </el-select>
       </el-form-item>
       <el-form-item label="购票渠道">
@@ -148,7 +148,7 @@
       <el-table-column label="剧目名称" align="center" prop="performName" />
       <el-table-column label="票务名称" align="center" prop="goodsName" />
       <el-table-column label="票务类型" align="center" prop="seatTypeName" />
-      <el-table-column label="购票渠道" align="center" prop="type">
+      <el-table-column label="购票渠道" align="center" prop="source">
         <template slot-scope="scope">
           <!-- <span>{{ sourceList[scope.row.source] }}</span> -->
           <dict-tag :options="dict.type.order_form_type" :value="scope.row.source"/>
@@ -164,9 +164,9 @@
         </template>
       </el-table-column>
 <!--      <el-table-column label="优惠信息" align="center" prop="refundReason" />-->
-      <el-table-column label="支付方式" align="center" prop="type">
+      <el-table-column label="支付方式" align="center" prop="payWay">
         <template slot-scope="scope">
-          <span>{{ payWayList[scope.row.payWay] }}</span>
+          <dict-tag :options="dict.type.pay_way_type" :value="scope.row.payWay"/>
         </template>
       </el-table-column>
       
@@ -175,12 +175,12 @@
           <span>{{ parseTime(scope.row.payTime) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="订单状态" align="center" prop="type">
+      <el-table-column label="订单状态" align="center" prop="status">
         <template slot-scope="scope">
-          <span>{{statusList[scope.row.status]}}</span>
+          <dict-tag :options="dict.type.order_status_type" :value="scope.row.status"/>
         </template>
       </el-table-column>
-      <el-table-column label="已核销票数" align="center" prop="type">
+      <el-table-column label="已核销票数" align="center" prop="usedTotal">
         <template slot-scope="scope">
           <span>{{ scope.row.usedTotal }}</span>
         </template>
@@ -193,6 +193,12 @@
             @click="openDetails(scope.row)"
             v-hasPermi="['orderMr:orderMr:details']"
           >详情</el-button>
+          <el-button
+              size="mini"
+              type="text"
+              @click="handleOpen([scope.row])"
+              v-hasPermi="['orderMr:orderMr:print']"
+            >打印小票</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -208,18 +214,38 @@
     <!-- 详情 -->
     <details-dia ref="detailsDia" @getList="getList"></details-dia>
 
+    <el-dialog
+        title="选择小票机"
+        :visible.sync="dialogVisible"
+        width="30%"
+        :before-close="handleClose">
+        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
+          <el-form-item label="小票机" prop="region">
+            <el-select v-model="ruleForm.region" placeholder="选择小票机">
+              <el-option :label="item.deviceName" :key="item.id" :value="item.id" v-for="(item,index) in printList"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <span slot="footer" class="dialog-footer">
+          <el-button @click="dialogVisible = false">取 消</el-button>
+          <el-button type="primary" :loading="dialogVisibleLoading" @click="print(viewerList)">{{ dialogVisibleLoading?'打印中...':'打印' }}</el-button>
+        </span>
+      </el-dialog>
   </div>
 </template>
 
 <script>
 
-import { pageList,downOrderListXls } from '@/api/order/orderMr'
-import detailsDia from "./dialog/details.vue";
+import { pageList,downOrderListXls, printApi } from '@/api/order/orderMr'
+import detailsDia from "./dialog/details";
 import { pagePerformTimeList } from "@/api/schedulingMr/schedulingMr"
 import { exportExcel } from '@/utils/exportexcel'
+import { pageList as getPrintListApi } from "@/api/device/pda";
+const https = require('https');
+const axios = require('axios');
 export default {
   name: "agreement",
-  dicts: ['order_form_type'],
+  dicts: ['order_form_type','order_status_type','pay_way_type'],
   components: { detailsDia },
   data() {
     return {
@@ -249,42 +275,6 @@ export default {
         pageNum: 1,
         pageSize: 10,
       },
-      statusList: {
-        0: '待支付',
-        2: '超时取消',
-        3: '待使用',
-        4: '退款中',
-        5: '己退款',
-        6: '退款失败',
-        7: '己使用',
-        8: '己超期',
-        9: '关闭',
-      },
-      statusMapList: [
-        {id: 1, name: '待支付', value: 0},
-        {id: 2, name: '超时取消', value: 2},
-        {id: 3, name: '待使用', value: 3},
-        {id: 4, name: '退款中', value: 4},
-        {id: 5, name: '己退款', value: 5},
-        {id: 6, name: '退款失败', value: 6},
-        {id: 7, name: '己使用', value: 7},
-        {id: 8, name: '己超期', value: 8},
-        {id: 9, name: '关闭', value: 9},
-      ],
-      payList: {
-        0: '未支付',
-        1: '已支付',
-        2: '支付中',
-        3: '支付失败',
-        4: '支付退款',
-      },
-      payWayList: {
-        'cahsh': '现金',
-        'wecaht.applet': '微信小程序支付',
-        'alipay': '支付宝OTA',
-        'wecaht.h5': '微信公众号支付',
-        'meituan': '美团支付',
-      },
       visibleStatus: false,
       newObj: {},
       visibleType: '',
@@ -292,6 +282,17 @@ export default {
       pagePerformTimeList: [], // 场次列表
 
       handleExportLoading: false,
+
+      viewerList: [],
+        printList: [],
+        dialogVisible: false,
+        ruleForm: {},
+        rules: {
+          region: [
+            { required: true, message: '请选择打印机', trigger: ['change','blur' ]}
+          ],
+        },
+        dialogVisibleLoading: false,
     };
   },
   created() {
@@ -342,6 +343,7 @@ export default {
       this.$set(this.queryParams, 'goodsName', '');
       this.$set(this.queryParams, 'performDate', '');
       this.$set(this.queryParams, 'timeSnapshot', '');
+      this.$set(this.queryParams, 'performTimeId', '');
       this.queryParams.pageNum = 1;
       this.handleQuery();
     },
@@ -401,6 +403,109 @@ export default {
           this.$message.info('您已取消导出!');
         });
     },
+    
+
+    handleOpen(list=[]){
+          if(!list||list.length==0) return
+          let idList = []
+          list.forEach((item,index)=>{
+            idList.push(item.id)
+          }) 
+          this.viewerList = idList
+          this.getPrintListApi()
+          this.$set(this.ruleForm, 'region', '');
+          this.$nextTick(()=>{
+            this.$refs.ruleForm.clearValidate('region')
+          })
+          this.dialogVisible = true
+        },
+        handleClose(){
+          this.dialogVisible = false
+        },
+        /** 查询打印机列表 */
+        getPrintListApi() {
+          getPrintListApi({deviceType:5,pageNum: 1,
+          pageSize: 999,})
+          .then(response => {
+              this.printList = response.data.rows;
+            }
+          );
+        },
+        /**  选择打印机  */
+        selectPrint(){
+
+        },
+        // 打印 
+        async print(list = []){
+          this.$refs.ruleForm.validate(async (valid) => {
+            if (valid) {
+              this.dialogVisibleLoading = true
+              try {
+                let res = await printApi({
+                  //viewerList:list,
+                  orderId: list[0],
+                  source: 2,
+                  deviceId: this.ruleForm.region
+                })
+                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.dialogVisible = false
+                this.dialogVisibleLoading = false
+                console.error("error=====",error)
+              }
+            } else {
+              console.log('error submit!!');
+              return false;
+            }
+          });
+          
+        },
+        /**  连接打印机  */
+        connectPrint(url,data){
+          // let xhr = new XMLHttpRequest();
+          // xhr.onreadystatechange = ()=>{
+          // if(xhr.readyState == 4){ // 监听请求完成
+          //     if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){
+          //       console.log(xhr.responseText)
+          //       this.dialogVisible = false
+          //       this.dialogVisibleLoading = false
+          //     }else{
+          //       console.log('请求失败')
+          //       this.dialogVisible = false
+          //       this.dialogVisibleLoading = false
+          //     }
+          //   }
+          // }
+          // xhr.open("post", url, true); // 异步请求
+          // xhr.send(JSON.stringify(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.dialogVisibleLoading = false
+          }).catch(()=>{
+            this.dialogVisible = false
+            this.dialogVisibleLoading = false
+          })
+
+        }
   }
 };
 </script>

+ 2 - 2
src/views/order/writeOffMr/index.vue

@@ -19,10 +19,10 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="核销剧目类型">
+      <el-form-item label="核销设备类型">
         <el-select
           v-model="queryParams.deviceType"
-          placeholder="核销剧目类型"
+          placeholder="核销设备类型"
           clearable
           style="width: 100%;"
         >

+ 1 - 1
src/views/otaMr/dialog/dataEdit.vue

@@ -160,7 +160,7 @@ export default {
           this.$set(this.form, 'seatTypeId', obj.seatTypeId);
           this.$set(this.form, 'performId', obj.performId);
           this.$set(this.form, 'auditoriumId', obj.auditoriumId);
-          this.$set(this.form, 'priceType', obj.priceType.toString());
+          this.$set(this.form, 'priceType', obj.priceType ? obj.priceType.toString():obj.priceType);
           this.$set(this.form, 'priceAmount', obj.priceAmount);
         });
       }else{

+ 2 - 2
src/views/statistics/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
+    <!-- <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
       <el-form-item label="报表名称">
         <el-input
           v-model="queryParams.name"
@@ -14,7 +14,7 @@
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
-    </el-form>
+    </el-form> -->
 
     <div class="box-class clearfix">
       <div class="item-class clearfix" @click="pageLink(item.url)" v-for="item in itemList" :key="item.id">

+ 6 - 8
src/views/system/selfServeAdvertis/index.vue

@@ -30,13 +30,13 @@
           <span>{{ scope.row.type == 1 ? '图文' : scope.row.type == 2 ? '视频' : '链接' }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="状态" align="center">
+      <!-- <el-table-column label="状态" align="center">
         <template slot-scope="scope">
           <el-tag type="success" v-if="scope.row.onlineStatus == '1'">己上线</el-tag>
           <el-tag type="danger" v-else-if="scope.row.onlineStatus == '0'">未上线</el-tag>
           <el-tag type="info" v-else>未发布</el-tag>
         </template>
-      </el-table-column>
+      </el-table-column> -->
       <el-table-column label="创建时间" align="center" prop="createTime" width="160">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime) }}</span>
@@ -44,12 +44,12 @@
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
-          <el-button
+          <!-- <el-button
             size="mini"
             type="text"
             @click="ionlineApi(scope.row)"
             v-hasPermi="['system:selfServeAdvertis:release']"
-          >{{scope.row.onlineStatus == '1' ? '取消发布' : '发布'}}</el-button>
+          >{{scope.row.onlineStatus == '1' ? '取消发布' : '发布'}}</el-button> -->
           <el-button
             size="mini"
             type="text"
@@ -59,14 +59,12 @@
           <el-button
             size="mini"
             type="text"
-            v-if="scope.row.onlineStatus != '1'"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['system:selfServeAdvertis:edit']"
           >编辑</el-button>
           <el-button
             size="mini"
             type="text"
-            v-if="scope.row.onlineStatus != '1'"
             @click="handleDelete(scope.row,scope.index)"
             v-hasPermi="['system:selfServeAdvertis:delete']"
           >删除</el-button>
@@ -176,8 +174,8 @@ export default {
     /** 删除按钮操作 */
     handleDelete(row) {
       const dataIds = row.id || this.ids;
-      this.$modal.confirm('是否确认删除数据编号为"' + dataIds + '"的数据项?').then(function() {
-        return deleteById(userIds);
+      this.$modal.confirm('是否确认删除标题名称为"' + row.name + '"的数据项?').then(function() {
+        return deleteById(row.id);
       }).then(() => {
         this.getList();
         this.$modal.msgSuccess("删除成功");

+ 13 - 2
src/views/team/applicationMr/dialog/applicationDetails.vue

@@ -45,7 +45,7 @@
           <div class="grid-content bg-purple item-class">团购单价: <span>¥{{ details.price || '' }}</span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">预约时间: <span>{{ details.performDate || '' }}日 {{ details.performTimeStart || '' }} {{ details.performTimeEnd || '' }}</span></div>
+          <div class="grid-content bg-purple item-class">预约时间: <span>{{ details.performDate || '' }}日 {{ details.performTimeStart +'  --' || '' }} {{ details.performTimeEnd || '' }}</span></div>
         </el-col>
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">报名时间: <span>{{ details.createTime || '' }}</span></div>
@@ -56,6 +56,9 @@
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">联系电话: <span>{{ details.teamMobile || '' }}</span></div>
         </el-col>
+        <el-col :span="12" v-if="details.errReason">
+          <div class="grid-content bg-purple item-class">驳回原因: <span style="color: red;">{{ details.errReason || '' }}</span></div>
+        </el-col>
       </el-row>
 
 
@@ -78,7 +81,7 @@
 
     <span slot="footer" class="dialog-footer" v-if="detailsType">
       <el-button type="primary" @click="passOpenEven" style="margin-right: 20px">通过</el-button>
-       <el-button type="danger" @click="rejectOpen = true" >驳回</el-button>
+       <el-button type="danger" @click="setRejectOpen" >驳回</el-button>
     </span>
 
 
@@ -226,6 +229,7 @@ export default {
     getSelectByIdApi(row) {
       const id = row.id
       getSelectById(id).then(response => {
+        this.details = {}
         this.details = response.data;
       });
     },
@@ -355,6 +359,13 @@ export default {
     cancel() {
       this.open = false;
     },
+    setRejectOpen() {
+      this.rejectOpen = true
+      this.$set(this.rejectForm,'errReason','')
+      this.$nextTick(()=>{
+        this.$refs.refRejectForm.clearValidate('errReason')
+      })
+    }
   },
 };
 </script>

+ 5 - 1
src/views/team/applicationMr/dialog/orderDetails.vue

@@ -45,7 +45,7 @@
           <div class="grid-content bg-purple item-class">团购单价: <span v-if="form.price">¥{{ form.price || '' }}/人</span></div>
         </el-col>
         <el-col :span="12">
-          <div class="grid-content bg-purple item-class">预约时间: <span>{{ form.performDate || '' }} {{ form.performTimeStart || '' }}--{{ form.performTimeEnd || '' }}</span></div>
+          <div class="grid-content bg-purple item-class">预约时间: <span>{{ form.performDate || '' }} {{ form.performTimeStart +'  --'  || '' }}{{ form.performTimeEnd || '' }}</span></div>
         </el-col>
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">报名时间: <span>{{ form.createTime || '' }}</span></div>
@@ -56,6 +56,9 @@
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">联系电话: <span>{{ form.teamMobile || '' }}</span></div>
         </el-col>
+        <el-col :span="12" v-if="form.errReason">
+          <div class="grid-content bg-purple item-class">驳回原因: <span  style="color: red;">{{ form.errReason || '' }}</span></div>
+        </el-col>
 <!--        <el-col :span="12">-->
 <!--          <div class="grid-content bg-purple item-class">支付总额: <span>¥{{ form.priceTotal || '' }}</span></div>-->
 <!--        </el-col>-->
@@ -168,6 +171,7 @@ export default {
     getSelectByIdApi(row) {
       const id = row.id
       getOrderDetail(id).then(response => {
+        this.form = {}
         this.form = response.data;
       });
     },

+ 3 - 3
src/views/team/ticketMr/index.vue

@@ -37,12 +37,12 @@
       <el-table-column label="座位类型" align="center" prop="seatTypeName" />
       <el-table-column label="销售价" align="center" prop="brokerageTotal">
         <template slot-scope="scope">
-          <span v-if="scope.row.originalSalePrice">¥{{ scope.row.originalSalePrice }}</span>
+          <span v-if="scope.row.originalSalePrice || scope.row.originalSalePrice==0">¥{{ scope.row.originalSalePrice }}</span>
         </template>
       </el-table-column>
       <el-table-column label="团购单价" align="center" prop="withdrawTotal">
         <template slot-scope="scope">
-          <span v-if="scope.row.salePrice">¥{{ scope.row.salePrice }}</span>
+          <span v-if="scope.row.salePrice || scope.row.salePrice==0">¥{{ scope.row.salePrice }}</span>
         </template>
       </el-table-column>
       <el-table-column label="成团人数" align="center" prop="teamPersonNum" />
@@ -132,7 +132,7 @@
 
 import { pageList, deleteById, updateStatus } from '@/api/team/ticketMr'
 import addAndEdit from "./dialog/addAndEdit.vue";
-import dumplingEdit from "./dialog/dumplingEdit.vue";
+import dumplingEdit from "./dialog/dumplingEdit";
 export default {
   name: "agreement",
   dicts: ['distribution_type', 'team_type'],

+ 267 - 0
src/views/ticket/ticketMr/dialog/FreightMgrIndexMi.js

@@ -0,0 +1,267 @@
+import { basePositionApi } from '@/api/ticketMr/ticketMr'
+export default {
+    data() {
+        return {
+            selectDeliveryAreaDialogList:[], // 全部数据
+            selectDeliveryAreaDialogOpen: false, // 是否显示弹窗
+            selectDeliveryAreaDialogTitle: '可售区域',
+
+            selectCityListLoading: false,
+
+            provinceIndex: -1,
+            initSelectData: {} // 回显载体
+        }
+    },
+    created() {
+        
+    },
+    methods: {
+        handleChangeProvince(){
+            
+        },
+        /**
+         * 打开 可售区域配置
+         */
+        deliverableAreaDialogCancel(data) {
+            let obj = {}
+            
+            this.selectCityListLoading = false
+
+            this.provinceIndex = -1
+            this.initSelectData = {}
+
+            if(data && data.length>0) {
+                data.forEach((item,index)=>{
+                    let list = item.split('-')
+                    if(obj[list[0]] && list[1]){
+                        obj[list[0]].push([list[1]])
+                    }else {
+                        obj[list[0]] = []
+                        if(list[1]){
+                            obj[list[0]].push([list[1]])
+                        }
+                    }
+                })
+            }
+            console.log('obj====',data,obj)
+            this.initSelectData = obj
+            this.selectDeliveryAreaDialogOpen = true;
+            this.basePositionFun("#")
+        },
+        /** 关闭弹窗  */
+        selectDeliveryAreaDialogCancel(){
+            this.selectDeliveryAreaDialogOpe = false;
+        },
+        /**  确认弹窗  */
+        selectDeliveryAreaDialogSubmitForm(){
+            let list = []
+            this.selectDeliveryAreaDialogList.forEach((item)=>{
+                if(item.selected){
+                    list.push(item.name)
+                }else if(item.selectCityList && item.selectCityList.length>0) {
+                    item.selectCityList.forEach((item1,index1)=>{
+                        console.log("item1===",item1)
+                        list.push(item.name+'-'+item1.join('-'))
+                    })
+                    
+                }
+            })
+            this.form.saleArea = list
+            this.selectDeliveryAreaDialogOpen = false
+            console.log("list====",list)
+        },
+        /**  初次获取行政区划  */
+        async basePositionFun(upCode) {
+            try {
+                this.selectCityListLoading = true
+                let res = await basePositionApi({
+                    upCode,
+                })
+                if(res.code == 200) {
+                    let list = []
+                    let listApi = []
+                    res.data.forEach((item,index) => {
+                        if(item.code!='#') {
+                            list.push({
+                                ...item,
+                                countyList: [],
+                                selected: this.initChekeSelectAll(item),
+                                selectCityList: this.initSelectData[item.name] ?this.initSelectData[item.name] : [] ,
+                                cityList: []
+                            })
+                            listApi.push(basePositionApi({
+                                upCode: item.code?item.code : '#',
+                            }))
+                        }
+                        
+                    });
+                    let res1 = await Promise.all(listApi)
+                    if(res1) {
+                        res1.forEach((item,index)=>{
+                            let list1 = []
+                            item.data.forEach((item1,index1)=>{
+                                list1.push({
+                                    ...item1,
+                                    //countyList: [],
+                                    //leaf: true,
+                                })
+                            })
+                            list[index].cityList = [].concat(list1)
+                        })
+                    }
+                    
+                    this.selectDeliveryAreaDialogList = [].concat(list)
+                    console.log("res1=====",res1,this.selectDeliveryAreaDialogList)
+                }
+                this.selectCityListLoading = false
+            } catch (error) {
+                console.error("error====",error)
+                this.selectCityListLoading = false
+            }
+        },
+         /**  懒加载 配置   */
+        areaCascaderProps(areaItem, areaIndex) {
+            return {
+              lazy: false,
+              lazyLoad: (node, resolve) => this.areaLazyLoad(node, resolve, areaItem, areaIndex),
+              multiple: true,
+              children: 'countyList',
+              label: 'name',
+              value: 'name',
+              expandTrigger: 'hover',
+              // emitPath: false,
+            };
+        },
+        /**  懒加载 函数   */
+        areaLazyLoad(node, resolve, areaItem, provinceIndex) {
+            const { level } = node;
+            // console.log(node, resolve, areaItem, provinceIndex)
+            if (level === 0) {
+              resolve([])
+            } else if(level == 1 ) {
+                console.log(node, resolve, areaItem, provinceIndex)
+                if(node.data && node.data.code){
+                    if(node.data.countyList) {
+                        let list = []
+                        node.data.countyList.forEach((item,index)=>{
+                            list.push({
+                                ...item,
+                                leaf: true,
+                            })
+                        })
+                        resolve(list)
+                    }
+                    // basePositionApi({
+                    //     upCode: node.data.code,
+                    // }).then((res)=>{
+                    //     let list = []
+                    //     res.data.forEach((item,index)=>{
+                    //         list.push({
+                    //             ...item,
+                    //             leaf: true,
+                    //         })
+                    //     })
+                    //     resolve(list)
+                    // })
+                }else {
+                    resolve([])
+                }   
+            }else {
+                resolve([])
+            }
+        },
+        // 当选中节点变化时触发
+        changeCascader(data){
+            console.log("data===",data)
+           // console.log('selectDeliveryAreaDialogList====',this.selectDeliveryAreaDialogList)
+            this.chekeSelectAll(this.provinceIndex)
+        },
+        // 下拉框出现/隐藏时触发
+        async handleCascaderVisibleChangeCity(isVisible, areaItem, provinceIndex){
+            this.provinceIndex = provinceIndex
+            if (isVisible) {
+                const loading = this.$loading({
+                    lock: true,
+                    text: 'Loading',
+                    spinner: 'el-icon-loading',
+                    background: 'rgba(0, 0, 0, 0.7)',
+                    customClass: 'custom-class-box'
+                });
+                try {
+                    console.log('this.selectDeliveryAreaDialogList1111====',this.selectDeliveryAreaDialogList)
+                    if(false && isVisible && this.selectDeliveryAreaDialogList[provinceIndex].cityList[0].countyList.length==0){
+                        
+                        console.log(isVisible, areaItem, provinceIndex)
+    
+                        let listApi = []
+                        areaItem.cityList.forEach((item,index)=>{
+                            listApi.push(basePositionApi({
+                                upCode: item.code?item.code : '#',
+                            }))
+                        })
+                        let res1 = await Promise.all(listApi)
+                        console.log("res1====",res1)
+                        if(res1) {
+                            res1.forEach((item,index)=>{
+                                this.$set(this.selectDeliveryAreaDialogList[provinceIndex].cityList[index],'countyList',item.data)
+                            })
+                        }
+                    }
+                    loading.close();
+                    if(isVisible && areaItem.selected){
+                        this.$nextTick(()=>{
+                            // let list = [['市辖区']]
+                            // this.$set(this.selectDeliveryAreaDialogList[provinceIndex],'selectCityList',list)
+                            // console.log('this.selectDeliveryAreaDialogList1111====',this.selectDeliveryAreaDialogList)
+                            this.setSelectAll(isVisible, areaItem, provinceIndex)
+                        })
+                        
+                    }
+                } catch (error) {
+                    loading.close();
+                    console.error("error=====",error)
+                }
+            }
+           
+            
+        },
+        /**  全选状态  */
+        setSelectAll(isVisible, areaItem, provinceIndex){
+            this.$nextTick(()=>{
+                let list = []
+                this.selectDeliveryAreaDialogList[provinceIndex].cityList.forEach((item,index)=>{
+                    if(item.countyList && item.countyList.length > 0) {
+                        item.countyList.forEach((item1,index1)=>{
+                            list.push([item.name,item1.name])
+                        })
+                    }else {
+                        list.push([item.name])
+                    }
+                })
+                this.$set(this.selectDeliveryAreaDialogList[provinceIndex],'selectCityList',list)
+                //console.log('this.selectDeliveryAreaDialogList1111====',this.selectDeliveryAreaDialogList)
+            })
+        },
+        /** 点击选中时 判断是否全选  */
+        chekeSelectAll(provinceIndex){
+            let flog = true
+            this.selectDeliveryAreaDialogList[provinceIndex].cityList.forEach((item,index)=>{
+                if(this.selectDeliveryAreaDialogList[provinceIndex].selectCityList.every((currentValue)=> !currentValue.includes(item.name)) ) {
+                    flog = false
+                }
+            })
+            this.selectDeliveryAreaDialogList[provinceIndex].selected = flog
+            console.log("provinceIndex====",provinceIndex)
+            console.log("flog====",flog)
+            console.log('this.selectDeliveryAreaDialogList1111====',this.selectDeliveryAreaDialogList)
+        },
+        /** 点击选中时 判断是否全选  */
+        initChekeSelectAll(item){
+            if(this.initSelectData[item.name] && this.initSelectData[item.name].length == 0) {
+                return true
+            }else {
+                return false
+            }
+        },
+    }
+}

+ 161 - 1
src/views/ticket/ticketMr/dialog/addAndEdit.vue

@@ -31,6 +31,18 @@
             <el-form-item label="实名信息:" prop="isAuth">
               <el-radio v-model="form.isAuth" label="1">全部观影人员均实名</el-radio>
             </el-form-item>
+            <el-form-item label="停止售卖时间:" prop="stopSaleTime">
+              <span style="margin-right: 5px">开演前</span>
+              <el-input
+                v-model="form.stopSaleTime"
+                type="number"
+                placeholder="停止售卖时间"
+                clearable
+                style="width: 180px;"
+              >
+              </el-input>
+              <span style="margin-left: 5px">分钟内<i style="font-size: 12px;margin-left: 5px;">注:必须大于核销时间至少30秒</i></span>
+            </el-form-item>
             <el-form-item label="核销时间:" prop="beforeTime">
               <span style="margin-right: 5px">开演前</span>
               <el-input
@@ -99,6 +111,17 @@
             <el-form-item label="售票渠道:" required label-width="100px">
               <el-checkbox v-model="form.channelWx">小程序</el-checkbox>
               <el-checkbox v-model="form.channelWindow">窗口</el-checkbox>
+              <el-checkbox v-model="form.channelAutoSale">自助售/取票机</el-checkbox>
+            </el-form-item>
+            <el-form-item label="可售区域:" label-width="100px">
+              <span @click="deliverableAreaDialogCancel(form.saleArea)" style="cursor: pointer;color: #1890ff;">请选择(点击这里进行选择)</span>
+              <span style="margin-left: 10px;color: red;cursor: pointer;" @click="form.saleArea=''">全部清除</span>
+              <div style="width: 100%;height: 100px;overflow: hidden;overflow-y: auto;background-color: #ccc;padding: 5px;box-sizing: border-box;border-radius: 10px;">
+                <div v-if="form.saleArea">
+                  <el-tag :key="index" v-for="(item,index) in form.saleArea" >{{ item }}</el-tag>
+                </div>
+                
+              </div>
             </el-form-item>
           </el-tab-pane>
 
@@ -147,6 +170,63 @@
         <span v-else>保存</span>
       </el-button>
     </span>
+    <!-- 选择配送区域对话框 Start -->
+    <el-dialog
+        :visible.sync="selectDeliveryAreaDialogOpen"
+        :title="selectDeliveryAreaDialogTitle"
+        width="60%"
+        append-to-body
+        class="delivery-area-dialog"
+        @close="selectDeliveryAreaDialogCancel"
+      >
+        <div class="area-container" 
+        v-loading="selectCityListLoading"
+        element-loading-text="加载数据中..."
+        >
+          <el-row>
+            <el-col
+              v-for="(areaItem, areaIndex) in selectDeliveryAreaDialogList"
+              :key="areaItem.areaCode"
+              class="area-wrap"
+              :span="8"
+            >
+              <el-checkbox
+                v-model="areaItem.selected"
+                :label="areaItem.name"
+                class="area-wrap-province"
+                @change="handleChangeProvince(areaIndex, areaItem)"
+              >
+                <template #default>
+                  <span
+                    slot="reference"
+                      :class="areaItem.hasChildrenSelect ? 'area-province-label' : ''"
+                    >{{ areaItem.name }}</span>
+                  
+                </template>
+              </el-checkbox>
+              <el-cascader
+                v-model="areaItem.selectCityList"
+                :options="areaItem.cityList"
+                :props="areaCascaderProps(areaItem, areaIndex)"
+                :clearable="false"
+                collapse-tags
+                class="area-wrap-city"
+                popper-class="area-city-popper"
+                @visible-change="(isVisible)=>handleCascaderVisibleChangeCity(isVisible, areaItem, areaIndex)"
+                @change="changeCascader"
+              />
+            </el-col>
+          </el-row>
+        </div>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="selectDeliveryAreaDialogCancel">取 消</el-button>
+            <el-button type="primary" @click="selectDeliveryAreaDialogSubmitForm">确 定</el-button>
+          </div>
+        </template>
+      </el-dialog>
+      <!-- 选择配送区域对话框 End -->
+    <!-- 添加或修改对话框 End -->
   </el-dialog>
 </template>
 
@@ -155,9 +235,23 @@
 import { saveAndEdit, getSelectById } from '@/api/ticketMr/ticketMr'
 import { getToken } from "@/utils/auth";
 import { pageList } from '@/api/performMr/performMr'
+import FreightMgrIndexMi from "./FreightMgrIndexMi"
 export default {
   name: "addAndEdit",
+  mixins: [FreightMgrIndexMi],
   data() {
+    let validateNumber = (rule, value, callback) => {
+      let regNumber=/^(([1-9]\d*)|([0][.]{1}[0-9]{0,2}[0-9]+)|([1-9]\d*[.]{1}[0-9]+))$/g;
+      if (value === '') {
+        callback(new Error('请输入大于等于0的数值!!!'));
+      } else if(value==0){
+        callback();
+      }else if (!regNumber.test(value)) {
+        callback(new Error('只能大于等于0的数值!!!'));
+      } else{
+        callback();
+      }
+    };
     return {
       channelList: [
         {id: 1, name: '小程序', value: 1},
@@ -184,6 +278,10 @@ export default {
       },
       rules: {
         goodsName: [{ required: true, message: "请输入票务名称", trigger: ["change","blur"] }],
+        stopSaleTime: [
+          { required: true, message: "请输入停止售卖时间", trigger: ["change","blur"] },
+          { validator: validateNumber, trigger: ["blur","change"]},
+        ],
         beforeTime: [{ required: true, message: "请输入核销时间", trigger: ["change","blur"] }],
         verificationSpeaker: [{ required: true, message: "请输入核销播报次数", trigger: ["change","blur"] }],
         detail: [{ required: true, message: "请输入票务说明", trigger: ["change","blur"] }],
@@ -257,6 +355,7 @@ export default {
           this.$set(this.form, 'isAuth', '1');
           this.$set(this.form, 'verificationSpeaker', obj.goodsPerform.verificationSpeaker);
           this.$set(this.form, 'beforeTime', obj.goodsPerform.beforeTime);
+          this.$set(this.form, 'stopSaleTime', obj.goodsPerform.stopSaleTime);
           this.$set(this.form, 'detail', obj.goodsPerform.detail);
 
 
@@ -270,10 +369,15 @@ export default {
           }
           this.$set(this.form, 'channelWx', obj.goodsPerform.channelWx == 0);
           this.$set(this.form, 'channelWindow', obj.goodsPerform.channelWindow == 0);
+          this.$set(this.form, 'channelAutoSale', obj.goodsPerform.channelAutoSale == 0);
 
           this.$set(this.form, 'backStatus', obj.goodsPerform.backStatus);
           this.$set(this.form, 'backTime', '1');
           this.$set(this.form, 'backStatus', obj.goodsPerform.backStatus.toString());
+          
+          this.$set(this.form, 'saleArea', obj.saleArea);
+          this.$set(this.form, 'stopSaleTime', obj.goodsPerform.stopSaleTime);
+
           if(obj.goodsPerform.backStatus == '0') {
             this.$set(this.form, 'days', obj.performRefundRule.days);
             this.$set(this.form, 'hour', obj.performRefundRule.hour);
@@ -314,12 +418,13 @@ export default {
 
             postMap.salePrice = this.form.salePrice;
             postMap.goodsPerform.buyAstrict = this.form.buyAstrictType == '1' ? this.form.buyAstrict : '-1';
-            if(!(this.form.channelWx || this.form.channelWindow)){
+            if(!(this.form.channelWx || this.form.channelWindow || this.form.channelAutoSale)){
               this.$message.error("请选择销售渠道!");
               return false;
             }
             postMap.goodsPerform.channelWx = this.form.channelWx ? 0 : 1;
             postMap.goodsPerform.channelWindow = this.form.channelWindow  ? 0 : 1;
+            postMap.goodsPerform.channelAutoSale = this.form.channelAutoSale  ? 0 : 1;
             postMap.goodsPerform.backStatus = this.form.backStatus;
             if(this.form.backStatus == '0') {
               postMap.performRefundRule.days = this.form.days;
@@ -328,6 +433,8 @@ export default {
             postMap.goodsType = 2;
             postMap.classifyId = 1;
             postMap.classifyName = "门票类";
+            postMap.saleArea = this.form.saleArea&&this.form.saleArea.length>0?this.form.saleArea:[]
+            postMap.goodsPerform.stopSaleTime = this.form.stopSaleTime
             this.loading = true;
             const { code } = await saveAndEdit({ ...postMap });
             if (code === 200) {
@@ -359,12 +466,16 @@ export default {
       this.$set(this.form, 'buyAstrict', '');
       this.$set(this.form, 'channelWx', '');
       this.$set(this.form, 'channelWindow', '');
+      this.$set(this.form, 'beforeTime', '');
 
       this.$set(this.form, 'backStatus', '');
       this.$set(this.form, 'backTime', '1');
       this.$set(this.form, 'backStatus', '');
       this.$set(this.form, 'days', '');
       this.$set(this.form, 'hour', '');
+      this.$set(this.form, 'saleArea', '');
+      this.$set(this.form, 'stopSaleTime', '');
+
     },
     /**
      * 关闭弹框
@@ -424,4 +535,53 @@ export default {
     cursor: pointer;
   }
 }
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+    .el-input__inner {
+      display: none !important;
+    }
+    span.el-input__suffix {
+      position: inherit !important;
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
 </style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

+ 6 - 0
src/views/ticket/ticketMr/dialog/details.vue

@@ -26,6 +26,12 @@
         <el-col :span="12">
           <div class="grid-content bg-purple item-class">实名信息: <span>全部观影人员均实名</span></div>
         </el-col>
+        <el-col :span="12">
+          <div class="grid-content bg-purple item-class">停止售卖时间: <span>开演前{{ form.goodsPerform && form.goodsPerform.stopSaleTime || '' }}分钟内</span></div>
+        </el-col>
+        <el-col :span="12">
+          <div class="grid-content bg-purple item-class">核销时间: <span>开演前{{ form.goodsPerform && form.goodsPerform.beforeTime || '' }}分钟内</span></div>
+        </el-col>
         <el-col :span="12" v-if="form.goodsPerform">
           <div class="grid-content bg-purple item-class">核销播报次数: <span>{{ form.goodsPerform.verificationSpeaker + '次' || '' }}</span></div>
         </el-col>

+ 8 - 7
src/views/userMr/dialog/dataBox.vue

@@ -89,10 +89,10 @@ export default {
       this.type = type
       this.open = true;
       if (obj){
-        //this.getSelectByIdFun(obj)
-        this.$nextTick(() => {
-          this.form = Object.assign({},this.form,obj)
-        });
+        this.getSelectByIdFun(obj)
+        // this.$nextTick(() => {
+        //   this.form = Object.assign({},this.form,obj)
+        // });
       }else{
         this.$nextTick(() => {
           this.$refs["form"].clearValidate();
@@ -104,9 +104,10 @@ export default {
     async getSelectByIdFun(data) {
       try {
         this.loading = true
-        let res = await getSelectById(data.id)
-        if(res.code == 0){
-          this.form = Object.assign({},this.form,res.data)
+        let res = await getSelectById({id:data.id})
+        if(res.code == 200){
+          this.form = JSON.parse(JSON.stringify(res.data))
+          this.loading = false
         }else {
           throw new Error(res)
         }

+ 9 - 4
src/views/userMr/index.vue

@@ -101,9 +101,9 @@
             size="mini"
             type="text"
             v-hasPermi="['userMr:userMr:blacklist']"
-            v-if="scope.row.isBlackList == 0"
+            
             @click="addBlackListEven(scope.row)"
-          >加入黑名单</el-button>
+          >{{scope.row.isBlackList == 1?'取消黑名单':'加入黑名单'}}</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -196,6 +196,7 @@ export default {
       this.$set(this.queryParams, 'realName', '');
       this.$set(this.queryParams, 'cardId', '');
       this.$set(this.queryParams, 'mobile', '');
+      this.$set(this.queryParams, 'isBlackList', '')
       this.queryParams.pageNum = 1;
       this.handleQuery();
     },
@@ -225,12 +226,16 @@ export default {
 
     /** 加入黑名单按钮操作 */
     addBlackListEven(row) {
-      this.$confirm("是否将该用户加入黑名单?", '提示', {
+      let str = row.isBlackList == 0 ? "是否将该用户加入黑名单?":'是否将该用户移出黑名单?'
+      this.$confirm(str, '提示', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         type: 'warning'
       }).then(() => {
-        addBlackList({ id: row.id}).then((res) => {
+        addBlackList({ 
+          id: row.id,
+          type: row.isBlackList == 0 ? 1:2
+        }).then((res) => {
           if (res.code == 200) {
             this.$message({
               type: 'success',

+ 80 - 361
src/views/venue/performanceHallMr/dialog/seatTemplateEdit.vue

@@ -11,155 +11,29 @@
   <el-dialog
     :title="title"
     :visible.sync="open"
-    width="1200px"
+    width="90%"
     append-to-body
     :close-on-click-modal="false"
     @close="cancel"
+    :fullscreen="dialogFull"
+    class="ygh-dialog"
   >
-    <div class="dialog">
-      <el-row>
-        <el-col :span="18" style="padding-right: 15px">
-          <div class="title-class">
-            <el-row>
-              <el-col :span="8" style="padding-right: 15px">
-                <el-input placeholder="请输入" v-model.number="seatMapRow">
-                  <template slot="append">行</template>
-                </el-input>
-              </el-col>
-              <el-col :span="8" style="padding-left: 15px">
-                <el-input placeholder="请输入" v-model.number="seatMapCol">
-                  <template slot="append">列</template>
-                </el-input>
-              </el-col>
-              <el-col :span="8" style="padding-left: 15px">
-                <el-button @click="setRowCol(seatMapRow, seatMapCol)" style="width: 100%;" type="primary">生成模板</el-button>
-              </el-col>
-            </el-row>
-          </div>
-          <div class="box-top-class" style="position:relative;">
-            <div class="stage-class">舞台</div>
-            <el-button :type="!dragStatus ? 'danger' : 'primary'" size="mini" @click="dragEven" style="position: absolute; bottom: 0; right: 0" icon="el-icon-rank">{{dragStatus ? '开始设置' : '关闭设置'}}</el-button>
-          </div>
-          <div class="box-class scroll-container-class"
-               v-if="seatType"
-               @contextmenu.prevent.stop="contextmenuEven"
-               @wheel.prevent="wheelHandle"
-               ref="scrollContainer"
-               style="position: relative; overflow: hidden; padding: 0;"
-               >
-            <!--  画框确定  -->
-            <div class="draw-dialog-class" id="draw-dialog-type" v-show="drawDialogType">
-              <div class="box-class" style="border: none; height: 280px" @wheel.stop="wheelDrawHandle">
-                <el-form :model="drawForm" ref="drawForm" :rules="drawRules" label-width="100px" label-position="top">
-                  <el-form-item label="" prop="status">
-                    <el-radio v-model="drawForm.status" label="1">可售</el-radio>
-                    <el-radio v-model="drawForm.status" label="2">不可售</el-radio>
-                  </el-form-item>
-                  <el-form-item label="" prop="seatTypeId" v-if="drawForm.status == 1">
-                    <el-select
-                      v-model="drawForm.seatTypeId"
-                      placeholder="座位类型"
-                      clearable
-                      style="width: 100%"
-                      @change="seatTypeDrawChange"
-                    >
-                      <el-option
-                        v-for="dict in seatList"
-                        :key="dict.id"
-                        :label="dict.name"
-                        :value="dict.id"
-                      />
-                    </el-select>
-                  </el-form-item>
-                  <el-form-item label="" v-if="drawForm.status == 1">
-                    <el-input
-                      v-model.number="drawForm.priority"
-                      placeholder="座位自动分配优先级"
-                      clearable
-                      style="width: 100%;"
-                    />
-                  </el-form-item>
-                  <el-form-item >
-                    <el-button @click="drawDialogClen">取 消</el-button>
-                    <el-button @click="drawDialogOk" style="float: right" type="primary">确 定</el-button>
-                  </el-form-item>
-                </el-form>
-              </div>
-            </div>
-            <div style="position: relative;">
-              <div class="box-bottom-class scroll-container" style="position: absolute; width: 100%; height: 100%" id="drawBox" v-drag :style="{ width: boxWidth ? boxWidth + 'px' : '100%', height: boxWidth ? boxWidth + 'px' : '100%'}" ref="seatBox" v-if="seatType">
-                <div v-for="row in seatMap.row" :key="row" style="display: inline-block">
-                  <div class="seat-tag"
-                       :id="(((row - 1) * seatMap.col) + index + '_')"
-                       @click.stop="setSeatTemplateMap((((row - 1) * seatMap.col) + index + '_'))"
-                       v-for="(col, index) in seatMap.col"
-                       :key="col"
-                       :style="{
-                       width: seatWidth + 'px',
-                       height: seatWidth + 'px',
-                       backgroundColor: colSeatMap[((row - 1) * seatMap.col) + index + '_'] && colSeatMap[((row - 1) * seatMap.col) + index + '_'].color ? colSeatMap[((row - 1) * seatMap.col) + index + '_'].color : ''}"
-                  >
-                    <div v-if="seatWidth > 160" :style="{paddingTop: (seatWidth / 4) + 'px', width: seatWidth + 'px', height: seatWidth + 'px'}" class="seat-p-class">
-                      <p style="font-size: 16px !important;"><span>{{colSeatMap[((row - 1) * seatMap.col) + index + '_'].name ? colSeatMap[((row - 1) * seatMap.col) + index + '_'].name : (colSeatMap[((row - 1) * seatMap.col) + index + '_'].rowNo + '排' + (colSeatMap[((row - 1) * seatMap.col) + index + '_'].columnNo) + '座')}}</span><span style="font-size: 14px !important;" v-if="colSeatMap[((row - 1) * seatMap.col) + index + '_'].seatLabel">({{colSeatMap[((row - 1) * seatMap.col) + index + '_'].seatLabel}})</span></p>
-                      <p style="font-size: 14px !important;" v-if="colSeatMap[((row - 1) * seatMap.col) + index + '_'].priority">自动分配优先级 <span>({{colSeatMap[((row - 1) * seatMap.col) + index + '_'].priority}})</span></p>
-                    </div>
-                  </div>
-                </div>
-              </div>
-            </div>
+    <template slot="title">
+        <div class="avue-crud__dialog__header">
+            <span class="el-dialog__title">
+            <span style="display:inline-block;background-color: #3478f5;width:3px;height:20px;margin-right:5px; float: left;margin-top:2px"></span>
+              座位配置
+            </span>
+          <div class="avue-crud__dialog__menu" @click="dialogFull? dialogFull=false: dialogFull=true">
+            <i class="el-icon-full-screen"></i>
           </div>
-          <div style="margin-top: 5px">
-            总座位数:{{ seatMap.row * seatMap.col || 0}}; 可售数量:<span style="color: #67c23a">{{ canNum.length }}</span>; 不可售数量:<span style="color: #f56c6c">{{ unCanNum.length }}</span>
-          </div>
-        </el-col>
-        <el-col :span="6" style="padding-left: 15px">
-          <div class="title-class">座位设置</div>
-          <div class="box-class" style="height: 540px">
-            <el-form :model="form" ref="form" label-width="100px" label-position="top">
-              <el-form-item label="是否可售">
-                <el-radio v-model="form.status" label="1">可售</el-radio>
-                <el-radio v-model="form.status" label="2">不可售</el-radio>
-              </el-form-item>
-              <el-form-item label="座位类型">
-                <el-select
-                  v-model="form.seatTypeId"
-                  placeholder="座位类型"
-                  clearable
-                  style="width: 100%"
-                  @change="seatTypeChange"
-                >
-                  <el-option
-                    v-for="dict in seatList"
-                    :key="dict.id"
-                    :label="dict.name"
-                    :value="dict.id"
-                  />
-                </el-select>
-              </el-form-item>
-              <el-form-item label="座位自动分配优先级">
-                <el-input
-                  v-model.number="form.priority"
-                  placeholder="优先级"
-                  clearable
-                  style="width: 100%;"
-                />
-              </el-form-item>
-              <el-form-item label="自定义座位名">
-                <el-input
-                  v-model="form.name"
-                  placeholder="自定义座位名"
-                  clearable
-                  style="width: 100%;"
-                />
-              </el-form-item>
-
-              <el-form-item >
-                <el-button @click="setSeatMap" style="width: 100%; margin-top: 20px" type="primary">确 定</el-button>
-              </el-form-item>
-            </el-form>
-          </div>
-        </el-col>
-      </el-row>
+        </div>
+      </template>
+    <div class="dialog">
+      <seatManagementTable
+      ref="seatManagementTable"
+      @saveSeat="saveSeat"
+       />
     </div>
     <span slot="footer" class="dialog-footer">
       <el-button @click="cancel">取消</el-button>
@@ -182,9 +56,13 @@
 import { pageList } from '@/api/seatTypeMr/seatTypeMr'
 import { seatSaveAndEdit, saveAndEdit, getSelectById } from "@/api/performanceHallMr/performanceHallMr";
 import { getToken } from "@/utils/auth";
+import seatManagementTable from "../model/seatManagementTable"
 export default {
   name: "seatTemplateEdit",
   that: this,
+  components: {
+    seatManagementTable
+  },
   data() {
     return {
       title: "编辑",
@@ -232,96 +110,11 @@ export default {
         status: [{ required: true, message: "请选择状态", trigger: ["change","blur"] }],
         seatTypeId: [{ required: true, message: "请选择座位类型", trigger: ["change","blur"] }]
       },
+
+      dialogFull: false,
     };
   },
   methods: {
-    drawDialogClen() {
-      let drawDialog = document.getElementById("draw-dialog-type");
-      drawDialog.style.display = "none";
-      let drawDiv = document.getElementById("drawDiv");
-      drawDiv.remove();
-
-      this.$forceUpdate();
-    },
-    // 画框座位设置
-    drawDialogOk() {
-      this.$refs["drawForm"].validate(async (valid) => {
-        if (valid) {
-          let drawDialog = document.getElementById("drawDiv");
-          // 获取div元素的坐标点
-          let rect = drawDialog.getBoundingClientRect();
-          let P_div = document.getElementById("drawBox");
-
-          let P_div_list = P_div.children; // 获取行子集
-          let select_div = [];
-          // 循环判断是否在选择框里
-          for (let i = 0; i < P_div_list.length; i++) {
-            if(P_div_list[i] && P_div_list[i].childNodes) {
-              let child_div = P_div_list[i].children
-              for (let j = 0; j <child_div.length; j++) {
-                let rect_div = child_div[j].getBoundingClientRect();
-                if(rect.top < (rect_div.top + rect_div.height) && rect.bottom > (rect_div.bottom - rect_div.height) &&
-                  rect.left < (rect_div.left + rect_div.width) && rect.right > (rect_div.right - rect_div.width)) {
-                  select_div.push(child_div[j].getAttribute("id"));
-                }
-              }
-            }
-          }
-          for (let i = 0; i < select_div.length; i++) {
-            this.setSeatDrawMap(select_div[i]);
-          }
-          this.drawDialogClen()
-        }
-      });
-    },
-    // 画框座位放置参数
-    setSeatDrawMap(key) {
-      let map = this.colSeatMap[key];
-      map.status = this.drawForm.status;
-      map.color = this.drawForm.seat ? this.drawForm.seat.color : '';
-      map.seatTypeId = this.drawForm.seat ? this.drawForm.seat.id : '';
-      map.seatLabel = this.drawForm.seat ? this.drawForm.seat.name : '';
-      map.name = "";
-      map.priority = this.drawForm.priority;
-
-      if(this.drawForm.status == 2) {
-        map.color = '#7d7d7e';
-        map.seatTypeId = '';
-        map.seatLabel = '';
-      }
-      this.$set(this.colSeatMap, key, map);
-      this.countNum();
-      this.$forceUpdate()
-    },
-    // 鼠标滚动
-    wheelHandle(e) {
-      if(e.wheelDelta > 0){
-        this.seatWidth = Math.trunc(this.seatWidth + 10);
-      } else {
-        if(this.initWidth > this.seatWidth + 5){
-          // this.seatWidth = this.initWidth;
-        } else {
-          this.seatWidth = Math.trunc(this.seatWidth -10)
-        }
-      }
-      this.boxWidth = this.seatWidth * this.seatMap.col + 100;
-      // this.seatWidth = (this.seatWidth + this.zoom);
-      this.$forceUpdate();
-    },
-    wheelDrawHandle(e) {
-      if(e.preventDefault){
-        e.preventDefault()
-      } else {
-        e.returnValue = false
-      }
-      return false
-    },
-    contextmenuEven(e) {
-      return false;
-    },
-    dragEven(){
-      this.dragStatus = !this.dragStatus;
-    },
     /**
      * 打开弹框
      * @date 2023-11-22
@@ -338,7 +131,7 @@ export default {
       this.boxWidth = 0;
       this.dragStatus = true;
       this.$set(this.form, 'status', '1')
-      if (obj){
+      if (obj){ // 编辑模式
         this.title = "座位模板";
         this.auditoriumId = obj.id;
         this.$set(this.seatMap, 'row', obj.rows);
@@ -347,7 +140,7 @@ export default {
         this.$set(this, 'seatMapCol', obj.cols);
 
         this.getSelectByIdApi(obj)
-      }else{
+      }else{ // 新增模式
         this.seatType = true;
         this.title = "座位模板";
         this.$nextTick(() => {
@@ -368,66 +161,10 @@ export default {
             this.$set(this.colSeatMap, item.sortId + '_', item);
           })
           this.seatType = true;
-          this.$nextTick(() =>{
-            this.boxWidth = this.$refs.seatBox.offsetWidth;
-            this.seatWidth = ((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
-            this.initWidth = Math.trunc((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
-          })
-          this.countNum();
+          this.$refs.seatManagementTable.initData(dataList,'edit')
         })
       });
     },
-    /** 设置座位模板行列 */
-    setRowCol(row, col) {
-      if(!row || !col){
-        this.$message.error("请输入行和列!");
-        return false;
-      }
-      if(row <= 0 || col <= 0){
-        this.$message.error("请输入大于0的行和列!");
-        return false;
-      }
-      if(this.colSeatMap) {
-        this.$confirm('此操作将重置座位模板, 是否继续?', '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          this.seatMap.row = row;
-          this.seatMap.col = col;
-          this.seatType = false;
-          this.seatType = true;
-          this.colSeatMap  = {}
-          let index = 0;
-          for (let i = 1; i < this.seatMap.row + 1; i++) {
-            for (let j = this.seatMap.col; j > 0; j--) {
-              let rowColMap = {
-                "auditoriumId": this.auditoriumId,
-                "name": "",
-                "rowNo": i,
-                "sortId": index,
-                "columnNo": j,
-                "seatTypeColor": '#fdfdfd',
-                "seatTypeId": "",
-                "seatLabel": "",
-                "priority": "",
-                "status": 2
-              };
-              this.$set(this.colSeatMap, index + '_', rowColMap);
-              index ++;
-            }
-          }
-          this.$nextTick(() =>{
-            this.boxWidth = this.$refs.seatBox.offsetWidth;
-            this.seatWidth = ((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
-            this.initWidth = Math.trunc((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
-          })
-          this.countNum();
-        }).catch(() => {
-
-        });
-      }
-    },
     /** 座位类型列表 */
     getSeatTypeList() {
       pageList(this.addDateRange({pageNum: 1, pageSize: 100}))
@@ -436,76 +173,6 @@ export default {
           }
         );
     },
-    /** 座位类型选择事件 */
-    seatTypeChange(val) {
-      this.$set(this.form, 'priority', '');
-      this.$set(this.form, 'name', '');
-      this.seatList.forEach(item => {
-        if(val == item.id){
-          this.form.seat = item
-        }
-      })
-    },
-    /** 画框座位类型选择事件 */
-    seatTypeDrawChange(val) {
-      this.$set(this.drawForm, 'priority', '');
-      this.seatList.forEach(item => {
-        if(val == item.id){
-          this.drawForm.seat = item
-        }
-      })
-    },
-    /** 座位设置确认事件 */
-    setSeatMap() {
-      this.seatSetMap = {};
-      this.seatSetMap.status = this.form.status;
-      this.seatSetMap.color = this.form.seat.color;
-      this.seatSetMap.seatTypeId = this.form.seat.id;
-      this.seatSetMap.seatLabel = this.form.seat.name;
-      this.seatSetMap.name = this.form.name;
-      this.seatSetMap.priority = this.form.priority;
-
-      if(this.seatSetMap.status == 2) {
-        this.seatSetMap.color = '#7d7d7e';
-        this.seatSetMap.seatTypeId = '';
-        this.seatSetMap.seatLabel = '';
-      }
-    },
-
-    // 计算可售和不可售数量
-    countNum() {
-      this.canNum = [];
-      this.unCanNum = [];
-      if(this.colSeatMap) {
-        for (const key in this.colSeatMap) {
-          if(this.colSeatMap[key].status == 2 || !this.colSeatMap[key].status){
-            this.unCanNum.push(key)
-          } else if (this.colSeatMap[key].status == 1) {
-            this.canNum.push(key)
-          }
-        }
-      }
-    },
-
-    // 点击座位放置参数
-    setSeatTemplateMap(key) {
-      if(this.dragStatus){
-        return false
-      }
-      if(!this.seatSetMap.status){
-        this.seatSetMap.color = '#7d7d7e';
-      }
-      let map = this.colSeatMap[key];
-      map.status = this.seatSetMap.status;
-      map.color = this.seatSetMap.color;
-      map.seatTypeId = this.seatSetMap.seatTypeId;
-      map.seatLabel = this.seatSetMap.seatLabel;
-      map.name = this.seatSetMap.name;
-      map.priority = this.seatSetMap.priority;
-      this.$set(this.colSeatMap, key, map);
-      this.countNum();
-      this.$forceUpdate()
-    },
     /**
      * 保存
      * @date 2023-11-22
@@ -521,12 +188,18 @@ export default {
           }
           try {
             this.loading = true;
-            const { code } = await saveAndEdit({ id: this.auditoriumId, rows: this.seatMap.row, cols: this.seatMap.col });
+            /**  保存行号  */
+            const { code } = await saveAndEdit({ 
+              id: this.auditoriumId, 
+              rows: this.seatMap.row, 
+              cols: this.seatMap.col 
+            });
             if (code === 200) {
               let postList = []
               for (const codeKey in this.colSeatMap) {
                 postList.push(this.colSeatMap[codeKey])
               }
+              /**  保存座位  */
               const { code } = await seatSaveAndEdit(postList);
               if (code === 200) {
                 that.$message.success("操作成功!");
@@ -679,4 +352,50 @@ export default {
     cursor: pointer;
   }
 }
+
+//这里注意:我当前将css样式加载全局上,如果单页添加样式需要每个样式前添加 ‘/deep/’ 修饰符
+
+/*  dialog*/
+.ygh-dialog ::v-deep .el-dialog__header {
+  padding: 16px 20px 15px;
+}
+.el-dialog__headerbtn{
+  top: 15px;
+}
+
+/*dialog header*/
+.el-dialog__header{
+  background: #e3eaed;
+}
+.avue-crud__dialog__header {
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  -webkit-box-pack: justify;
+  -ms-flex-pack: justify;
+  justify-content: space-between;
+}
+.el-dialog__title {
+  color: rgba(0,0,0,.85);
+  font-weight: 500;
+  word-wrap: break-word;
+}
+.avue-crud__dialog__menu {
+  padding-right: 20px;
+  float: left;
+}
+.avue-crud__dialog__menu i {
+  color: #909399;
+  font-size: 15px;
+}
+.el-icon-full-screen{
+  cursor: pointer;
+}
+.el-icon-full-screen:before {
+  content: "\e719";
+}
+
 </style>

+ 682 - 0
src/views/venue/performanceHallMr/dialog/seatTemplateEditOld.vue

@@ -0,0 +1,682 @@
+<!--
+ * @Description: 新增/编辑弹框
+ * @Author: Sugar.
+ * @Date: 2023-11-24 13:55:00
+ * @LastEditors: Sugar.
+ * @LastEditTime: 22023-11-24 13:55:00
+ * @FilePath: \cattle_webui\src\views\venue\performanceHallMr\dialog\seatTemplateEdit.vue
+ * @Copyright: Copyright (c) 2016~2023 by Sugar., All Rights Reserved.
+-->
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="open"
+    width="1200px"
+    append-to-body
+    :close-on-click-modal="false"
+    @close="cancel"
+  >
+    <div class="dialog">
+      <el-row>
+        <el-col :span="18" style="padding-right: 15px">
+          <div class="title-class">
+            <el-row>
+              <el-col :span="8" style="padding-right: 15px">
+                <el-input placeholder="请输入" v-model.number="seatMapRow">
+                  <template slot="append">行</template>
+                </el-input>
+              </el-col>
+              <el-col :span="8" style="padding-left: 15px">
+                <el-input placeholder="请输入" v-model.number="seatMapCol">
+                  <template slot="append">列</template>
+                </el-input>
+              </el-col>
+              <el-col :span="8" style="padding-left: 15px">
+                <el-button @click="setRowCol(seatMapRow, seatMapCol)" style="width: 100%;" type="primary">生成模板</el-button>
+              </el-col>
+            </el-row>
+          </div>
+          <div class="box-top-class" style="position:relative;">
+            <div class="stage-class">舞台</div>
+            <el-button :type="!dragStatus ? 'danger' : 'primary'" size="mini" @click="dragEven" style="position: absolute; bottom: 0; right: 0" icon="el-icon-rank">{{dragStatus ? '开始设置' : '关闭设置'}}</el-button>
+          </div>
+          <div class="box-class scroll-container-class"
+               v-if="seatType"
+               @contextmenu.prevent.stop="contextmenuEven"
+               @wheel.prevent="wheelHandle"
+               ref="scrollContainer"
+               style="position: relative; overflow: hidden; padding: 0;"
+               >
+            <!--  画框确定  -->
+            <div class="draw-dialog-class" id="draw-dialog-type" v-show="drawDialogType">
+              <div class="box-class" style="border: none; height: 280px" @wheel.stop="wheelDrawHandle">
+                <el-form :model="drawForm" ref="drawForm" :rules="drawRules" label-width="100px" label-position="top">
+                  <el-form-item label="" prop="status">
+                    <el-radio v-model="drawForm.status" label="1">可售</el-radio>
+                    <el-radio v-model="drawForm.status" label="2">不可售</el-radio>
+                  </el-form-item>
+                  <el-form-item label="" prop="seatTypeId" v-if="drawForm.status == 1">
+                    <el-select
+                      v-model="drawForm.seatTypeId"
+                      placeholder="座位类型"
+                      clearable
+                      style="width: 100%"
+                      @change="seatTypeDrawChange"
+                    >
+                      <el-option
+                        v-for="dict in seatList"
+                        :key="dict.id"
+                        :label="dict.name"
+                        :value="dict.id"
+                      />
+                    </el-select>
+                  </el-form-item>
+                  <el-form-item label="" v-if="drawForm.status == 1">
+                    <el-input
+                      v-model.number="drawForm.priority"
+                      placeholder="座位自动分配优先级"
+                      clearable
+                      style="width: 100%;"
+                    />
+                  </el-form-item>
+                  <el-form-item >
+                    <el-button @click="drawDialogClen">取 消</el-button>
+                    <el-button @click="drawDialogOk" style="float: right" type="primary">确 定</el-button>
+                  </el-form-item>
+                </el-form>
+              </div>
+            </div>
+            <div style="position: relative;">
+              <div class="box-bottom-class scroll-container" style="position: absolute; width: 100%; height: 100%" id="drawBox" v-drag :style="{ width: boxWidth ? boxWidth + 'px' : '100%', height: boxWidth ? boxWidth + 'px' : '100%'}" ref="seatBox" v-if="seatType">
+                <div v-for="row in seatMap.row" :key="row" style="display: inline-block">
+                  <div class="seat-tag"
+                       :id="(((row - 1) * seatMap.col) + index + '_')"
+                       @click.stop="setSeatTemplateMap((((row - 1) * seatMap.col) + index + '_'))"
+                       v-for="(col, index) in seatMap.col"
+                       :key="col"
+                       :style="{
+                       width: seatWidth + 'px',
+                       height: seatWidth + 'px',
+                       backgroundColor: colSeatMap[((row - 1) * seatMap.col) + index + '_'] && colSeatMap[((row - 1) * seatMap.col) + index + '_'].color ? colSeatMap[((row - 1) * seatMap.col) + index + '_'].color : ''}"
+                  >
+                    <div v-if="seatWidth > 160" :style="{paddingTop: (seatWidth / 4) + 'px', width: seatWidth + 'px', height: seatWidth + 'px'}" class="seat-p-class">
+                      <p style="font-size: 16px !important;"><span>{{colSeatMap[((row - 1) * seatMap.col) + index + '_'].name ? colSeatMap[((row - 1) * seatMap.col) + index + '_'].name : (colSeatMap[((row - 1) * seatMap.col) + index + '_'].rowNo + '排' + (colSeatMap[((row - 1) * seatMap.col) + index + '_'].columnNo) + '座')}}</span><span style="font-size: 14px !important;" v-if="colSeatMap[((row - 1) * seatMap.col) + index + '_'].seatLabel">({{colSeatMap[((row - 1) * seatMap.col) + index + '_'].seatLabel}})</span></p>
+                      <p style="font-size: 14px !important;" v-if="colSeatMap[((row - 1) * seatMap.col) + index + '_'].priority">自动分配优先级 <span>({{colSeatMap[((row - 1) * seatMap.col) + index + '_'].priority}})</span></p>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div style="margin-top: 5px">
+            总座位数:{{ seatMap.row * seatMap.col || 0}}; 可售数量:<span style="color: #67c23a">{{ canNum.length }}</span>; 不可售数量:<span style="color: #f56c6c">{{ unCanNum.length }}</span>
+          </div>
+        </el-col>
+        <el-col :span="6" style="padding-left: 15px">
+          <div class="title-class">座位设置</div>
+          <div class="box-class" style="height: 540px">
+            <el-form :model="form" ref="form" label-width="100px" label-position="top">
+              <el-form-item label="是否可售">
+                <el-radio v-model="form.status" label="1">可售</el-radio>
+                <el-radio v-model="form.status" label="2">不可售</el-radio>
+              </el-form-item>
+              <el-form-item label="座位类型">
+                <el-select
+                  v-model="form.seatTypeId"
+                  placeholder="座位类型"
+                  clearable
+                  style="width: 100%"
+                  @change="seatTypeChange"
+                >
+                  <el-option
+                    v-for="dict in seatList"
+                    :key="dict.id"
+                    :label="dict.name"
+                    :value="dict.id"
+                  />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="座位自动分配优先级">
+                <el-input
+                  v-model.number="form.priority"
+                  placeholder="优先级"
+                  clearable
+                  style="width: 100%;"
+                />
+              </el-form-item>
+              <el-form-item label="自定义座位名">
+                <el-input
+                  v-model="form.name"
+                  placeholder="自定义座位名"
+                  clearable
+                  style="width: 100%;"
+                />
+              </el-form-item>
+
+              <el-form-item >
+                <el-button @click="setSeatMap" style="width: 100%; margin-top: 20px" type="primary">确 定</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="cancel">取消</el-button>
+      <el-button
+        type="primary"
+        @click="submitForm"
+        v-loading.fullscreen.lock="loading"
+        element-loading-text="提交中..."
+        element-loading-spinner="el-icon-loading"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+      >
+        <span v-if="loading">提交中...</span>
+        <span v-else>保存</span>
+      </el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { pageList } from '@/api/seatTypeMr/seatTypeMr'
+import { seatSaveAndEdit, saveAndEdit, getSelectById } from "@/api/performanceHallMr/performanceHallMr";
+import { getToken } from "@/utils/auth";
+export default {
+  name: "seatTemplateEdit",
+  that: this,
+  data() {
+    return {
+      title: "编辑",
+      model: "EDIT",
+      activeName: '01',
+      open: false,
+      seatType: false,
+      loading: false,
+      seatWidth: null,
+      seatMap: {
+        row: 0,
+        col: 0,
+      },
+      seatMapRow: '',
+      seatMapCol: '',
+      seatSetMap: {},
+      seatTemplateMap: [],
+      colSeatMap: {},
+      form: {
+        id: undefined,
+        status: "1",
+        content: "",
+      },
+      seatList: [],
+      auditoriumId: '',
+      zoom: 10,
+      boxWidth: '',
+      initWidth: '',
+      moveStatus: false,
+      mouseMap: {},
+      mousemoveMap: {},
+      scrollTop: 0,
+      scrollLeft: 0,
+      scrollEvenTop: 0,
+      scrollEvenLeft: 0,
+      dragStatus: true,
+      canNum: [],
+      unCanNum: [],
+
+      drawForm: {
+        status: '1'
+      },
+      drawDialogType: false,
+      drawRules: {
+        status: [{ required: true, message: "请选择状态", trigger: ["change","blur"] }],
+        seatTypeId: [{ required: true, message: "请选择座位类型", trigger: ["change","blur"] }]
+      },
+    };
+  },
+  methods: {
+    drawDialogClen() {
+      let drawDialog = document.getElementById("draw-dialog-type");
+      drawDialog.style.display = "none";
+      let drawDiv = document.getElementById("drawDiv");
+      drawDiv.remove();
+
+      this.$forceUpdate();
+    },
+    // 画框座位设置
+    drawDialogOk() {
+      this.$refs["drawForm"].validate(async (valid) => {
+        if (valid) {
+          let drawDialog = document.getElementById("drawDiv");
+          // 获取div元素的坐标点
+          let rect = drawDialog.getBoundingClientRect();
+          let P_div = document.getElementById("drawBox");
+
+          let P_div_list = P_div.children; // 获取行子集
+          let select_div = [];
+          // 循环判断是否在选择框里
+          for (let i = 0; i < P_div_list.length; i++) {
+            if(P_div_list[i] && P_div_list[i].childNodes) {
+              let child_div = P_div_list[i].children
+              for (let j = 0; j <child_div.length; j++) {
+                let rect_div = child_div[j].getBoundingClientRect();
+                if(rect.top < (rect_div.top + rect_div.height) && rect.bottom > (rect_div.bottom - rect_div.height) &&
+                  rect.left < (rect_div.left + rect_div.width) && rect.right > (rect_div.right - rect_div.width)) {
+                  select_div.push(child_div[j].getAttribute("id"));
+                }
+              }
+            }
+          }
+          for (let i = 0; i < select_div.length; i++) {
+            this.setSeatDrawMap(select_div[i]);
+          }
+          this.drawDialogClen()
+        }
+      });
+    },
+    // 画框座位放置参数
+    setSeatDrawMap(key) {
+      let map = this.colSeatMap[key];
+      map.status = this.drawForm.status;
+      map.color = this.drawForm.seat ? this.drawForm.seat.color : '';
+      map.seatTypeId = this.drawForm.seat ? this.drawForm.seat.id : '';
+      map.seatLabel = this.drawForm.seat ? this.drawForm.seat.name : '';
+      map.name = "";
+      map.priority = this.drawForm.priority;
+
+      if(this.drawForm.status == 2) {
+        map.color = '#7d7d7e';
+        map.seatTypeId = '';
+        map.seatLabel = '';
+      }
+      this.$set(this.colSeatMap, key, map);
+      this.countNum();
+      this.$forceUpdate()
+    },
+    // 鼠标滚动
+    wheelHandle(e) {
+      if(e.wheelDelta > 0){
+        this.seatWidth = Math.trunc(this.seatWidth + 10);
+      } else {
+        if(this.initWidth > this.seatWidth + 5){
+          // this.seatWidth = this.initWidth;
+        } else {
+          this.seatWidth = Math.trunc(this.seatWidth -10)
+        }
+      }
+      this.boxWidth = this.seatWidth * this.seatMap.col + 100;
+      // this.seatWidth = (this.seatWidth + this.zoom);
+      this.$forceUpdate();
+    },
+    wheelDrawHandle(e) {
+      if(e.preventDefault){
+        e.preventDefault()
+      } else {
+        e.returnValue = false
+      }
+      return false
+    },
+    contextmenuEven(e) {
+      return false;
+    },
+    dragEven(){
+      this.dragStatus = !this.dragStatus;
+    },
+    /**
+     * 打开弹框
+     * @date 2023-11-22
+     * @param {any} obj
+     * @returns {any}
+     */
+    openDialog(title, obj) {
+      this.open = true;
+      this.seatType = false;
+      this.getSeatTypeList();
+      this.colSeatMap = {}
+      this.drawForm = {};
+      this.$set(this.drawForm, 'status', '1')
+      this.boxWidth = 0;
+      this.dragStatus = true;
+      this.$set(this.form, 'status', '1')
+      if (obj){
+        this.title = "座位模板";
+        this.auditoriumId = obj.id;
+        this.$set(this.seatMap, 'row', obj.rows);
+        this.$set(this.seatMap, 'col', obj.cols);
+        this.$set(this, 'seatMapRow', obj.rows);
+        this.$set(this, 'seatMapCol', obj.cols);
+
+        this.getSelectByIdApi(obj)
+      }else{
+        this.seatType = true;
+        this.title = "座位模板";
+        this.$nextTick(() => {
+          this.$refs["form"].clearValidate();
+        });
+      }
+    },
+    /** 获取详情 */
+    getSelectByIdApi(row) {
+      const id = row.id
+      getSelectById(id).then(response => {
+        const dataList = response.data;
+        this.$nextTick(() =>{
+          dataList.forEach(item => {
+            if(item.status == 2){
+              item.color = '#7d7d7e';
+            }
+            this.$set(this.colSeatMap, item.sortId + '_', item);
+          })
+          this.seatType = true;
+          this.$nextTick(() =>{
+            this.boxWidth = this.$refs.seatBox.offsetWidth;
+            this.seatWidth = ((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
+            this.initWidth = Math.trunc((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
+          })
+          this.countNum();
+        })
+      });
+    },
+    /** 设置座位模板行列 */
+    setRowCol(row, col) {
+      if(!row || !col){
+        this.$message.error("请输入行和列!");
+        return false;
+      }
+      if(row <= 0 || col <= 0){
+        this.$message.error("请输入大于0的行和列!");
+        return false;
+      }
+      if(this.colSeatMap) {
+        this.$confirm('此操作将重置座位模板, 是否继续?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.seatMap.row = row;
+          this.seatMap.col = col;
+          this.seatType = false;
+          this.seatType = true;
+          this.colSeatMap  = {}
+          let index = 0;
+          for (let i = 1; i < this.seatMap.row + 1; i++) {
+            for (let j = this.seatMap.col; j > 0; j--) {
+              let rowColMap = {
+                "auditoriumId": this.auditoriumId,
+                "name": "",
+                "rowNo": i,
+                "sortId": index,
+                "columnNo": j,
+                "seatTypeColor": '#fdfdfd',
+                "seatTypeId": "",
+                "seatLabel": "",
+                "priority": "",
+                "status": 2
+              };
+              this.$set(this.colSeatMap, index + '_', rowColMap);
+              index ++;
+            }
+          }
+          this.$nextTick(() =>{
+            this.boxWidth = this.$refs.seatBox.offsetWidth;
+            this.seatWidth = ((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
+            this.initWidth = Math.trunc((this.$refs.seatBox.offsetWidth - 10 - (this.seatMap.col * 2))/this.seatMap.col);
+          })
+          this.countNum();
+        }).catch(() => {
+
+        });
+      }
+    },
+    /** 座位类型列表 */
+    getSeatTypeList() {
+      pageList(this.addDateRange({pageNum: 1, pageSize: 100}))
+        .then(response => {
+            this.seatList = response.data.rows;
+          }
+        );
+    },
+    /** 座位类型选择事件 */
+    seatTypeChange(val) {
+      this.$set(this.form, 'priority', '');
+      this.$set(this.form, 'name', '');
+      this.seatList.forEach(item => {
+        if(val == item.id){
+          this.form.seat = item
+        }
+      })
+    },
+    /** 画框座位类型选择事件 */
+    seatTypeDrawChange(val) {
+      this.$set(this.drawForm, 'priority', '');
+      this.seatList.forEach(item => {
+        if(val == item.id){
+          this.drawForm.seat = item
+        }
+      })
+    },
+    /** 座位设置确认事件 */
+    setSeatMap() {
+      this.seatSetMap = {};
+      this.seatSetMap.status = this.form.status;
+      this.seatSetMap.color = this.form.seat.color;
+      this.seatSetMap.seatTypeId = this.form.seat.id;
+      this.seatSetMap.seatLabel = this.form.seat.name;
+      this.seatSetMap.name = this.form.name;
+      this.seatSetMap.priority = this.form.priority;
+
+      if(this.seatSetMap.status == 2) {
+        this.seatSetMap.color = '#7d7d7e';
+        this.seatSetMap.seatTypeId = '';
+        this.seatSetMap.seatLabel = '';
+      }
+    },
+
+    // 计算可售和不可售数量
+    countNum() {
+      this.canNum = [];
+      this.unCanNum = [];
+      if(this.colSeatMap) {
+        for (const key in this.colSeatMap) {
+          if(this.colSeatMap[key].status == 2 || !this.colSeatMap[key].status){
+            this.unCanNum.push(key)
+          } else if (this.colSeatMap[key].status == 1) {
+            this.canNum.push(key)
+          }
+        }
+      }
+    },
+
+    // 点击座位放置参数
+    setSeatTemplateMap(key) {
+      if(this.dragStatus){
+        return false
+      }
+      if(!this.seatSetMap.status){
+        this.seatSetMap.color = '#7d7d7e';
+      }
+      let map = this.colSeatMap[key];
+      map.status = this.seatSetMap.status;
+      map.color = this.seatSetMap.color;
+      map.seatTypeId = this.seatSetMap.seatTypeId;
+      map.seatLabel = this.seatSetMap.seatLabel;
+      map.name = this.seatSetMap.name;
+      map.priority = this.seatSetMap.priority;
+      this.$set(this.colSeatMap, key, map);
+      this.countNum();
+      this.$forceUpdate()
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm() {
+      let that = this;
+      this.$refs["form"].validate(async (valid) => {
+        if (valid) {
+          let postList = []
+          for (const codeKey in this.colSeatMap) {
+            postList.push(this.colSeatMap[codeKey])
+          }
+          try {
+            this.loading = true;
+            const { code } = await saveAndEdit({ id: this.auditoriumId, rows: this.seatMap.row, cols: this.seatMap.col });
+            if (code === 200) {
+              let postList = []
+              for (const codeKey in this.colSeatMap) {
+                postList.push(this.colSeatMap[codeKey])
+              }
+              const { code } = await seatSaveAndEdit(postList);
+              if (code === 200) {
+                that.$message.success("操作成功!");
+                that.$emit("getList");
+                that.cancel();
+              }
+            }
+          } catch (error) {
+          } finally {
+            this.loading = false;
+          }
+        }
+      });
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      this.$refs["form"].resetFields();
+      this.form.id = undefined;
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+    /**
+     * 上传成功
+     * @date 2023-11-22
+     * @param {any} res
+     * @returns {any}
+     */
+    handleAvatarSuccess(res) {
+      if (res.code === 200) {
+        // this.form.mainImg = res?.data?.url;
+        this.$set(this.form, 'mainImg', res?.data?.url)
+      }
+    },
+    /**
+     * 上传文件之前之前
+     * @date 2023-11-22
+     * @param {any} file
+     * @returns {any}
+     */
+    beforeAvatarUpload(file) {
+      const isJPG = file.type === "image/jpeg" || "image/png";
+      if (!isJPG) {
+        this.$message.error("上传头像图片只能是jpg或png格式!");
+      }
+      return isJPG;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.dialog {
+  padding: 0 30px;
+  max-height: 75vh;
+  overflow-y: auto;
+}
+.draw-dialog-class{
+  border-radius: 10px;
+  height: 240px;
+  width: 220px;
+  background-color: #fff;
+  position: absolute;
+  z-index: 55;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+.dialog {
+  padding: 0 30px;
+
+  .title-class{
+    text-align: center;
+    color: #6e6e6e;
+    margin: 10px auto;
+  }
+  .box-top-class{
+    .stage-class{
+      margin: 10px auto;
+      width: 160px;
+      height: 80px;
+      border: 2px solid #7d7d7e;
+      text-align: center;
+      line-height: 80px;
+    }
+  }
+  .box-class ::-webkit-scrollbar{ /*滚动条基本样式,高度*/
+    width:10px;height:10px;
+  }
+  .box-class{
+    width: 100%;
+    height: 500px;
+    border: 2px solid #7d7d7e;
+    border-radius: 4px;
+    padding: 10px;
+
+    .box-bottom-class{
+      //border: 2px solid #5656c2;
+      //margin-top: 15px;
+      //padding-left: 4px;
+
+      .seat-tag{
+        display: inline-block;
+        border: 1px solid #7d7d7e;
+        margin-right: 2px;
+        cursor: pointer;
+        background: url("../../../../assets/images/seat-icon.png") no-repeat;
+        background-size: 100% 100%;
+        position: relative;
+
+        &:hover{
+          opacity: 0.8;
+        }
+      }
+      .seat-p-class{
+        position: absolute;
+        left: 0;
+        top: 0;
+        text-align: center;
+        font-size: 18px;
+        display: inline-block;
+        color: white;
+      }
+    }
+  }
+
+  .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;
+  }
+}
+</style>

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

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

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

@@ -0,0 +1,1375 @@
+<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="ruleFormRegion" 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('ruleFormRegion')">创建区域</el-button>
+                                <el-button size="mini" @click="resetForm('ruleFormRegion')">重置</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="名称">
+                                <template slot-scope="scope">
+                                    <div>
+                                        <span>{{ scope.row.name ? scope.row.name : '暂未命名' }}</span>
+                                        <span>({{ scope.row.rowNo}}-{{ scope.row.columnNo}})</span>
+                                    </div> 
+                                </template>
+                            </el-table-column>
+                            <el-table-column
+                            align="center"
+                            label="区域">
+                                <template slot-scope="scope">
+                                    <span>{{ scope.row.style && scope.row.style.keyLabel ? 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="formAll.status" placeholder="区域" clearable>
+                                <el-option
+                                    v-for="item in tableHeader"
+                                    :key="item.key"
+                                    :label="item.title"
+                                    :value="item.key"
+                                />
+                            </el-select>
+                        </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(list,type){
+            this.tableDataAll = JSON.parse(JSON.stringify(list))
+            //this.batchTableList = JSON.parse(JSON.stringify(list))
+            let listHeader = []
+            let listTabel = []
+        },
+        dataProcess(){
+            let list = JSON.parse(JSON.stringify(this.tableDataAll))
+            let list1 = JSON.parse(JSON.stringify(this.tableData))
+            list.forEach((item,index)=>{
+                if(item.style && item.style.key) {
+                    list1[item.rowNo-1][item.style.key].push(item)
+                }
+            })
+            this.tableData = JSON.parse(JSON.stringify(list1))
+            this.countRegionW()
+        },
+        /** 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(formName)
+                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'){
+                        console.log("sdfsdfsdfsdfds",this.formAll)
+                        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){
+            console.log('this.multipleSelection====',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 = ''
+            let listTabel = JSON.parse(JSON.stringify(this.tableDataAll))
+            this.tableHeader.forEach((item)=>{
+                if(item.key == this.formAll.status) {
+                    currentLabel = item.title
+                }
+            })
+            for(let i=0;i<this.multipleSelection.length;i++){
+                for(let j=0;j<this.tableDataAll.length;j++){
+                    if(this.multipleSelection[i].id == this.tableDataAll[j].id){
+                        listTabel[j] = {
+                        ...this.tableDataAll[j],
+                            style: {
+                                ...this.tableDataAll[j].style,
+                                key: this.formAll.status, // 所属区域的key
+                                keyLabel: currentLabel, // 所属区域的名称
+                            }
+                        }
+                        break;
+                    }    
+                }
+            }
+            this.tableDataAll = JSON.parse(JSON.stringify(listTabel))
+            console.log("this.tableDataAll=====",this.tableDataAll)
+            // this.batchTableList = JSON.parse(JSON.stringify(this.tableDataAll))
+            this.handleQuery()
+            this.dataProcess()
+        },
+        // 批量禁用
+        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]))
+        },
+
+        /**   保存座位   */
+        saveSeat() {
+            console.log('this.tableDataAll',this.tableDataAll)
+            this.$emit('saveSeat',this.tableDataAll)
+        }
+    }
+};
+</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>

+ 451 - 0
src/views/windowTicketSales/ticketingCollection.vue

@@ -0,0 +1,451 @@
+<template>
+    <div class="app-container app-container-me">
+      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
+        <el-form-item label="订单号" label-width="80px">
+          <el-input
+            v-model="queryParams.orderId"
+            placeholder="请输入订单号"
+            clearable
+            style="width: 240px;"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="取票码" label-width="80px">
+          <el-input
+            v-model="queryParams.qrcodeNo"
+            placeholder="请输入取票码"
+            clearable
+            style="width: 240px;"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="手机号:" prop="mobile">
+          <el-input
+            v-model="queryParams.mobile"
+            placeholder="请输入手机号"
+            clearable
+            style="width: 240px;"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="身份证号:" label-width="120px" prop="idcard">
+          <el-input
+            v-model="queryParams.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>
+        </el-form-item>
+        <el-form-item label="座位号" label-width="80px">
+          <el-input
+            v-model="queryParams.seatName"
+            placeholder="请输入座位号"
+            clearable
+            style="width: 240px;"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="订单状态">
+          <el-select
+            v-model="queryParams.orderStatus"
+            placeholder="订单状态"
+            clearable
+            style="width: 100%"
+          >
+            <el-option
+              v-for="dict in dict.type.order_status_type"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+        </el-form-item>
+      </el-form>
+  
+      <el-row :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <el-button
+                :disabled="multipleSelection.length == 0"
+                type="primary"
+                plain
+                icon="el-icon-plus"
+                size="mini"
+                @click="handleOpen(multipleSelection)"
+                v-hasPermi="['windowTicketSales:ticketingCollection:print']"
+              >批量打印门票</el-button>
+        </el-col>
+        <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      </el-row>
+  
+      <el-table 
+      ref="tables" 
+      v-loading="loading" 
+      :data="dataList" 
+      
+      @selection-change="handleSelectionChange"
+      border>
+        <el-table-column type="selection" width="55"></el-table-column>
+        <el-table-column label="序号" align="center" type="index" width="50"></el-table-column>
+        <el-table-column label="姓名" align="center" prop="name" />
+        <el-table-column label="身份证号" align="center" prop="idcard" />
+        <el-table-column label="手机号" align="center" prop="mobile" />
+        <el-table-column label="取票码" align="center" prop="qrcodeNo" />
+        <el-table-column label="订单号" align="center" prop="orderId" />
+        <el-table-column label="剧目名称" align="center" prop="performName" />
+        <el-table-column label="票务名称" align="center" prop="goodsName" />
+        <el-table-column label="座位信息" align="center" prop="seatName" />
+        <el-table-column label="座位类型" align="center" prop="seatTypeName" />
+        <el-table-column label="节目播出日期" align="center" prop="performDate" />
+        <el-table-column label="下单时间" align="center" prop="createTime" />
+        <el-table-column label="购票渠道" align="center" prop="source">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.order_form_type" :value="scope.row.source"/>
+          </template>
+        </el-table-column>
+        <el-table-column label="订单状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="dict.type.order_status_type" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="打印次数" align="center" prop="printNum" />
+        <el-table-column label="操作" align="center" fixed="right" width="80" class-name="small-padding fixed-width">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              @click="handleOpen([scope.row])"
+              v-hasPermi="['windowTicketSales:ticketingCollection:print']"
+            >打印门票</el-button>
+          </template>
+        </el-table-column>
+        <template slot="empty">
+            <div>
+                <span>未查询到相关订单,请重新输入!</span>
+            </div>
+        </template>
+      </el-table>
+      <pagination
+        v-show="total>0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+      <el-dialog
+        title="选择打印机"
+        :visible.sync="dialogVisible"
+        width="30%"
+        :before-close="handleClose">
+        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
+          <el-form-item label="打印机" prop="region">
+            <el-select v-model="ruleForm.region" placeholder="选择打印机">
+              <el-option :label="item.deviceName" :key="item.id" :value="item.id" v-for="(item,index) in printList"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+        <span slot="footer" class="dialog-footer">
+          <el-button @click="dialogVisible = false">取 消</el-button>
+          <el-button type="primary" :loading="dialogVisibleLoading" @click="print(viewerList)">{{ dialogVisibleLoading?'打印中...':'打印' }}</el-button>
+        </span>
+      </el-dialog>
+
+    </div>
+  </template>
+  
+  <script>
+  
+  import { pageList,printApi } from '@/api/windowTicketSales/ticketingCollection'
+  import { pageList as getPrintListApi } from "@/api/device/pda";
+  const https = require('https');
+  const axios = require('axios');
+  export default {
+    name: "distributionapplication",
+    dicts: ['order_form_type','order_status_type'],
+    data() {
+      return {
+        // 遮罩层
+        loading: false,
+        // 选中数组
+        multipleSelection: [],
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 用户表格数据
+        dataList: null,
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          // type: undefined
+          //orderStatus: "3"
+        },
+        visibleStatus: false,
+        visibleStatusLoading: false,
+        ruleForm: {},
+        rules: {
+          remark: [
+            { required: true, message: '请输入备注', trigger: ['blur','change'] },
+            { min: 0, max: 50, message: '长度在 0 到 50 个字符', trigger: ['blur','change'] }
+          ]
+        },
+        
+        viewerList: [],
+        printList: [],
+        dialogVisible: false,
+        ruleForm: {},
+        rules: {
+          region: [
+            { required: true, message: '请选择打印机', trigger: ['change','blur' ]}
+          ],
+        },
+        dialogVisibleLoading: false,
+
+        idcardLoading: false,
+      };
+    },
+    created() {
+      //this.getList();
+      //this.getPrintListApi()
+    },
+    methods: {
+      /** 查询列表 */
+      getList() {
+        this.loading = true;
+        pageList(this.queryParams)
+        .then(response => {
+            this.dataList = response.data.rows;
+            this.total = response.data.total;
+            this.loading = false;
+            console.log("this.multipleSelection=====",this.multipleSelection)
+          }
+        ).catch(()=>{
+          this.dataList = []
+          this.total = 0
+          this.loading = false
+        })
+      },
+      
+      // 取消按钮
+      cancel() {
+        this.open = false;
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.dateRange = [];
+        this.$set(this.queryParams, 'orderId', '');
+        this.$set(this.queryParams, 'qrcodeNo', '');
+        this.$set(this.queryParams, 'idcard', '');
+        this.$set(this.queryParams, 'mobile', '');
+        this.$set(this.queryParams, 'orderStatus', '');
+        this.$set(this.queryParams, 'seatName', '');
+        this.handleQuery();
+      },
+      setRemark(data) {
+        this.visibleStatus = true
+        this.resetForm.id = data.id
+      },
+      submitForm(formName) {
+          this.$refs[formName].validate(async (valid) => {
+            if (valid) {
+              try { 
+                this.visibleStatusLoading = true
+                let res = await setRemark({
+                  id: this.resetForm.id,
+                  "remark": this.ruleForm.remark
+                })
+                this.visibleStatus = false
+                this.visibleStatusLoading = false
+                this.resetForm('ruleForm')
+                this.queryParams.pageNum = 1;
+                this.getList()
+              } catch (error) {
+                this.visibleStatusLoading = false
+              }
+              
+            } else {
+              this.visibleStatusLoading = false
+              return false;
+            }
+          });
+        },
+        resetForm(formName) {
+          this.$refs[formName].resetFields();
+        },
+        handleSelectionChange(val) {
+          console.log("val====",val)
+          this.multipleSelection = val;
+        },
+        handleOpen(list=[]){
+          if(!list||list.length==0) return
+          let idList = []
+          list.forEach((item,index)=>{
+            idList.push(item.id)
+          }) 
+          this.viewerList = idList
+          this.getPrintListApi()
+          this.$set(this.ruleForm, 'region', '');
+          this.$nextTick(()=>{
+            this.$refs.ruleForm.clearValidate('region')
+          })
+          this.dialogVisible = true
+        },
+        handleClose(){
+          this.dialogVisible = false
+        },
+        /** 查询打印机列表 */
+        getPrintListApi() {
+          getPrintListApi({deviceType:5,pageNum: 1,
+          pageSize: 999,})
+          .then(response => {
+              this.printList = response.data.rows;
+          }).catch((error)=>{
+            console.log("error===",error)
+          }
+          );
+        },
+        /**  选择打印机  */
+        selectPrint(){
+
+        },
+        // 打印 
+        async print(list = []){
+          this.$refs.ruleForm.validate(async (valid) => {
+            if (valid) {
+              this.dialogVisibleLoading = true
+              try {
+                let res = await printApi({
+                  viewerList:list,
+                  source: 2,
+                  deviceId: this.ruleForm.region
+                })
+                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.dialogVisible = false
+                this.dialogVisibleLoading = false
+                console.error("error=====",error)
+              }
+            } else {
+              console.log('error submit!!');
+              return false;
+            }
+          });
+          
+        },
+        /**  连接打印机  */
+        connectPrint(url,data){
+          // let xhr = new XMLHttpRequest();
+          // xhr.withCredentials = true
+          
+          // xhr.onreadystatechange = ()=>{
+          // if(xhr.readyState == 4){ // 监听请求完成
+          //     if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){
+          //       console.log(xhr.responseText)
+          //       this.dialogVisible = false
+          //       this.dialogVisibleLoading = false
+          //     }else{
+          //       console.log('请求失败')
+          //       this.dialogVisible = false
+          //       this.dialogVisibleLoading = false
+          //     }
+          //   }
+          // }
+         
+          // xhr.open("post", url, true); // 异步请求
+          // xhr.setRequestHeader('Content-Type', 'application/json')
+          // xhr.send(JSON.stringify(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.dialogVisibleLoading = false
+          }).catch(()=>{
+            this.dialogVisible = false
+            this.dialogVisibleLoading = false
+          })
+          // 在 axios 请求时,选择性忽略 SSL
+          // const agent = new https.Agent({  
+          //   rejectUnauthorized: false
+          // });
+          // axios.post(
+          //   url, 
+          //   { httpsAgent: agent,...data }
+          //   ).then(()=>{
+          //   this.dialogVisible = false
+          //   this.dialogVisibleLoading = false
+          // })
+          // .catch(()=>{
+          //   this.dialogVisible = false
+          //   this.dialogVisibleLoading = 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.queryParams,"idcard",obj.resultContent.certNumber)
+          }else {
+            this.$message.error('读取失败!!!');
+          }
+          
+          this.idcardLoading = false
+          //return result;
+            console.log(result,obj)
+          }
+        }
+        
+  };
+  </script>

+ 11 - 0
src/views/windowTicketSales/ticketingInquiry.vue

@@ -0,0 +1,11 @@
+<template>
+    <!--  票务查询  -->
+    <div>
+        票务查询
+    </div>
+</template>
+<script>
+    export default {
+        
+    }
+</script>

+ 11 - 0
src/views/windowTicketSales/ticketingSales.vue

@@ -0,0 +1,11 @@
+<template>
+    <!--  票务售票  -->
+    <div>
+        票务售票
+    </div>
+</template>
+<script>
+    export default {
+        
+    }
+</script>