index.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. <template>
  2. <div class="pay-layout">
  3. <div class="pay-header">
  4. <div class="h-left">
  5. <img src="@/assets/images/logo-black.png" alt>
  6. <span class="h-line"></span>
  7. <span>支付中心</span>
  8. </div>
  9. <div class="h-right">当前账号:{{info.userName}}</div>
  10. </div>
  11. <div class="pay-con">
  12. <div class="mid">
  13. <div class="attr">支付方式:</div>
  14. <div class="body">
  15. <div class="pay-tag" :class="{'tag-active':paytype==='alipay'}" @click="paytype='alipay'">
  16. <img src="@/assets/images/ali-pay.png" class="t-icon" alt>
  17. <span>支付宝</span>
  18. <img src="@/assets/images/tag-icon.png" class="t-click" alt>
  19. </div>
  20. <div class="pay-tag" :class="{'tag-active':paytype==='wechatPay'}" @click="paytype='wechatPay'">
  21. <img src="@/assets/images/wechat-pay.png" class="t-icon" alt>
  22. <span>微信支付</span>
  23. <img src="@/assets/images/tag-icon.png" class="t-click" alt>
  24. </div>
  25. <div class="pay-tag paypal-con" :class="{'tag-active':paytype==='paypal'}" @click="paytype='paypal'">
  26. <img src="@/assets/images/paypal.png" class="t-icon" alt>
  27. <span>paypal</span>
  28. <img src="@/assets/images/tag-icon.png" class="t-click" alt>
  29. <form id="formid" class="form-con" :action="`${$serverName}api/order/pay/paypal`" method="post">
  30. <input v-model="$route.params.orderId" type="text" name='orderId'>
  31. <input v-model="$route.params.orderType" type="text" name='orderType'>
  32. <input type="submit" value="提交">
  33. </form>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="bottom" v-if="paytype !== 'paypal'">
  38. <div class="attr">应付金额:</div>
  39. <div class="price-detail">
  40. <div class="price">¥{{response.price}}</div>
  41. <img v-if="response.src" :src="`${$serverName}${response.src}`" alt="">
  42. <div class="dec">使用<span style="color:#ff0000">{{payZH}}</span>app扫码完成支付</div>
  43. </div>
  44. </div>
  45. </div>
  46. <div class="pay-bottom">
  47. ©2019 4dkankan移动开放平台
  48. </div>
  49. </div>
  50. </template>
  51. <script>
  52. import { mapState } from 'vuex'
  53. let payTypes = {
  54. wechatPay: '微信',
  55. alipay: '支付宝',
  56. paypal: 'paypal'
  57. }
  58. let PAYS = {
  59. 0: 'wechatPay',
  60. 1: 'alipay',
  61. 2: 'paypal'
  62. }
  63. let PAYSID = {
  64. wechatPay: 0,
  65. alipay: 1,
  66. paypal: 2
  67. }
  68. export default {
  69. data () {
  70. return {
  71. privilege: 'year',
  72. response: '',
  73. t1: null,
  74. paytype: PAYS[this.$route.params.payType]
  75. }
  76. },
  77. computed: {
  78. ...mapState({
  79. token: state => state.user.token,
  80. info: state => state.user.info
  81. }),
  82. payZH () {
  83. return payTypes[this.paytype]
  84. }
  85. },
  86. watch: {
  87. paytype (newVal, oldVal) {
  88. this.getCode()
  89. }
  90. },
  91. mounted () {
  92. this.getCode()
  93. },
  94. methods: {
  95. inverRequest () {
  96. clearInterval(this.t1)
  97. this.t1 = null
  98. this.t1 = setInterval(() => {
  99. this.queryOrderStatus()
  100. }, 5000)
  101. },
  102. async queryOrderStatus () {
  103. if (this.t1) {
  104. let {orderSn, orderType} = this.$route.params
  105. if (!orderSn) {
  106. return this.$toast.show('error', '获取订单信息失败')
  107. }
  108. let params = {
  109. orderSn,
  110. orderType: Number(orderType),
  111. payType: Number(PAYSID[this.paytype])
  112. }
  113. let res = await this.$http
  114. .post('/user/order/queryOrderStatus', params, {
  115. headers: {
  116. token: this.token
  117. }
  118. })
  119. let response = res.data
  120. if (response.code === 0 && response.data) {
  121. this.t1 = null
  122. this.t1 && clearInterval(this.t1)
  123. this.$router.replace({
  124. name: 'payresult',
  125. params: {
  126. isSuccess: 'success'
  127. }
  128. })
  129. }
  130. }
  131. },
  132. async getCode () {
  133. let {orderId, orderType} = this.$route.params
  134. if (!orderId || (!orderType && orderType !== 0)) {
  135. return this.$toast.show('error', '获取订单信息失败')
  136. }
  137. if (this.paytype !== 'paypal') {
  138. let params = {
  139. orderId: orderId,
  140. orderType: Number(orderType)
  141. }
  142. let res = await this.$http
  143. .post(`/order/pay/${this.paytype}`, params, {
  144. headers: {
  145. token: this.token
  146. }
  147. })
  148. let response = res.data
  149. if (response.code !== 0) {
  150. return this.$toast.show('error', '获取支付二维码失败', () => {
  151. this.t1 = null
  152. this.t1 && clearInterval(this.t1)
  153. })
  154. }
  155. this.response = response.data
  156. this.inverRequest()
  157. } else {
  158. document.getElementById('formid').submit()
  159. this.$toast.show('warn', '正在跳转至paypal支付链接,请稍等')
  160. }
  161. }
  162. },
  163. beforeDestroy () {
  164. clearInterval(this.t1)
  165. this.t1 = null
  166. }
  167. }
  168. </script>
  169. <style lang="scss" scoped>
  170. $theme-color: #1fe4dc;
  171. .pay-layout {
  172. width: 1030px;
  173. min-height: 74vh;
  174. margin: 25px auto;
  175. .pay-header {
  176. width: 100%;
  177. margin-bottom: 50px;
  178. display: flex;
  179. justify-content: space-between;
  180. align-items: center;
  181. .h-left {
  182. display: flex;
  183. justify-content: space-between;
  184. align-items: center;
  185. .h-line {
  186. width: 1px;
  187. height: 20px;
  188. background: #000;
  189. margin: 0 10px;
  190. display: inline-block;
  191. }
  192. span {
  193. font-size: 20px;
  194. color: #2d2d2d;
  195. }
  196. }
  197. .h-right {
  198. font-size: 14px;
  199. color: #2d2d2d;
  200. }
  201. }
  202. .pay-con {
  203. background: #f4f4f4;
  204. padding: 40px;
  205. .top,
  206. .mid,
  207. .bottom {
  208. display: flex;
  209. margin-bottom: 50px;
  210. .attr {
  211. font-size: 14px;
  212. color: #2d2d2d;
  213. }
  214. .val {
  215. display: flex;
  216. align-items: center;
  217. margin-left: 20px;
  218. .tag {
  219. height: 100%;
  220. font-size: 0;
  221. margin-right: 50px;
  222. display: flex;
  223. align-items: center;
  224. border: 1px solid #f4f4f4;
  225. position: relative;
  226. .year {
  227. width: 52px;
  228. height: 48px;
  229. line-height: 48px;
  230. text-align: center;
  231. display: inline-block;
  232. background: #ededed;
  233. color: #777777;
  234. font-size: 14px;
  235. flex-shrink: 0;
  236. }
  237. .price {
  238. background: #fff;
  239. height: 48px;
  240. width: 160px;
  241. line-height: 48px;
  242. display: inline-block;
  243. font-size: 18px;
  244. color: #ff0000;
  245. text-align: center;
  246. .per {
  247. font-size: 12px;
  248. margin-left: 20px;
  249. color: #777777;
  250. }
  251. }
  252. img {
  253. position: absolute;
  254. bottom: 0;
  255. right: 0;
  256. width: 14px;
  257. }
  258. }
  259. .tag-active {
  260. border: 1px solid $theme-color;
  261. box-sizing: border-box;
  262. }
  263. }
  264. .body {
  265. margin-left: 20px;
  266. .pay-tag {
  267. cursor: pointer;
  268. border: 1px solid #e7e7e7;
  269. width: 200px;
  270. line-height: 36px;
  271. height: 36px;
  272. margin-bottom: 20px;
  273. position: relative;
  274. span {
  275. margin-left: 36px;
  276. display: inline-block;
  277. text-align: center;
  278. padding-left: 60px;
  279. }
  280. img {
  281. position: absolute;
  282. }
  283. .t-icon {
  284. width: 36px;
  285. height: 36px;
  286. padding: 6px;
  287. left: 0;
  288. border-right: 1px solid #e7e7e7;
  289. }
  290. .t-click {
  291. right: 0;
  292. bottom: 0;
  293. display: none;
  294. }
  295. }
  296. .paypal-con{
  297. position: relative;
  298. .form-con{
  299. opacity: 0;
  300. input[type='text']{
  301. width: 1px;
  302. height: 1px;
  303. position: absolute;
  304. top: 0;
  305. opacity: 0;
  306. left: 0;
  307. }
  308. input[type='submit']{
  309. width: 100%;
  310. position: absolute;
  311. top: 0;
  312. left: 0;
  313. opacity: 0;
  314. height: 100%;
  315. }
  316. }
  317. }
  318. .tag-active {
  319. border: 1px solid $theme-color;
  320. span {
  321. color: #000;
  322. }
  323. .t-icon {
  324. border-right: 1px solid $theme-color;
  325. }
  326. .t-click {
  327. display: inline-block;
  328. }
  329. }
  330. }
  331. .price-detail{
  332. margin-left: 6px;
  333. text-align: center;
  334. position: relative;
  335. width: 160px;
  336. top: -15px;
  337. .price{
  338. font-size: 30px;
  339. color: #ff0000;
  340. margin: 0 0 0 8px;
  341. text-align: left;
  342. padding: 0;
  343. margin-bottom: 40px;
  344. }
  345. .sao{
  346. font-size: 14px;
  347. color: #2d2d2d;
  348. margin-bottom: 5px;
  349. }
  350. .dec{
  351. color: #2d2d2d;
  352. font-size: 12px;
  353. margin-top: 10px;
  354. }
  355. img{
  356. width: 130px;
  357. height: 130px;
  358. }
  359. }
  360. }
  361. .bottom {
  362. margin-bottom: 0;
  363. }
  364. }
  365. .pay-bottom{
  366. color: #969696;
  367. font-size: 12px;
  368. text-align: center;
  369. margin-top: 20px;
  370. }
  371. }
  372. </style>