| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678 |
- <template>
- <div>
- <el-card>
- <template slot="header">
- <div
- class="card-title"
- style="display:flex;"
- v-if="currentTicket">
- <div style="display:flex;">
- <div class="top-title">当前票种:<b>{{ currentTicket.name || '无' }}</b></div>
- <span v-if="currentTicket.isSale === 0" style="color: red">(停售)</span>
- <div v-if="category === 'batch'" style="margin-left: 20px;">当前场次:<b>{{ currentBatchName || '无' }}</b></div>
- </div>
- <div>{{ form.playDateBegin | formatDate }} 票价:<span class="price"><b>{{ currentPrice }}</b> 元</span></div>
- </div>
- <span
- v-else
- style="color:red">请选择门票</span>
- </template>
- <el-form
- v-loading="loading"
- class="sale-form-wrap"
- ref="form"
- :model="form"
- :inline="true"
- label-width="100px">
- <el-form-item
- v-if="isTeam"
- verify
- required
- label="团体">
- <el-select
- filterable
- v-model="form.teamId">
- <el-option
- v-for="item in teamList"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item
- v-if="isTeam"
- label="导游">
- <el-select
- filterable
- v-model="form.guideId">
- <el-option
- v-for="item in guideList"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item
- verify
- can-be-empty
- label="顾客姓名"
- prop="buyerName">
- <el-input
- v-model="form.buyerName"></el-input>
- </el-form-item>
- <el-form-item
- can-be-empty
- :verify="verifyPhone"
- label="顾客电话"
- prop="buyerPhone">
- <el-input
- v-model="form.buyerPhone"></el-input>
- </el-form-item>
- <el-form-item
- label="证件类型"
- prop="buyerIdentifyType">
- <el-select
- :disabled="identifyLockCheckStyle"
- v-model="form.buyerIdentifyType"
- placeholder="请选择">
- <el-option
- v-for="(item, idx) in papersType"
- :key="`id-${idx}`"
- :label="item.label"
- :value="item.value">
- </el-option>
- </el-select>
- <el-checkbox
- style="margin-left:10px"
- v-model="identifyLockCheckStyle">
- 锁定
- </el-checkbox>
- </el-form-item>
- <!-- <el-form-item
- key="id1"
- :verify="form.buyerIdentifyType === 0 ? verifyId : ''"
- can-be-empty
- v-if="form.buyerIdentifyType === 0"
- label="证件号码"
- prop="buyerIdentify">
- <ReaderInput
- type="ID"
- @change="form.buyerName = $event.Name,Certificate=$event"
- @input="form.buyerIdentify = $event"
- v-model="form.buyerIdentify"></ReaderInput>
- </el-form-item> -->
- <el-form-item
- key="id2"
- label="证件号码"
- prop="buyerIdentify">
- <el-input v-model="form.buyerIdentify"></el-input>
- </el-form-item>
- <el-form-item
- v-if="Certificate.Nation"
- label="国家"
- >
- {{ Certificate.Nation }}
- </el-form-item>
- <el-form-item
- v-if="Certificate.Sex"
- label="性别"
- >
- {{ Certificate.Sex }}
- </el-form-item>
- <el-form-item
- v-if="Certificate.ValidDate"
- label="有效截止日期"
- >
- {{ Certificate.ValidDate }}
- </el-form-item>
- <el-form-item
- prop="playDateBegin"
- label="游玩日期">
- <el-date-picker
- :clearable="false"
- type="date"
- :editable="false"
- disabled
- :picker-options="dateOption"
- v-model="form.playDateBegin"
- >
- </el-date-picker>
- </el-form-item>
- <el-form-item
- prop="playDateEnd"
- label="结束日期">
- <el-date-picker
- :clearable="false"
- :editable="false"
- disabled
- :picker-options="dateOption"
- v-model="form.playDateEnd"
- type="date"
- >
- </el-date-picker>
- </el-form-item>
- <el-form-item
- verify
- number
- label="购买数量"
- prop="count"
- >
- <el-input-number
- ref="ticketCount"
- name="ticket-count"
- v-model.number="form.count"
- :min="1"
- :max="10000"
- :precision="0"
- ></el-input-number>
- </el-form-item>
- <el-form-item
- label="检票方式"
- prop="checkWay">
- <el-select
- v-model="form.checkWay"
- :disabled="retailLockCheckStyle">
- <el-option
- v-for="item in checkWayList"
- :key="item.val"
- :value="item.val"
- :label="item.name"
- ></el-option>
- </el-select>
- <el-checkbox
- style="margin-left:10px"
- v-model="retailLockCheckStyle">
- 锁定
- </el-checkbox>
- </el-form-item>
- <!-- v-if="form.checkWay === 3 || form.checkWay === 4" -->
- <el-form-item
- label="游客信息"
- >
- <div
- v-if="currentTicket"
- class="input-space"
- >
- <el-button
- type="primary"
- size="small"
- icon="el-icon-edit"
- @click="showTouristList"
- >
- 编辑查看
- </el-button>
- </div>
- </el-form-item>
- </el-form>
- <div class="btn-wrap">
- <el-button
- @click="resetForm"
- style="margin-right:20px">
- 重置表单
- </el-button>
- <el-button
- type="primary"
- @click="addToOrder">
- 加入订单
- </el-button>
- </div>
- </el-card>
- <!-- 游客列表 -->
- <TouristList
- :check-ticket-no="needCheckTicket"
- :check-face="needCheckFace"
- :check-id="needCheckId"
- :check-ic="needCheckIc"
- :tourist-list="touristList"
- :update-tourist="updateTourist"
- ref="touristList"></TouristList>
- </div>
- </template>
- <script>
- import { randomString } from '@/utils'
- import { verifyId, verifyPhone } from '@/utils/validate'
- import { checkWayList } from '@/assets/staticData'
- import { setTourist } from '@/pages/common'
- import TouristList from '../common/TouristList'
- // import ReaderInput from '@/components/ReaderInput'
- import moment from 'moment'
- import { IDENTIFY_TYPES } from '@/const'
- import { getTeamList, getGuideList } from '@/api/checker'
- export default {
- props: {
- currentTicket: {
- type: Object,
- default: () => null
- },
- currentBatch: {
- type: Object,
- default: () => null
- },
- orderItems: {
- type: Array,
- default: () => []
- }
- },
- components: {
- TouristList
- // ReaderInput
- },
- computed: {
- category () {
- return this.$route.meta.category || 'ticket'
- },
- isTeam () {
- return this.$route.meta.type === 'team'
- },
- totalPrice () {
- if (!this.currentTicket) {
- return 0
- }
- return this.$NP.times(this.currentPrice, this.form.count)
- },
- scenicName () {
- return this.$store.state.user.scenicName
- },
- currentBatchName () {
- if (!this.currentTicket || !this.currentBatch) return ''
- const { name, startTime, endTime } = this.currentBatch
- return name ? `${name} ${startTime} - ${endTime}` : ''
- },
- needCheckTicket () {
- return this.form.checkWay === 5
- },
- needCheckId () {
- const { category, currentTicket } = this
- return category === 'member' && currentTicket.checkType.includes('idcard')
- },
- needCheckFace () {
- const { category, currentTicket } = this
- return category === 'member' && currentTicket.checkType.includes('face')
- },
- needCheckIc () {
- const { category, currentTicket } = this
- return category === 'member' && currentTicket.checkType.includes('card')
- }
- },
- data () {
- return {
- loading: false,
- keyControl: 2, // 键盘控制:1,2,3标识选中顺序
- isFocus: false, // 当前组件是否选中
- papersType: IDENTIFY_TYPES,
- checkWayList,
- pricePlan: [],
- currentPrice: 0,
- currentPlan: null,
- retailLockCheckStyle: this.$localStore.get('retailLockCheckStyle') || false,
- identifyLockCheckStyle: this.$localStore.get('identifyLockCheckStyle') || false,
- touristList: [{
- batchConfigId: randomString(),
- guestName: '',
- guestPhone: '',
- guestIdentify: '',
- guestIdentifyType: 0,
- ticketTypeId: 0,
- checkNum: 1,
- price: 0,
- seatId: 0,
- playDateBegin: new Date(moment().startOf('day').valueOf()),
- lock: false // 是否可编辑
- }],
- form: {
- buyerIdentify: '',
- buyerName: '',
- buyerIdentifyType: 0,
- buyerPhone: '',
- groupIndividual: 1,
- count: this.$localStore.get('initNum') === '空' ? undefined : 1,
- payChannel: '现金',
- playDateBegin: new Date(moment().startOf('day').valueOf()),
- playDateEnd: '',
- price: 0,
- teamId: '',
- guideId: '',
- checkWay: this.isTeam ? 2 : 1,
- actualMoney: 0 // 实付金额,不需要传给后台
- },
- Certificate: {
- },
- dateOption: {
- // 日历禁用日期
- disabledDate () {
- return false
- }
- },
- disablePlayDateBegin: false,
- teamList: [],
- guideList: []
- }
- },
- created () {
- if (this.isTeam) {
- getTeamList({ pageSize: -1, pageNum: 1 }).then(res => {
- this.teamList = res.data.records || []
- })
- getGuideList({ pageSize: -1, pageNum: 1 }).then(res => {
- this.guideList = res.data.records || []
- })
- }
- },
- methods: {
- verifyId,
- verifyPhone,
- randomString,
- setFocus () {
- this.$refs.ticketCount.focus()
- this.$refs.ticketCount.select()
- },
- resetForm () {
- this.touristList = [{
- batchConfigId: randomString(),
- guestName: '',
- guestPhone: '',
- guestIdentify: '',
- guestIdentifyType: 0,
- lock: false // 是否可编辑
- }]
- this.$refs.form.resetFields()
- this.form.checkWay = this.isTeam ? 2 : 1
- this.Certificate = {}
- },
- setEndDate (val) {
- const { category, currentTicket } = this
- const { useDateType, memberUseDateType, useDays } = currentTicket
- if ((category === 'ticket' && useDateType === 1) || (category === 'member' && memberUseDateType === 2)) {
- this.form.playDateEnd = moment(val).add((useDays || 1) - 1, 'days').format('YYYY-MM-DD')
- }
- if (category === 'batch') {
- this.form.playDateEnd = moment(val).format('YYYY-MM-DD')
- }
- if (category === 'member' && memberUseDateType === 1) {
- this.form.playDateEnd = moment(val).add((useDays || 1) - 1, 'days').format('YYYY-MM-DD')
- }
- },
- // 更新游客列表
- updateTourist (data) {
- this.form.count = data.length
- this.touristList = data
- },
- // 同步游客数据与游客数
- syncTouristList () {
- let num = this.form.count - this.touristList.length
- setTourist(this.touristList, num)
- },
- // 显示游客弹窗
- showTouristList () {
- this.syncTouristList()
- this.$refs.touristList.show()
- },
- isPlayToday () {
- const isBefore = moment(this.form.playDateBegin).isBefore(moment().format('YYYY-MM-DD'))
- const isAfter = moment(this.form.playDateBegin).isAfter(moment().format('YYYY-MM-DD'))
- return !(isBefore || isAfter)
- },
- addToOrder (callback) {
- if (this.currentTicket && this.currentTicket.isSale === 0) {
- return this.$message.error('当前票种已停售')
- }
- if (!this.isPlayToday()) {
- // 客户端下单的时候游玩日期不是当天,提示一下
- this.$message.warning('友情提示:您下单的游玩日期不是今天!')
- }
- if (!this.currentTicket) {
- return this.$message.error('请选择门票')
- }
- if (this.category === 'batch') {
- if (!this.currentBatch) {
- return this.$message.error('请选场次')
- }
- if (this.currentBatch.leftNums !== -1) {
- if (this.currentBatch.leftNums === 0) {
- return this.$message.error('当前场次已售罄')
- }
- if (this.currentBatch.leftNums < this.form.count) {
- return this.$message.error('当前场次剩余票数不足')
- }
- }
- }
- if (this.loading) return
- this.$refs.form.validate((valid) => {
- if (valid) {
- this.syncTouristList()
- const { playDateBegin, playDateEnd } = this.form
- const { currentBatch } = this
- const { id, name, checkCount, isUseDateLimit } = this.currentTicket
- const price = this.currentPrice
- const originalPrice = this.currentPrice
- if (this.isTeam) {
- if (!this.form.teamId) {
- this.$message.error('请选择团队')
- return
- }
- }
- if (this.form.checkWay === 3) {
- // 是否存在未填写的内容
- let blankData = this.touristList.find(item => {
- return !item.guestName || !item.guestIdentify
- })
- if (blankData) {
- this.$message.error('游客信息不完整,请编辑查看')
- return
- }
- }
- if (this.form.checkWay === 4) {
- // 是否存在未填写的内容
- let blankData = this.touristList.find(item => {
- return !item.face
- })
- if (blankData) {
- this.$message.error('游客人脸信息不完整,请编辑查看')
- return
- }
- }
- const pdb = moment(playDateBegin).format('YYYY-MM-DD')
- const pde = moment(playDateEnd).format('YYYY-MM-DD')
- let tickets = this.touristList.map(item => {
- return {
- ...item,
- ticketTypeId: id,
- checkNum: checkCount,
- price,
- originalPrice,
- discountPrice: 0,
- ticketNo: item.ticketNo,
- batchConfigId: currentBatch?.id || '',
- face: item.face,
- isPrepare: this.form.checkWay === 5 ? 1 : 0,
- pricePlanId: this.currentPlan || 0,
- playDateBegin: pdb,
- playDateEnd: pde
- }
- })
- // 合并游玩日期相同的票种数据
- const existItem = this.orderItems.find(i => {
- let dateIsEque
- if (isUseDateLimit) {
- dateIsEque = JSON.stringify(i.playDateBegin) === JSON.stringify(pdb)
- } else {
- dateIsEque = true
- }
- // 日期对象不全等
- return i.id === id && dateIsEque && i.price === this.currentPrice
- })
- if (existItem) {
- Object.assign(existItem, this.form)
- existItem.tickets = existItem.tickets.concat(tickets)
- existItem.count = existItem.tickets.length
- existItem.total = this.$NP.plus(existItem.total, this.totalPrice)
- } else {
- this.orderItems.push({
- ...this.form,
- keyId: randomString(), // 唯一标识
- id, // 票种Id
- ticketName: name,
- count: tickets.length,
- price,
- originalPrice,
- discountPrice: 0,
- total: this.totalPrice,
- playDateBegin: pdb,
- currentTicket: {
- ...this.currentTicket,
- pricePlanId:
- this.currentPlan,
- price,
- playDateBegin: pdb,
- playDateEnd: pde
- },
- tickets
- })
- }
- // 重置游客数量
- this.touristList = [{
- batchConfigId: randomString(),
- guestName: '',
- guestPhone: '',
- guestIdentify: '',
- guestIdentifyType: 0,
- playDateBegin: moment().format('YYYY-MM-DD'),
- lock: false // 是否可编辑
- }]
- this.form.count = this.$localStore.get('initNum') === '空' ? undefined : 1
- if (callback && typeof callback === 'function') {
- callback()
- }
- this.$nextTick(() => {
- this.$refs.form.clearValidate()
- })
- }
- })
- },
- setPrice (price) {
- this.currentPrice = price || this.currentTicket.price
- this.form.price = this.currentPrice
- },
- defaultPapersType () {
- if (process.env.VUE_APP_PROJECT === 'zql') {
- return 0
- } else if (this.$localStore.get('retail_identify')) {
- return this.$localStore.get('retail_identify')
- } else {
- return ''
- }
- }
- },
- watch: {
- async currentTicket (val) {
- if (!val) return
- await this.$nextTick()
- this.resetForm()
- const { useDateType, useDateStart, useDateEnd, useDays, memberUseDateType, playDate } = val
- this.disablePlayDateBegin = false
- switch (this.category) {
- case 'ticket':
- if (useDateType === 2) {
- this.form.playDateBegin = moment(useDateStart).format('YYYY-MM-DD')
- this.form.playDateEnd = moment(useDateEnd).format('YYYY-MM-DD')
- this.disablePlayDateBegin = true
- } else {
- this.form.playDateBegin = moment(playDate).format('YYYY-MM-DD')
- this.form.playDateEnd = moment(playDate).add((useDays || 1) - 1, 'days').format('YYYY-MM-DD')
- }
- break
- case 'batch':
- this.form.playDateBegin = moment(playDate).format('YYYY-MM-DD')
- this.form.playDateEnd = moment(playDate).format('YYYY-MM-DD')
- this.disablePlayDateBegin = true
- break
- case 'member':
- if (memberUseDateType === 1) {
- this.form.playDateBegin = moment(playDate).format('YYYY-MM-DD')
- this.form.playDateEnd = moment(playDate).add((useDays || 1) - 1, 'days').format('YYYY-MM-DD')
- } else {
- this.form.playDateBegin = moment(useDateStart).format('YYYY-MM-DD')
- this.form.playDateEnd = moment(useDateEnd).format('YYYY-MM-DD')
- }
- this.disablePlayDateBegin = true
- break
- default :
- break
- }
- // 设置不可选日期
- this.dateOption.disabledDate = (date) => {
- let beforeToday = moment().subtract(1, 'days').isAfter(date)
- let beforeStart = moment(val.useDateStart).isAfter(date)
- let afterEnd = moment(val.useDateEnd).isBefore(date)
- return beforeToday || beforeStart || afterEnd
- }
- this.timer && clearTimeout(this.timer)
- this.timer = setTimeout(() => {
- this.setPrice(this.currentTicket.price)
- }, 300)
- },
- retailLockCheckStyle (val) {
- if (val) {
- this.$localStore.set('retailCheckWay', this.form.checkWay)
- }
- this.$localStore.set('retailLockCheckStyle', val)
- },
- identifyLockCheckStyle (val) {
- if (val) {
- this.$localStore.set('retail_identify', this.form.buyerIdentifyType)
- }
- this.$localStore.set('identifyLockCheckStyle', val)
- },
- 'form.playDateBegin' (val) {
- if (val) {
- this.setEndDate(val)
- this.currentPlan = null
- this.$emit('changePlayDate', moment(val).format('YYYY-MM-DD'))
- this.timer && clearTimeout(this.timer)
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .el-input,.el-select,.el-date-editor,.el-date-editor.el-input,.el-input-number {
- width: 200px;
- }
- </style>
|