Cashier 收银台

Scan me!

业务支付弹窗,支持支付渠道选择和支付验证码发送

引入

  1. import { Cashier } from 'mand-mobile'
  2. Vue.component(Cashier.name, Cashier)

代码演示

基本

  1. <template>
  2. <div class="md-example-child md-example-child-cashier">
  3. <md-field
  4. title="支付结果"
  5. >
  6. <md-radio
  7. v-model="cashierResult"
  8. :options="cashierResults"
  9. ></md-radio>
  10. </md-field>
  11. <md-field
  12. title="支付配置"
  13. >
  14. <md-input-item
  15. title="支付金额"
  16. align="right"
  17. type="money"
  18. v-model="cashierAmount"
  19. >
  20. </md-input-item>
  21. <md-field-item
  22. title="发送验证码"
  23. align="right"
  24. >
  25. <md-switch v-model="isCashierCaptcha"></md-switch>
  26. </md-field-item>
  27. </md-field>
  28. <md-button @click="isCashierhow = !isCashierhow">{{ isCashierhow ? '收起收银台' : '唤起收银台' }}</md-button>
  29. <md-cashier
  30. ref="cashier"
  31. v-model="isCashierhow"
  32. :channels="cashierChannels"
  33. :payment-amount="cashierAmount"
  34. payment-describe="关于支付金额的特殊说明"
  35. @select="onCashierSelect"
  36. @pay="onCashierPay"
  37. @cancel="onCashierCancel"
  38. ></md-cashier>
  39. </div>
  40. </template>
  41. <script>
  42. import {Button, Radio, Field, FieldItem, InputItem, Switch, Cashier, Toast} from 'mand-mobile'
  43. export default {
  44. name: 'cashier-demo',
  45. components: {
  46. [Button.name]: Button,
  47. [Radio.name]: Radio,
  48. [Field.name]: Field,
  49. [FieldItem.name]: FieldItem,
  50. [InputItem.name]: InputItem,
  51. [Switch.name]: Switch,
  52. [Cashier.name]: Cashier,
  53. },
  54. data() {
  55. return {
  56. isCashierhow: false,
  57. isCashierCaptcha: false,
  58. cashierAmount: '100.00',
  59. cashierResult: 'success',
  60. cashierResults: [
  61. {
  62. text: '支付成功',
  63. value: 'success',
  64. },
  65. {
  66. text: '支付失败',
  67. value: 'fail',
  68. },
  69. ],
  70. cashierChannels: [
  71. {
  72. icon: 'cashier-icon-1',
  73. text: '招商银行储蓄卡(0056)支付',
  74. value: '001',
  75. },
  76. {
  77. icon: 'cashier-icon-2',
  78. text: '支付宝支付',
  79. value: '002',
  80. },
  81. {
  82. icon: 'cashier-icon-3',
  83. text: '微信支付',
  84. value: '003',
  85. },
  86. {
  87. icon: 'cashier-icon-4',
  88. text: 'QQ钱包支付',
  89. value: '004',
  90. },
  91. {
  92. icon: 'cashier-icon-5',
  93. text: '一网通支付',
  94. value: '005',
  95. },
  96. ],
  97. }
  98. },
  99. computed: {
  100. cashier() {
  101. return this.$refs.cashier
  102. },
  103. },
  104. methods: {
  105. doPay() {
  106. if (this.isCashierCaptcha) {
  107. this.cashier.next('captcha', {
  108. text: 'Verification code sent to 156 **** 8965',
  109. autoCountdown: false,
  110. countNormalText: 'Send Verification code',
  111. countActiveText: 'Retransmission after {$1}s',
  112. onSend: countdown => {
  113. console.log('[Mand Mobile] Send Captcha')
  114. this.sendCaptcha().then(() => {
  115. countdown()
  116. })
  117. },
  118. onSubmit: code => {
  119. console.log(`[Mand Mobile] Send Submit ${code}`)
  120. this.checkCaptcha(code).then(res => {
  121. if (res) {
  122. this.createPay().then(() => {
  123. this.cashier.next(this.cashierResult)
  124. })
  125. }
  126. })
  127. },
  128. })
  129. } else {
  130. this.createPay().then(() => {
  131. this.cashier.next(this.cashierResult, {
  132. buttonText: '好的',
  133. handler: () => {
  134. Toast.info(`${this.cashierResult}点击`)
  135. },
  136. })
  137. })
  138. }
  139. },
  140. // Create a pay request & check pay result
  141. createPay() {
  142. this.cashier.next('loading')
  143. return new Promise(resolve => {
  144. this.timer = setTimeout(() => {
  145. resolve()
  146. }, 3000)
  147. })
  148. },
  149. // Create a captcha sending request
  150. sendCaptcha() {
  151. return new Promise(resolve => {
  152. this.timer = setTimeout(() => {
  153. resolve()
  154. }, 200)
  155. })
  156. },
  157. // Create a captcha checking request
  158. checkCaptcha(code) {
  159. return new Promise(resolve => {
  160. this.timer = setTimeout(() => {
  161. resolve(!!code)
  162. }, 200)
  163. })
  164. },
  165. onCashierSelect(item) {
  166. console.log(`[Mand Mobile] Select ${JSON.stringify(item)}`)
  167. },
  168. onCashierPay(item) {
  169. console.log(`[Mand Mobile] Pay ${JSON.stringify(item)}`)
  170. this.doPay()
  171. },
  172. onCashierCancel() {
  173. // Abort pay request or checking request
  174. this.timer && clearTimeout(this.timer)
  175. },
  176. },
  177. }
  178. </script>
  179. <style lang="stylus">
  180. .md-example-child-cashier
  181. .md-field
  182. margin-bottom 30px
  183. .choose-channel-item
  184. .item-icon.cashier-icon-1
  185. background url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAABHklEQVR4Ae2WgUYEURSGh70oQIB6gh6gHmBsqhfqHdq2hAJTUYAACMCytqQISUDAVpsEsWi09TX/XFcxYeJ0E/vzMf4z7uc6cJMQWi6l1egU5AUYkfszXZp8TVFmBfwyWbhZU0UcXKrbdWMJ5ZLwNaIwl5CY1BPen8HgAtoT1dn6pJ/dnRoKn64p01mpztQpj1eGwsNlyuTPsDX92W/P+A70j6FQ3BxR5nI3dP4bNDPeochmYZTD+xvsz8HBvP8evWhmLvScb1Cm3/Mo6sLcXLg5BcMHQhgO1BkL+8fUjP6NLLw9MRB+R0h19h+F4x3WYSystVe/rx/zJ0+MXtxHVNstxBO6ZqKw2tiLINxJQrzULenKxjvVWV3W3GLwfAD9KR4TBA12SgAAAABJRU5ErkJggg==') center no-repeat
  186. background-size 26px
  187. .item-icon.cashier-icon-2
  188. background url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAB7ElEQVR4Ac2WA6weQRSFb62gtuPajetGtW0FNcO6cVK7XdRu2Ia149R2Z6bP9r6T+yb5bZ7k/Bh9gzt3l1hXfzUiS+4iU36GK2AnTq6AP/PYJ/42JhZ+oPAp7CTWYDDUVHu4IDneCaD8kkTgV4r4zA5+akBuivhMI56llyLv768wXkpfYNK3NGXAaHQhpxlHY9KAlpwc6Qojt6W2urZYnYoFWA5XhWhTSaf/dmHYDqc2/v+NFPiZDLmKzv7pxAPAZIvWZPwbjrqN8B242LU6edUtgMZGGjS3XI8R6IRTj/yI2xhiPNofA7CPCyiuRAL8wM9FUy6AH8I5urwE/gwb8FSdS311+ldz1KsIgGIpmWpNGEGSQYbaC7f1gWIyPClD3uaJBgWeld3x/S3MyCwkWwz1AfqsWCzV8EIfIAeJqd6GAcuHx7oFylz4AVlqGl116gQ/c3HABTTkFH1pywPD1Esy//V0wdQMlJe6Rex3MtQ2OvO/fRgZXbziGVqqP+CmXm0m/AED2WT9G0GOU4sg/sYVCZLCyngrLTHRJ9K9Gl4jWzShYDoj+5Ih7keQiSQWcwgTHqKBPrP8wanK/D+QLzwOH4DeOgDu+maeiPwmBS9RuFNJA1pyV9JfhF33BHS9vZVxhFTWjCn2kYZVAyRlGm3AoxGeAAAAAElFTkSuQmCC') center no-repeat
  189. background-size 26px
  190. .item-icon.cashier-icon-3
  191. background url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAYCAYAAADpnJ2CAAABiklEQVR4AbWVAWRCURSGf8gIGQyYgUEAgyAAbCCAAAQQGBAYIGAwAAgIwAMJGIsqRTAgQPAQEsKDu//kXHLddV+v+w6f0HnvP/e8/5yLYPzgAXN0yICsSUoyZUeW+l/nlFs45miSRF9scpKRBDM0rhGqacXmRobhE8/wwsQtMZHYyjv/E2swYU9MZPZW1DVGWoLYEQt88ffR/W7DyEIHCn3ab4gVKpjhzbayHlOI9K2QHqZFNsSctKSSCEI78oE17h1PTJy8PnRwjYdNjlanpEdqsLHC04XnltA2+KuWiudoe9y7xQLvWKF6JlSVE5DjxZZf3CRs91nV3zqjXYxw55iuk9PlGQKJGaZ4hoR123lM8cqc3yu+dSqC40BS4lkSdf9zQcY4tSic2LQLQgc5K+jmrl3Wu0DiUkxy4+o72LEJnDISUrDjtKREwTHc0DkalSA2sfPqE62oKWKJDWRmgzd+BKENaUGjLMGjzmbbLoiigmvSk/tMnKa3y0DQ9vdIM9S6gKCK6FqLGX+Ik2Cgy7oRZQAAAABJRU5ErkJggg==') center no-repeat
  192. background-size 26px
  193. .item-icon.cashier-icon-4
  194. background url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAcCAYAAAB75n/uAAADaElEQVR4AWIgADiAOAaI1wDxUxZAadUA5GoTBCd59Wzbtm3btm3btm3btm3btt/5+v/6uLXRl/q7qu+SRc/OzKbXIhAh5ZXB1QZLyf8ANz+noAseNZhc3ETb4NOaocUiX+JFlYJiEuU1cdNBzGQSjbVWN3bu3BkHDx5EgQIFQsb69u2LjRs3IkWKFHqgE+ICndUNFCB27drFIBxDoUKFcP/+fZLj9rIpL05wVV1co0YNEBQdP3484sWLx9OjXbt2JD5//mwvwBaHV1KvPctCsEyLFy9GxIgRQeErV67g2rVrePz4sf1eOEBGLtB56tQpEPPmzQO/x4gRAx8+fADRvXt3R02PJnaQw97inKnCYkiLTBjf2IJ5bQTkxJax0KdpdiSPK44CxBcdk5LE7qqWaGxDwZv5AmxyzjtTLKiVP3QfNfakTVBZdDzOHHPDhESREBxkQA3Br4Vh8WlyJAr568Leq634MC4yPs63onz2UPEVySL7vswcc6LoeJIx+vPXmWNgW8ooSBs+DDcgY2LBoYEWvBoaDVeaJMSNlvFD+G5sZJYLsaMGlTJiGOxPFRXUuJ8x+nnREO16+ui+nAzm4qSRUT5qWES2Bpbg7OCwuNcjJok1nawMzjlUix4Oq5NHhrr3WJqonnqj5/HUJ9IEnkAnx5n6rMSRQFLQ0VpmkSSslVlNkyAkD647/y8pkx9vC6XiYrf4tnh6dEocHapWsDdNVK/Y/Pnz8XvdYlOiH6rlx7fh3eFx8iDg54uyZcvq13W8jT1s3boVPyYPVYXg/+8vfJ4/htedayT42d/TAzoaNmyoB7gquj3QJXkqNQBPZwZ6gCBtgcpp06bZBPD79QMmQFNUhYMpj4M+dOYEHdT3y0f8nDsBX3u3wpdujU1l4OHhgQgRIsBqld+K7VNbBgU1mlhNx6SZuYtVq1ZRUL2e04TaGuLTbmnP7uDv379Ily4dxZ/bOqkGPt5Mk802i+bNm4MHy5ZccokzYJOMN/jn6WxBscxhwVfM29sbjsBSsmclMoc47x9q2BffLP00x/TfM0DQvkYqjB45BHyT+Q7zNeNvpWuntmhUIgq4RtsHaokObJS2nHRAf2a1s5/s3NFXtvOzauE6qeWoRHUMHjT4mQJBfGpws8HKyrrKHOOcso57DlJDFPwHtUxGlWBNgLkAAAAASUVORK5CYII=') center no-repeat
  195. background-size 26px
  196. .item-icon.cashier-icon-5
  197. background url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAMAAABF0y+mAAABPlBMVEUAAAC/AEDIFS3GFS3HFS3HFS3HFS3MADPGFC7GFS3FFSvHFS3GFS3HFS3HFS3KIjnooKnmmKPJHDTMLELqqLHmlaDIGjHONEnssLjkjJjHFi7////hgI3rqrLdcoDwwsjUS17KITjed4T44+XIGC/LJz3++fr119vQPFD//v7NMEXgf43ca3r78PLZX3DVUWPpoavut77IGTD44+bxxszmlqHxw8nHFy/44OPttr3LJjz99/jaZXXXWWrhgY7+/P3//f3XV2jzzdPgf4zut7/nmqTxxMrllJ/yyM7dcH/++vvMK0HWUmTQO0/ZYXHba3r77vDJHTTts7v22Nzxxcv55OffdoXed4XRP1PedIPaZHThg5D11dnVTmDJHzb77e/55+rLJj377/Hqp7DkjprTRlnlkZzRPlLNL0TXVmdZnHwTAAAAD3RSTlMABEqUzPH/BXDmMNZV+P145yZGAAABMklEQVR4AXTQ02KcARCG4Z/v2t5vVdv2to1t2/d/BcnEfE7H45xxPT8IIQx8z3WuikRjnItFI5dj8QRXJOIXsWSKa1LJ81iaG9Kn0XiKW6TiFoskuFXCtopyh+jRfTFMJpvLA4ViqQxUqrU6MdfxwJSkBtCUWkBb6oDn+Jh796UHD3n0WHoCT6Vnz8F3AsyLl6+k1zQk6Q1vpXdA4IQWe//h4yfp85evFvz2/YdlQOhgfkq/nkm/pT9S96/1NifBf9L/HpnePql/QIMYa0tHGhoekRkdk16NT0yCtQ2AKalIfVrSDO9npbl5TGCnPO9KC7AoaQmWpRUwvj1hVWoDa+vaKMPmlrbBePa+LzvVCsDu3j7AweEyxSAJghFfwOONMnyRjS+Z4Etg+JIm4USNNzsAAPHdK2mIKv4bAAAAAElFTkSuQmCC') center no-repeat
  198. background-size 26px
  199. </style>
  200.  

API

Cashier Props

属性说明类型默认值备注
v-model收银台是否显示Booleanfalse-
channels支付渠道数据源Array<{text, value, icon}>[]icon可作为className或组件Iconname属性
default-index默认选中支付渠道索引Number0-
title收银台弹窗标题String支付-
payment-title支付金额标题String支付金额支持html fragment
payment-amount支付金额String0.00支持html fragment
payment-describe支付金额说明String-支持html fragment
pay-button-text1.3.1+确认支付按钮文案String确认支付支持html fragment
more-button-text1.3.1+更多支付渠道按钮文案String更多支付方式支持html fragment

Cashier Methods

next(scene, option)

进入收银台下一步

参数说明类型默认值备注
scene步骤标识, 'captcha(发送验证码)', 'loading(支付中)', 'success(支付成功)', 'fail(支付失败)'String--
option当前步骤配置Object属性如下所示-
  • captcha option

    属性说明类型默认值备注
    text发送验证码说明String-支持html fragment
    maxlength验证码位数Number4若为-1则不限制输入长度
    count验证码重新发送倒计时Number60若为0则不显示重新发送
    auto-countdown是否自动开始倒计时,否则需手动调用countdownBooleantrue-
    countNormalText1.3.0+发送验证码正常状态文字String发送验证码-
    countActiveText1.3.0+发送验证码及倒计时按钮文案配置项String{$1}秒后重发-
    onSend验证码发送回调Function(countdown: Function)-countdown为开始倒计时方法
    onSubmit验证码提交回调Function(code: String)-code为输入的验证码
  • loading option

    属性说明类型默认值备注
    text支付中说明String支付结果查询中…支持html fragment
  • success option

    属性说明类型默认值备注
    text支付成功说明String支付成功支持html fragment
    buttonText1.3.1+按钮文案String我知道了支持html fragment
    handler按钮点击回调Function--
  • fail option

    属性说明类型默认值备注
    text支付失败说明String支付失败,请稍后重试支持html fragment
    buttonText1.3.1+按钮文案String我知道了支持html fragment
    handler按钮点击回调Function--

Cashier Events

@select(item: {text, value})

支付渠道选中事件

@pay(item: {text, value})

支付渠道确认并发起支付事件

@cancel()

取消支付事件

@show()

收银台弹窗展示事件

@hide()

收银台弹窗隐藏事件