SmallTicketPrintTemplate.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <template>
  2. <div
  3. class="print-wrap"
  4. v-show="true"
  5. >
  6. <div
  7. id="printMe"
  8. ref="printMe"
  9. :style="{}"
  10. v-if="customStyle"
  11. >
  12. <div
  13. class="wrap"
  14. v-for="(layout,index) in customStyle"
  15. :key="index">
  16. <div
  17. :style="layout"
  18. v-for="(child,idx) in layout.children"
  19. :key="idx">
  20. <div
  21. :style="el.style"
  22. v-for="(el,i) in child"
  23. :key="i">
  24. <div v-if="el.type==='ticketInfo'">
  25. <table
  26. class="table"
  27. >
  28. <tr>
  29. <th>项目名</th>
  30. <th>单位</th>
  31. <th>数量</th>
  32. <th>单价</th>
  33. <th>金额</th>
  34. </tr>
  35. <tr
  36. v-for="(item,j) in orderInfo"
  37. :key="j">
  38. <td>{{ item.tname }}</td>
  39. <td>张</td>
  40. <td>{{ item.num }}</td>
  41. <td>{{ item.price }}</td>
  42. <td>{{ item.totalPrice }}</td>
  43. </tr>
  44. </table>
  45. </div>
  46. <div v-if="el.type==='prepayment'">
  47. <span v-if="info.payChannel==='旅行社余额'">
  48. {{ el.nickname }} {{ info[el.key] }}
  49. </span>
  50. </div>
  51. <div v-else>
  52. <span v-if="el.isStatic">
  53. {{ el.nickname }} {{ el.content }}
  54. </span>
  55. <span v-else>
  56. <span v-if="info[el.key]">{{ el.nickname }} {{ info[el.key] }}</span>
  57. </span>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. </div>
  64. </template>
  65. <script>
  66. import moment from 'moment'
  67. export default {
  68. computed: {
  69. printTemplate () {
  70. return this.$store.state.app.smallTicketTemplate
  71. },
  72. showUnit () {
  73. return this.scenicName !== '狼山景区' && this.scenicName !== '军山景区'
  74. },
  75. scenicName () {
  76. return this.$localStore.get('scenicName') || this.$store.state.user.scenicName
  77. }
  78. },
  79. data () {
  80. return {
  81. qrImg: '',
  82. customStyle: null,
  83. info: {},
  84. orderInfo: []
  85. }
  86. },
  87. props: {
  88. preview: { // 仅预览时,不打印
  89. type: Boolean,
  90. default: false
  91. },
  92. currentOrder: {
  93. type: Object,
  94. default: () => {}
  95. }
  96. },
  97. methods: {
  98. startPrint () {
  99. const webview = document.querySelector('#printSmallTicketWebview')
  100. let printDoc = this.$refs.printMe.outerHTML
  101. if (this.preview) {
  102. console.log(printDoc)
  103. // return
  104. }
  105. // webview.openDevTools()
  106. webview.send('webview-print-render', printDoc)
  107. },
  108. sendPrinter (style) {
  109. this.getOrderInfo()
  110. if (style) {
  111. this.customStyle = JSON.parse(JSON.stringify(style))
  112. this.$nextTick(() => {
  113. this.startPrint()
  114. })
  115. } else {
  116. this.startPrint()
  117. }
  118. },
  119. getOrderInfo () {
  120. const orderInfo = []
  121. this.currentOrder.tickets.forEach(ticket => {
  122. let target = orderInfo.find(i => i.ticketTypeId === ticket.ticketTypeId)
  123. if (target) {
  124. target.num++
  125. target.totalPrice += ticket.price
  126. } else {
  127. ticket.num = 1
  128. ticket.totalPrice = ticket.price
  129. orderInfo.push(ticket)
  130. }
  131. })
  132. this.orderInfo = orderInfo
  133. const { performName, batchConfigName, ticket_price_plan_name } = this.currentOrder.tickets[0]
  134. this.currentOrder.createTime = moment(this.currentOrder.createTime).format('YYYY-MM-DD HH:mm:ss')
  135. this.info = {
  136. ...this.currentOrder,
  137. performName,
  138. batchConfigName,
  139. ticket_price_plan_name
  140. }
  141. }
  142. },
  143. watch: {
  144. printTemplate: {
  145. handler (val) {
  146. if (val) {
  147. this.customStyle = val
  148. }
  149. },
  150. deep: true,
  151. immediate: true
  152. },
  153. currentOrder: {
  154. handler (val) {
  155. if (!val) return
  156. this.getOrderInfo()
  157. let target
  158. let id = this.$localStore.get('defaultSmallTicketTemplate')
  159. target = this.$store.state.app.smallTicketTemplateList.find(i => i.id === id)
  160. this.$store.commit('SET_SMALL_TICKET_TEMPLATE', target ? JSON.parse(target.content) : this.printTemplate)
  161. this.$nextTick(() => {
  162. if (this.preview) return
  163. setTimeout(() => {
  164. this.sendPrinter()
  165. }, 100)
  166. })
  167. },
  168. immediate: true
  169. }
  170. }
  171. }
  172. </script>
  173. <style lang="scss" scoped>
  174. .img {
  175. height: 100%; background: no-repeat center center /contain;
  176. }
  177. .table {
  178. width: 100%; text-align: center; border-top: 1px dashed #000;border-bottom: 1px dashed #000;
  179. th {
  180. border-bottom: 1px dashed #000;
  181. }
  182. }
  183. .print-wrap {
  184. background: #fff;
  185. }
  186. * {
  187. box-sizing: border-box;
  188. }
  189. .wrap{
  190. display: flex;
  191. }
  192. </style>