quickSell.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <template>
  2. <el-form
  3. class="sell-form"
  4. ref="form"
  5. :model="form"
  6. :inline="true"
  7. label-width="100px"
  8. >
  9. <div class="sell-form-inner">
  10. <div class="top-block">
  11. <div class="side-content">
  12. <TickList
  13. type-id="1"
  14. @update="handleTicketUpdate"
  15. slot="left"
  16. ></TickList>
  17. </div>
  18. <div class="main-content">
  19. <div
  20. class="content-inner custom-scroll block-wrap"
  21. id="guest-list-card">
  22. <div
  23. class="block-title"
  24. v-if="currentTicket"
  25. >
  26. 当前票种:<b>{{ currentTicket.name }}</b>(请刷身份证)
  27. </div>
  28. <el-table
  29. border
  30. stripe
  31. width="100%"
  32. :max-height="tableHeight"
  33. :data="guestList"
  34. >
  35. <el-table-column
  36. label="#"
  37. type="index"
  38. >
  39. </el-table-column>
  40. <el-table-column
  41. prop="guestName"
  42. label="游客姓名"
  43. >
  44. <template slot-scope="scope">
  45. {{ scope.row.guestName || '(空)' }}
  46. </template>
  47. </el-table-column>
  48. <el-table-column
  49. label="身份证"
  50. >
  51. <template slot-scope="scope">
  52. {{ scope.row.guestIdentify || '(空)' }}
  53. </template>
  54. </el-table-column>
  55. <el-table-column label="操作">
  56. <template slot-scope="scope">
  57. <span
  58. class="el-button el-button--primary el-button--mini"
  59. @click="delTicket(scope.row.idKey)"
  60. >
  61. <i class="el-icon-delete"></i>
  62. 删除
  63. </span>
  64. </template>
  65. </el-table-column>
  66. </el-table>
  67. </div>
  68. <div class="footer block-wrap">
  69. <el-form-item label="订单总金额">
  70. <div class="input-space warning">
  71. <b class="strong">
  72. {{ totalPrice }}
  73. </b> 元
  74. </div>
  75. </el-form-item>
  76. <el-form-item
  77. class="is-required"
  78. label="付款方式"
  79. prop="payChannel"
  80. >
  81. <el-select
  82. v-model="form.payChannel">
  83. <el-option
  84. v-for="item in payChannelOptions"
  85. :key="item"
  86. :value="item"
  87. :label="item"
  88. ></el-option>
  89. </el-select>
  90. </el-form-item>
  91. <el-form-item label="实付金额">
  92. <el-input-number
  93. :min="0"
  94. :step="0.01"
  95. :precision="2"
  96. :controls="false"
  97. v-model.number="form.actualMoney"
  98. ></el-input-number>
  99. </el-form-item>
  100. <el-form-item
  101. :label="payBack>0?'找零':'还需支付'"
  102. v-if="payBack!==0"
  103. >
  104. <div class="input-space">
  105. <b class="strong">
  106. {{ Math.abs(payBack) }}
  107. </b> 元
  108. </div>
  109. </el-form-item>
  110. <div class="btn-wrap">
  111. <div class="right">
  112. <el-checkbox
  113. v-model="autoPrint"
  114. style="margin-right:30px"
  115. @change="handleAutoPrintChange"
  116. >
  117. 自动打印
  118. </el-checkbox>
  119. <el-button
  120. type="default"
  121. size="medium"
  122. @click="reset"
  123. >
  124. 重置
  125. </el-button>
  126. <el-button
  127. type="primary"
  128. class="warnBtn"
  129. size="medium"
  130. :disabled="submitDisable"
  131. @click="confirm"
  132. >
  133. {{ submitDisable?'正在处理':'确认出票' }}
  134. </el-button>
  135. </div>
  136. </div>
  137. </div>
  138. </div>
  139. </div>
  140. </div>
  141. <ElDialog
  142. title="确认出票"
  143. v-model="confirmDialogVisible">
  144. <ConfirmDialog
  145. @submit="submit"
  146. :current-ticket="currentTicket"
  147. :guest-list="guestList"
  148. :total-price="totalPrice"
  149. />
  150. </ElDialog>
  151. <ReadValueCard
  152. ref="readValueCard"
  153. @getInfo="handleValueCardPay"
  154. @close="submitDisable=false"></ReadValueCard>
  155. </el-form>
  156. </template>
  157. <script>
  158. import TickList from './common/TicketList'
  159. import { createOrder, getSingleOrder } from '@/api/order'
  160. import { createValueCardOrder } from '@/api/valueCard'
  161. import { getIdInfo } from '@/api/ZTKReaderApi'
  162. import { getPayChannel } from '@/api/systemConfig'
  163. import { getTicketTypeInfo } from '@/api/ticketType'
  164. import ReadValueCard from './common/ReadValueCard'
  165. import moment from 'moment'
  166. import ElDialog from '@/components/Dialog'
  167. import ConfirmDialog from './quickSell/ConfirmDialog'
  168. import posMixin from '@/pages/common/posMixin'
  169. import handlePay from './common/handlePay'
  170. export default {
  171. mixins: [posMixin],
  172. components: {
  173. TickList,
  174. ElDialog,
  175. ConfirmDialog,
  176. ReadValueCard
  177. },
  178. computed: {
  179. model () {
  180. return {
  181. guestData: this.guestData
  182. }
  183. },
  184. totalPrice () {
  185. if (!this.currentTicket) {
  186. return 0
  187. }
  188. return this.currentTicket.price * this.form.count
  189. },
  190. payBack () {
  191. if (this.form.actualMoney === undefined) {
  192. return (-this.totalPrice * 1000) / 1000
  193. } else {
  194. return (this.form.actualMoney * 1000 - this.totalPrice * 1000) / 1000
  195. }
  196. }
  197. },
  198. data () {
  199. return {
  200. submitDisable: false,
  201. currentTicket: null,
  202. currentPrice: 0,
  203. autoPrint: this.$localStore.get('autoPrint'),
  204. finished: false,
  205. visible: false,
  206. idKey: 0,
  207. guestList: [],
  208. currentPrint: null,
  209. orderInfo: null,
  210. qrImg: '',
  211. form: {
  212. payChannel: '现金',
  213. actualMoney: 0,
  214. count: 0,
  215. buyerIdentify: '',
  216. buyerName: '',
  217. buyerIdentifyType: 1,
  218. buyerPhone: '',
  219. groupIndividual: 1,
  220. payDateBegin: new Date(),
  221. playDateEnd: '',
  222. price: 0
  223. },
  224. payChannelOptions: [],
  225. tableHeight: 300,
  226. confirmDialogVisible: false
  227. }
  228. },
  229. methods: {
  230. handleTicketUpdate (ticket) {
  231. this.currentTicket = ticket
  232. },
  233. formatDateTime (input) {
  234. return moment(input).format('YYYY-MM-DD HH:mm:ss')
  235. },
  236. formatDate (input) {
  237. return moment(input).format('YYYY-MM-DD')
  238. },
  239. setEndDate () {
  240. if (!this.form.payDateBegin) return
  241. let endDate = moment(this.form.payDateBegin).add(this.currentTicket.useDays - 1, 'days')
  242. let endTime = endDate.format('YYYY-MM-DD') + ' 23:59:59'
  243. this.form.playDateEnd = new Date(endTime)
  244. },
  245. async getIdInfo () {
  246. if (this.finished) return
  247. this.timer && clearTimeout(this.timer)
  248. let idInfo = await getIdInfo()
  249. idInfo.Certificate && this.addTicket(idInfo.Certificate)
  250. this.timer = setTimeout(() => {
  251. this.getIdInfo()
  252. }, 300)
  253. },
  254. addTicket (data) {
  255. let existInfo = this.guestList.find(item => {
  256. return data.IDNumber === item.guestIdentify
  257. })
  258. if (existInfo) return
  259. let guestInfo = {
  260. idKey: this.idKey++,
  261. guestName: data.Name,
  262. guestPhone: '',
  263. guestIdentify: data.IDNumber
  264. }
  265. this.guestList.unshift(guestInfo)
  266. this.form.count++
  267. },
  268. delTicket (id) {
  269. let index = this.guestList.findIndex(item => {
  270. return item.idKey === id
  271. })
  272. this.guestList.splice(index, 1)
  273. this.form.count--
  274. },
  275. reset () {
  276. this.$refs.form.resetFields()
  277. this.form.count = 0
  278. this.guestList = []
  279. },
  280. confirm () {
  281. if (this.guestList.length === 0) {
  282. this.$message.error('请刷身份证,录入信息')
  283. return
  284. }
  285. this.confirmDialogVisible = true
  286. },
  287. submit () {
  288. if (this.submitDisable) return
  289. this.submitDisable = true
  290. let tickets = this.guestList.map(item => {
  291. return {
  292. ticketTypeId: this.currentTicket.id,
  293. checkNum: this.currentTicket.check_count,
  294. price: this.currentPrice,
  295. guestName: item.guestName,
  296. guestPhone: item.guestPhone,
  297. guestIdentify: item.guestIdentify,
  298. payDateBegin: this.form.payDateBegin,
  299. playDateEnd: this.form.playDateEnd
  300. }
  301. })
  302. let params = Object.assign({}, this.form)
  303. params.price = this.totalPrice
  304. params.tickets = tickets
  305. this.params = params
  306. handlePay(params, this, () => {
  307. this.createOrder(params)
  308. })
  309. },
  310. handleValueCardPay (cardInfo) {
  311. console.log('储值卡信息', cardInfo)
  312. // console.log(createValueCardOrder)
  313. createValueCardOrder({
  314. cardNo: cardInfo.cardCode,
  315. cardVendor: 'CHANGYI',
  316. order: this.params
  317. }).then(res => {
  318. this.$message.success('出票成功。')
  319. this.handleCreateSuccess(res)
  320. })
  321. },
  322. createOrder (params) {
  323. createOrder(params).then(res => {
  324. this.handleCreateSuccess(res)
  325. }).finally(() => {
  326. this.submitDisable = false
  327. })
  328. },
  329. handleCreateSuccess (res) {
  330. this.$message.success('出票成功')
  331. this.reset()
  332. this.guestList = []
  333. // 获取订单详情
  334. this.autoPrint && getSingleOrder(res?.data).then(order => {
  335. this.$print(order)
  336. })
  337. },
  338. handleAutoPrintChange (val) {
  339. this.$localStore.set('autoPrint', val)
  340. },
  341. setPrice () {
  342. this.loading = true
  343. getTicketTypeInfo({
  344. id: this.currentTicket.id,
  345. start: moment(this.form.payDateBegin).format('YYYY-MM-DD'),
  346. end: moment(this.form.payDateBegin).format('YYYY-MM-DD')
  347. }).then(res => {
  348. this.currentPrice = res?.data.prices[0] ? res?.data.prices[0].price : 0
  349. }).finally(() => {
  350. this.loading = false
  351. })
  352. }
  353. },
  354. mounted () {
  355. let elem = document.getElementById('guest-list-card')
  356. this.tableHeight = elem.offsetHeight - 82
  357. this.getIdInfo()
  358. getPayChannel().then(res => {
  359. this.payChannelOptions = res
  360. this.form.payChannel = this.payChannelOptions[0]
  361. })
  362. },
  363. watch: {
  364. currentTicket (val) {
  365. if (!val) return
  366. // 设置初始日期
  367. if (moment(val.useDateStart).isAfter(new Date())) {
  368. this.form.payDateBegin = val.useDateStart
  369. } else {
  370. this.form.payDateBegin = new Date(moment().startOf('day').valueOf())
  371. }
  372. this.setPrice()
  373. },
  374. 'form.payDateBegin' (val) {
  375. if (val) {
  376. this.setEndDate()
  377. this.setPrice()
  378. }
  379. },
  380. totalPrice (val) {
  381. this.form.actualMoney = val
  382. }
  383. },
  384. beforeDestroy () {
  385. this.timer && clearTimeout(this.timer)
  386. this.finished = true
  387. this.killAllPosProcess()
  388. }
  389. }
  390. </script>
  391. <style scoped>
  392. </style>