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

票务销售:增加批量锁定功能按钮

shipeng 3 сар өмнө
parent
commit
973fb6d48e

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

@@ -120,6 +120,15 @@ export const lockOrUnLock = (query) => {
   })
 }
 
+// 批量锁定
+export const batchLockApi = (query) => {
+  return request({
+    url: '/merchant/merchantSeatOccupy/batchLockOrUnLock',
+    method: 'post',
+    data: query
+  })
+}
+
 //  票务是否设置了价格
 
 export const selectRegion = (query) => {

+ 27 - 13
src/views/windowTicketSales/lock.vue

@@ -88,9 +88,10 @@
             <span>已勾选锁定座位:{{ seatSelectListNo.length }}</span>
             <el-button size="mini" type="warning" style="margin: 0 15px;"
               @click="clearSeatSelectListAll">清空已选座位</el-button>
-            <el-button size="mini" v-hasPermi="['windowTicketSales:ticket:lock']" type="danger"
+            <el-button size="mini" v-hasPermi="['windowTicketSales:ticket:lock']" type="warning"
               :loading="lockOrUnLockLoading" @click="lockOrUnLockFun(0)">{{
                 seatSelectListNo.length > 0 ? '解 锁' : '锁 定' }}</el-button>
+            <el-button size="mini" v-hasPermi="['window:ticket:batchlock']" type="danger" @click="batchLockFun">批量锁定</el-button>
           </div>
           <!-- <div style="width: 100%;display: flex;justify-content: center;height: 30px;">
             <el-button size="mini" v-hasPermi="['windowTicketSales:ticketingSales:lock']" type="warning"
@@ -157,6 +158,8 @@
     </div>
     <!--  锁座备注  -->
     <lock-seat ref="lockSeat" @querySeatListFun="querySeatListFun" />
+    <!--  批量锁座  -->
+    <batch-lock ref="batchLockSeat" @querySeatListFun="querySeatListFun" />
     <!--  添加观影人  -->
     <increaseViewers ref="increaseViewers" @clearDialogVisible="clearDialogVisible" />
 
@@ -187,11 +190,13 @@ import moment from "moment"
 import { pageList as getSeatType } from '@/api/seatTypeMr/seatTypeMr'
 import selectListMixin from "./mixins/selectList"
 import LockSeat from './model/lockSeat.vue'
+import batchLock from './model/batchLock.vue'
 export default {
   name: "Lock",
   components: {
     increaseViewers,
-    LockSeat
+    LockSeat,
+    batchLock
   },
   mixins: [selectListMixin],
   dicts: ['channel_type'],
@@ -324,21 +329,19 @@ export default {
     // 获取 日志
     async getSeatLockLogs() {
       let ids = []
-      console.log(this.seatSelectList,'this.seatSelectList');
+      // console.log(this.seatSelectList,'this.seatSelectList');
       if(this.seatSelectList.length > 0) {
         ids = this.seatSelectList.map(ele => ele.id)
       }
       if(this.seatSelectListNo.length > 0) {
         ids = this.seatSelectListNo.map(ele => ele.id)
       }
-      console.log(ids,'ids');
       this.logList = []
       let res = await seatLockLogs({
         auditoriumId: this.queryParams.auditoriumId,
         timeId: this.queryParams.timeId,
         seatIds: ids.join(','),
       })
-      console.log(res,'1111');
       if (res.code == 200) {
         this.logList = res.data.rows;
       }
@@ -369,7 +372,7 @@ export default {
         param.status = 1;
         let res = await merchantPerformTimeListNew(param)
         if (res.code == 200) {
-          console.log('merchantPerformTimeListS', res.data.rows);
+          // console.log('merchantPerformTimeListS', res.data.rows);
           this.merchantPerformTimeListS = res.data.list
 
         }
@@ -377,6 +380,18 @@ export default {
 
       }
     },
+    // 批量锁定
+    batchLockFun(){
+      let listS = this.seatSelectListNo.length > 0 ? this.seatSelectListNo : this.seatSelectList
+      if (listS.length <= 0) {
+        this.$message.info(`请选择需要锁定的座位!!!`);
+        return
+      }
+      if (this.seatSelectListNo.length == 0) {
+        this.$refs.batchLockSeat.openDialog(this.seatSelectListNo, this.seatSelectList, this.queryParams.auditoriumId, this.queryParams.timeId)
+      }
+
+    },
     /**  座位锁定/解锁  */
     async lockOrUnLockFun(type) {
       try {
@@ -495,12 +510,12 @@ export default {
           return a.sort - b.sort
         })
         this.seatMapListKey = seatMapListKey
-        console.log("seatMapListKey=====", seatMapListKey)
+        // console.log("seatMapListKey=====", seatMapListKey)
         this.width = 70 * (flog + 1)
         this.$nextTick(() => {
           if (this.$refs.seatbox) {
             var ele = this.$refs.seatbox
-            console.log(ele.getBoundingClientRect().width); // 100
+            // console.log(ele.getBoundingClientRect().width); // 100
             if (this.width < ele.getBoundingClientRect().width) {
               this.justifyContent = true
             } else {
@@ -511,7 +526,7 @@ export default {
           }
         })
 
-        console.log("list====", listCopy)
+        // console.log("list====", listCopy)
 
         let columnList = []
         listCopy[seatMapListKey[0].key].forEach((item, index) => {
@@ -608,7 +623,7 @@ export default {
     },
     /**  设置 场次 对应得剧目ID */
     changePerformId(value) {
-      console.log("value=====", value)
+      // console.log("value=====", value)
       this.performId = ''
       this.merchantPerformTimeListS.forEach((item, index) => {
         if (item.id == value) {
@@ -618,7 +633,7 @@ export default {
     },
     /**  设置 票务 对应价格 */
     changeSalePrice(value) {
-      console.log("value=====", value)
+      // console.log("value=====", value)
       this.salePrice = null
       this.goodsPageListS.forEach((item, index) => {
         if (item.goodsId == value) {
@@ -726,7 +741,6 @@ export default {
     },
     /** 删除已选座位  */
     delSeatSelect(row) {
-      console.log(row, 'row222');
 
       // row.isSelect = !row.isSelect
       // if(row.isSelect){
@@ -870,7 +884,7 @@ export default {
               left: (e.x + 10) + 'px',
               zIndex: 999999
             }
-            console.log('dsfdsff====', this.lockObj, this.lockStyle)
+            // console.log('dsfdsff====', this.lockObj, this.lockStyle)
             return
           } else {
             this.isLcokShow = false

+ 214 - 0
src/views/windowTicketSales/model/batchLock.vue

@@ -0,0 +1,214 @@
+<template>
+    <el-dialog :title="title" :visible.sync="dialogVisible" custom-class="custom-dialog" width="75%"
+        :before-close="handleClose">
+        <div class="dialog-content">
+            <div>
+                <span class="demonstration">选择月份:</span>
+                <el-date-picker v-model="performMonth" type="month" value-format="yyyy-MM" placeholder="选择月"
+                    @change="hanldeChange">
+                </el-date-picker>
+            </div>
+            <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
+                <el-button type="primary" icon="el-icon-finished" @click="handleCheckAllChange">{{ checkAll ?
+                    '取消全选' : '全选' }}</el-button>
+            </div>
+            <div v-loading="loading" style="margin: 0 20px;height: 430px;overflow-y: auto;">
+                <!-- <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
+                @change="handleCheckAllChange">全选</el-checkbox> -->
+                <el-checkbox-group v-model="checkedList" @change="handleCheckedChange">
+                    <el-checkbox v-for="item in performTimeList" :label="item.id" :key="item.id" :value="item.id">
+                        <span>{{ item.performDate + '(' +
+                            item.performTimeStart + '-' + item.performTimeEnd + ')' }}</span>
+                    </el-checkbox>
+                </el-checkbox-group>
+            </div>
+            <div v-loading="loading" style="margin-top: 20px;">
+                <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
+                    <el-form-item label="锁定原因" prop="remark">
+                        <el-input type="textarea" :rows="4" placeholder="请输入锁定原因" maxlength="250"
+                            v-model="ruleForm.remark" style="width: 80%;"></el-input>
+                    </el-form-item>
+                </el-form>
+            </div>
+        </div>
+
+        <span slot="footer" class="dialog-footer">
+            <el-button @click="handleClose">取 消</el-button>
+            <el-button :loading="loading" type="primary" @click="lockOrUnLockFun">提交</el-button>
+        </span>
+    </el-dialog>
+</template>
+<script>
+import {
+    lockOrUnLockApi,
+    lockOrUnLock,
+    batchLockApi,
+    merchantPerformTimeListNew
+} from "@/api/windowTicketSales/ticketingSales"
+import moment from "moment"
+
+export default {
+    name: "LockSeat",
+    data() {
+        return {
+            loading: false,
+            dialogVisible: false,
+            list: [],
+            title: '',
+            auditoriumId: '',
+            timeId: '',
+            ruleForm: {
+                remark: null
+            },
+            rules: {
+                remark: [
+                    { required: true, message: '请输入锁定原因', trigger: ['blur', 'change'] },
+                ]
+            },
+            checkAll: false,
+            checkedList: [],
+            performTimeList: [], // 场次
+            isIndeterminate: true,
+            performMonth: '',
+        }
+    },
+    methods: {
+        /**
+         * @param list 解锁列表
+         * @param list1 上锁列表
+         */
+        async openDialog(list = [], list1 = [], auditoriumId = null, timeId = null) {
+            this.auditoriumId = auditoriumId
+            // this.timeId = timeId
+            this.performMonth = moment().format("yyyy-MM")
+            this.merchantPerformTimeListFun();
+            this.list = list.length > 0 ? list : list1
+            this.title = '批量锁定座位'
+            // console.log(list, list1)
+            this.dialogVisible = true
+            this.$nextTick(() => {
+                if (list.length == 0) {
+                    this.$refs.ruleForm.clearValidate()
+                }
+            })
+        },
+        // 全选
+        handleCheckAllChange() {
+            this.checkAll = !this.checkAll
+            let ids = this.performTimeList.map(ele => ele.id)
+            this.isIndeterminate = false;
+            this.checkedList = this.checkAll ? ids : [];
+        },
+        handleCheckedChange(value) {
+            let checkedCount = value.length;
+            this.checkAll = checkedCount === this.performTimeList.length;
+            this.isIndeterminate = checkedCount > 0 && checkedCount < this.performTimeList.length;
+        },
+        // 选月份
+        hanldeChange() {
+            if (!this.performMonth) {
+                this.$message.info(`请选择月份查询场次!`);
+                return
+            }
+            // console.log(this.performMonth, 'this.performMonth');
+            this.merchantPerformTimeListFun();
+        },
+        /**  获取场次  */
+        async merchantPerformTimeListFun() {
+            try {
+                let param = {
+                    auditoriumId: this.auditoriumId,
+                    performMonth: this.performMonth,
+                    status: 1,
+                };
+                let res = await merchantPerformTimeListNew(param)
+                if (res.code == 200) {
+                    this.performTimeList = res.data.list
+
+                }
+            } catch (error) {
+
+            }
+        },
+        handleClose() {
+            this.ruleForm = {}
+            this.dialogVisible = false
+            this.checkAll = false
+            this.isIndeterminate = false;
+            this.checkedList = []
+        },
+        /**  批量座位锁定  */
+        async lockOrUnLockFun(type) {
+            try {
+                if (this.checkedList.length <= 0) {
+                    this.$message.info(`请勾选需要批量锁定座位的场次`);
+                    return
+                }
+                if (!this.ruleForm.remark) {
+                    this.$message.info(`请输入锁定原因`);
+                    return
+                }
+                this.loading = true
+                let list = []
+                this.list.forEach((item, index) => {
+                    list.push({
+                        "auditoriumId": this.auditoriumId,
+                        "seatId": item.id,
+                    })
+                })
+                let res = await batchLockApi({
+                    type: 0, // 类型 0锁定,1解锁
+                    seatList: list,
+                    remark: this.ruleForm.remark,
+                    timeIds: this.checkedList
+                })
+                this.loading = false
+                if (res.code) {
+                    this.$message({
+                        showClose: true,
+                        message: res.msg,
+                        type: 'success'
+                    });
+                    this.$emit('querySeatListFun', true)
+                    this.handleClose()
+                }
+
+            } catch (error) {
+                this.loading = false
+                this.$message({
+                    showClose: true,
+                    message: "操作失败!!!",
+                    type: 'error'
+                });
+                console.error('error===', error)
+            }
+
+        },
+    }
+}
+</script>
+<style lang="scss" scoped>
+::v-deep .el-checkbox {
+    color: #606266;
+    font-weight: 500;
+    font-size: 14px;
+    position: relative;
+    cursor: pointer;
+    display: inline-block;
+    white-space: nowrap;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    margin-right: 20px;
+    margin-bottom: 10px;
+    padding: 5px;
+    border: 1px solid #dcdada;
+    border-radius: 6px;
+}
+
+.dialog-content {
+    height: 660px;
+    overflow-y: auto;
+}
+</style>

+ 59 - 16
src/views/windowTicketSales/model/ticketInfo.vue

@@ -145,7 +145,7 @@
               show-word-limit></el-input>
           </el-form-item>
           <el-form-item>
-            <el-button :loading="loading" :disabled="isFlag" type="danger"
+            <el-button :loading="loading" :disabled="isFlag || !isDisabled" type="danger"
               style="width: 120px;height: 40px;font-size: 18px;" @click="submitForm('ruleForm11')">结 算</el-button>
           </el-form-item>
 
@@ -162,7 +162,13 @@
     </span> -->
 
     <!-- 添加 观影人员实名 -->
-    <el-dialog title="观影人员实名" modal-append-to-body :close-on-click-modal="false" :visible.sync="isVisible" width="85%">
+    <el-dialog title="观影人员实名" 
+      modal-append-to-body 
+      :close-on-click-modal="false" 
+      :visible.sync="isVisible"
+      @close="closeVisible" 
+      width="85%"
+    >
       <el-form :model="ValidateForm" ref="validateForm" label-width="90px">
         <el-form-item prop="type" label="证件类型:">
           <el-select v-model="ValidateForm.type" placeholder="请选择活动区域">
@@ -253,7 +259,7 @@
 
       <span slot="footer" class="dialog-footer">
         <el-button :disabled="isFlag" type="primary" @click="handleSubmit">保 存</el-button>
-        <el-button @click="isVisible = false">取 消</el-button>
+        <el-button @click="closeVisible">取 消</el-button>
       </span>
     </el-dialog>
 
@@ -431,7 +437,8 @@ export default {
       grantQuota: null, // 授信使用额度
 
       code: '', // 支付code
-      codeTime: null // 检测是websocket是否还在连接
+      codeTime: null, // 检测是websocket是否还在连接
+      isDisabled: true,
     };
 
   },
@@ -455,6 +462,10 @@ export default {
     }
   },
   methods: {
+    // 控制 结算按钮
+    setFlag() {
+      this.isDisabled = false;
+    },
     async initData(list, params) {
       try {
         this.code = ''
@@ -464,6 +475,7 @@ export default {
         this.personnelNum = params.personnelNum   // 人员要求:0-表示不限制 其他数字表示限制人数
         this.websocketClear()
         this.idcardLoading = false
+        this.isDisabled = true;
         this.ruleForm = {
           performId: params.performId, // 剧目ID
           retailId: "", // 分销ID
@@ -487,16 +499,16 @@ export default {
           remark: '', // 订单备注
           sourceRemark: '', //  来源备注
         }
-        console.log(this.ruleForm, 'this.ruleForm');
+        // console.log(this.ruleForm, 'this.ruleForm');
         this.payStatus = null
         this.orderId = null
         this.websocket_connected = false
         // this.dialogVisible = true
         // this.loading = true
         this.actionIndex = null
-        this.viewerList = []
+        // this.viewerList = []
         let perform = await this.selectRegionFun(params, list[0].seatTypeId)
-        // console.log("perform===", perform)
+        console.log("perform===", perform)
         // let perform = {
         //     money: params.salePrice,
         //     //name: params.goodsName,
@@ -505,19 +517,21 @@ export default {
         // }
         let listCopy = []
         if (list.length > 0) {
-          console.log(list, 'list11');
-
+          // console.log(list, 'list11');
           this.ifShow = true
           list.forEach((item, index) => {
             listCopy.push({
-              id: index + 1,
+              // id: index + 1,
+              id: this.uniqueNumberId(),
               name: '', // 姓名
               mobile: '', // 电话
               idcard: '', // 身份证
               identity: '0', // 观影人身份
               remark: '', // 备注信息
-              salePrice: this.oneMany == 2 || (this.oneMany == 1 && this.personnelNum != 0) ? index == 0 ? perform.money : 0 : perform.money, // 原价
-              realPrice: this.oneMany == 2 || (this.oneMany == 1 && this.personnelNum != 0) ? index == 0 ? perform.money : 0 : perform.money, // 实收金额
+           // salePrice: this.oneMany == 2 || (this.oneMany == 1 && this.personnelNum != 0) ? index == 0 ? perform.money : 0 : perform.money, // 原价
+           // realPrice: this.oneMany == 2 || (this.oneMany == 1 && this.personnelNum != 0) ? index == 0 ? perform.money : 0 : perform.money, // 实收金额
+              salePrice: this.oneMany == 2 || (this.oneMany == 1 && this.personnelNum != 0) ? index == 0 ? item.salePrice : 0 : item.salePrice, // 原价
+              realPrice: this.oneMany == 2 || (this.oneMany == 1 && this.personnelNum != 0) ? index == 0 ? item.salePrice : 0 : item.salePrice, // 实收金额
               seatId: item.id, // 座位ID
               seatName: item.name ? item.name : '暂无命名', // 座位名称
               seatType: perform.seatTypeId, // 座位类型
@@ -525,19 +539,39 @@ export default {
               seatTypeName: perform.seatTypeName,
             })
           })
+          if(this.viewerList.length > 0){
+            // 创建一个 Map 来存储 listCopy 的数据,以 seatId 为键
+            const map = new Map(listCopy.map(item => [item.seatId, item]));
+            // 遍历 this.viewerList,如果有相同的 seatId 就替换
+            this.viewerList.forEach(item => {
+              if (map.has(item.seatId)) {
+                const existing = map.get(item.seatId);
+                let obj1 = {
+                  name: item.name, // 姓名
+                  idcard: item.idcard, // 身份证
+                  identity: item.identity, // 观影人身份
+                  remark: item.remark, // 备注信息
+                }
+                map.set(item.seatId, {...existing, ...obj1});  // 替换
+              }
+            });
+            this.viewerList = Array.from(map.values());
+          } else {
+            this.viewerList = JSON.parse(JSON.stringify(listCopy))
+          }
         } else {
-          console.log(list, 'list12221');
           this.ifShow = false
+          this.viewerList = []
         }
         //this.goodsList = 
-        this.viewerList = JSON.parse(JSON.stringify(listCopy))
+        // this.viewerList = JSON.parse(JSON.stringify(listCopy))
         if (list.length > 0) {
           this.setMoneyAll()
         } else {
           this.moneyAll = ''
           this.$set(this.ruleForm, 'realPrice', this.moneyAll)
         }
-        // console.log(this.viewerList)
+        console.log(this.viewerList,'3333')
         // this.loading = false
 
         this.$nextTick(() => {
@@ -548,6 +582,10 @@ export default {
       }
 
     },
+    // 随机数
+    uniqueNumberId() {
+      return Number(Date.now() + Math.floor(Math.random() * 1000));
+    },
     /**  获取票务信息  */
     async selectRegionFun(params, seatTypeId) {
       try {
@@ -614,6 +652,11 @@ export default {
     handleRealName() {
       this.isVisible = true
     },
+    // 关闭 实名信息弹框
+    closeVisible() {
+      this.isVisible = false
+      this.actionIndex = null
+    },
     // 保存 观影人员实名信息
     handleSubmit() {
       this.isVisible = false
@@ -1333,7 +1376,7 @@ export default {
   },
   beforeDestroy() {
     // 组件销毁前执行的代码
-    console.log('组件即将销毁');
+    // console.log('组件即将销毁');
     document.removeEventListener('keydown', this.keydownAdd);
   },
 }

+ 13 - 8
src/views/windowTicketSales/ticket.vue

@@ -16,6 +16,7 @@
         <el-select 
           v-model="queryParams.timeId" 
           placeholder="场次" 
+          @change="handleQuery"
           clearable style="width: 100%"
         >
           <el-option v-for="dict in merchantPerformTimeListS" :key="dict.id"
@@ -63,7 +64,7 @@
       </div>
       <el-empty v-else :image-size="200"></el-empty>
     </div>
-    <el-button class="btnClass" type="danger" @click="handleBuyTicket">确 定</el-button>
+    <!-- <el-button class="btnClass" type="danger" @click="handleBuyTicket">确 定</el-button> -->
     
   </div>
 </template>
@@ -136,6 +137,7 @@ export default {
     moment,
     selectItem(item) {
       this.queryParams.goodsId = item.goodsId;
+      this.handleBuyTicket();
     },
     // 跳转到票务销售
     handleBuyTicket() {
@@ -282,6 +284,7 @@ export default {
     /** 搜索按钮操作 */
     handleQuery() {
       this.$refs.queryForm.validate((valid) => {
+        this.loading = true
         if (valid) {
           // this.querySeatListFun(true);
           this.$set(this.queryParams, 'goodsId', '')
@@ -295,7 +298,9 @@ export default {
           setTimeout(() => {
             this.goodsPageListS = list2
           }, 500)
+          this.loading = false
         } else {
+          this.loading = false
           console.log('error submit!!', valid);
           return false;
         }
@@ -360,13 +365,13 @@ export default {
     }
     
   }
-  .btnClass {
-    width: 100px;
-    height: 40px;
-    position: fixed;
-    right: 40px;
-    bottom: 40px;
-  }
+  //.btnClass {
+  //  width: 100px;
+  //  height: 40px;
+  //  position: fixed;
+  //  right: 40px;
+  //  bottom: 40px;
+  //}
 }
 
 </style>

+ 1 - 0
src/views/windowTicketSales/ticketSales.vue

@@ -930,6 +930,7 @@ export default {
                 if (this.personnelNum != 0) {
                     if (this.seatSelectList.length != this.personnelNum) {
                         this.$message.error(`票务类型设置了实名要求,选择人数为${this.personnelNum}人`);
+                        this.$refs.increaseViewers.setFlag();
                         return
                     }
                 }