index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <template>
  2. <!-- 支付弹窗 -->
  3. <view :style="colorStyle">
  4. <view class="payment" :class="pay_close ? 'on' : ''">
  5. <view class="title acea-row row-center-wrapper">
  6. 选择付款方式<text class="iconfont icon-guanbi" @click='close'></text>
  7. </view>
  8. <view class="item acea-row row-between-wrapper" v-for="(item,index) in payMode" :key="index"
  9. v-if='item.payStatus' @click="payType(item.number || 0 , item.value,index)">
  10. <view class="left acea-row row-between-wrapper">
  11. <view class="iconfont" :class="item.icon"></view>
  12. <view class="text">
  13. <view class="name">{{item.name}}</view>
  14. <view class="info" v-if="item.value == 'yue'">
  15. {{item.title}} <span class="money">{{ item.number }}</span>
  16. </view>
  17. <view class="info" v-else>{{item.title}}</view>
  18. </view>
  19. </view>
  20. <view class="iconfont" :class="active==index?'icon-xuanzhong11 font-num':'icon-weixuan'"></view>
  21. </view>
  22. <view class="payMoney" >支付<span class="font-color">¥<span class="money">{{totalPrice}}</span></span></view>
  23. <view class="button bg-color acea-row row-center-wrapper" @click='goPay(number, paytype)'>去付款</view>
  24. <slot name="buttom"></slot>
  25. </view>
  26. <view class="mask" @click='close' v-if="pay_close"></view>
  27. <view v-show="false" v-html="formContent"></view>
  28. </view>
  29. </template>
  30. <script>
  31. import {
  32. orderPay
  33. } from '@/api/order.js';
  34. import colors from '@/mixins/color.js';
  35. export default {
  36. props: {
  37. payTT: {
  38. type: Boolean,
  39. default: false,
  40. },
  41. payMode: {
  42. type: Array,
  43. default: function() {
  44. return [];
  45. }
  46. },
  47. pay_close: {
  48. type: Boolean,
  49. default: false,
  50. },
  51. order_id: {
  52. type: String,
  53. default: ''
  54. },
  55. totalPrice: {
  56. type: String,
  57. default: '0'
  58. },
  59. isCall: {
  60. type: Boolean,
  61. default: false
  62. }
  63. },
  64. mixins:[colors],
  65. data() {
  66. return {
  67. formContent: '',
  68. active: 0,
  69. paytype: '',
  70. number: 0
  71. };
  72. },
  73. watch: {
  74. payMode: {
  75. handler(newV, oldValue) {
  76. let newPayList = [];
  77. newV.forEach((item, index) => {
  78. if (item.payStatus) {
  79. item.index = index;
  80. newPayList.push(item)
  81. }
  82. });
  83. this.active = newPayList[0].index;
  84. this.paytype = newPayList[0].value;
  85. this.number = newPayList[0].number || 0;
  86. },
  87. immediate: true,
  88. deep: true
  89. }
  90. },
  91. methods: {
  92. payType(number, paytype, index) {
  93. this.active = index;
  94. console.log(this.active,'this.active');
  95. this.paytype = paytype;
  96. this.number = number;
  97. this.$emit('changePayType', paytype)
  98. },
  99. close: function() {
  100. this.$emit('onChangeFun', {
  101. action: 'payClose'
  102. });
  103. },
  104. goPay: function(number, paytype) {
  105. if (this.isCall) {
  106. return this.$emit('onChangeFun', {
  107. action: 'payCheck',
  108. value: paytype
  109. });
  110. }
  111. let that = this;
  112. if (paytype == 'yue' && parseFloat(number) < parseFloat(that.totalPrice)) return that.$util.Tips({
  113. title: '余额不足!'
  114. });
  115. if(that.payTT) {
  116. return that.$emit('onChooseType', paytype);
  117. }
  118. if (!that.order_id) return that.$util.Tips({
  119. title: '请选择要支付的订单'
  120. });
  121. uni.showLoading({
  122. title: '支付中'
  123. });
  124. orderPay({
  125. uni: that.order_id,
  126. paytype: paytype,
  127. // #ifdef MP
  128. 'from': 'routine',
  129. // #endif
  130. // #ifdef H5
  131. 'from': this.$wechat.isWeixin() ? 'weixin' : 'weixinh5',
  132. // #endif
  133. // #ifdef H5
  134. quitUrl: location.port ? location.protocol + '//' + location.hostname + ':' + location
  135. .port +
  136. '/pages/goods/order_details/index?order_id=' + this.order_id : location.protocol +
  137. '//' + location.hostname +
  138. '/pages/goods/order_details/index?order_id=' + this.order_id
  139. // #endif
  140. // #ifdef APP-PLUS
  141. quitUrl: '/pages/goods/order_details/index?order_id=' + this.order_id
  142. // #endif
  143. }).then(res => {
  144. let jsConfig = res.data.result.jsConfig;
  145. switch (paytype) {
  146. case 'weixin':
  147. if (res.data.result === undefined) return that.$util.Tips({
  148. title: '缺少支付参数'
  149. });
  150. // #ifdef MP
  151. let mp_pay_name=''
  152. if(uni.requestOrderPayment){
  153. mp_pay_name='requestOrderPayment'
  154. }else{
  155. mp_pay_name='requestPayment'
  156. }
  157. uni[mp_pay_name]({
  158. timeStamp: jsConfig.timestamp,
  159. nonceStr: jsConfig.nonceStr,
  160. package: jsConfig.package,
  161. signType: jsConfig.signType,
  162. paySign: jsConfig.paySign,
  163. success: function(res) {
  164. uni.hideLoading();
  165. return that.$util.Tips({
  166. title: res.msg,
  167. icon: 'success'
  168. }, () => {
  169. that.$emit('onChangeFun', {
  170. action: 'pay_complete'
  171. });
  172. });
  173. },
  174. fail: function(e) {
  175. uni.hideLoading();
  176. return that.$util.Tips({
  177. title: '取消支付'
  178. }, () => {
  179. that.$emit('onChangeFun', {
  180. action: 'pay_fail'
  181. });
  182. });
  183. },
  184. complete: function(e) {
  185. uni.hideLoading();
  186. if (e.errMsg == 'requestPayment:cancel') return that.$util
  187. .Tips({
  188. title: '取消支付'
  189. }, () => {
  190. that.$emit('onChangeFun', {
  191. action: 'pay_fail'
  192. });
  193. });
  194. },
  195. });
  196. // #endif
  197. // #ifdef H5
  198. let data = res.data;
  199. if (data.status == "WECHAT_H5_PAY") {
  200. uni.hideLoading();
  201. location.replace(data.result.jsConfig.mweb_url);
  202. return that.$util.Tips({
  203. title: "支付成功",
  204. icon: 'success'
  205. }, () => {
  206. that.$emit('onChangeFun', {
  207. action: 'pay_complete'
  208. });
  209. });
  210. } else {
  211. that.$wechat.pay(data.result.jsConfig)
  212. .then(() => {
  213. return that.$util.Tips({
  214. title: "支付成功",
  215. icon: 'success'
  216. }, () => {
  217. that.$emit('onChangeFun', {
  218. action: 'pay_complete'
  219. });
  220. });
  221. })
  222. .catch(function(res) {
  223. if (res.errMsg == 'chooseWXPay:cancel') return that.$util.Tips({
  224. title: '取消支付'
  225. },() => {
  226. that.$emit('onChangeFun', {
  227. action: 'pay_fail'
  228. });
  229. });
  230. });
  231. }
  232. // #endif
  233. // #ifdef APP-PLUS
  234. uni.requestPayment({
  235. provider: 'wxpay',
  236. orderInfo: jsConfig,
  237. success: (e) => {
  238. let url = '/pages/goods/order_pay_status/index?order_id=' + orderId +
  239. '&msg=支付成功';
  240. uni.showToast({
  241. title: "支付成功"
  242. })
  243. setTimeout(res => {
  244. that.$emit('onChangeFun', {
  245. action: 'pay_complete'
  246. });
  247. }, 2000)
  248. },
  249. fail: (e) => {
  250. uni.showModal({
  251. content: "支付失败",
  252. showCancel: false,
  253. success: function(res) {
  254. if (res.confirm) {
  255. that.$emit('onChangeFun', {
  256. action: 'pay_fail'
  257. });
  258. } else if (res.cancel) {}
  259. }
  260. })
  261. },
  262. complete: () => {
  263. uni.hideLoading();
  264. },
  265. });
  266. // #endif
  267. break;
  268. case 'yue':
  269. uni.hideLoading();
  270. return that.$util.Tips({
  271. title: res.msg,
  272. icon: 'success'
  273. }, () => {
  274. that.$emit('onChangeFun', {
  275. action: 'pay_complete'
  276. });
  277. });
  278. break;
  279. case 'offline':
  280. uni.hideLoading();
  281. return that.$util.Tips({
  282. title: res.msg,
  283. icon: 'success'
  284. }, () => {
  285. that.$emit('onChangeFun', {
  286. action: 'pay_complete'
  287. });
  288. });
  289. break;
  290. case 'alipay':
  291. uni.hideLoading();
  292. //#ifdef H5
  293. if (this.$wechat.isWeixin()) {
  294. uni.redirectTo({
  295. url: `/pages/users/alipay_invoke/index?id=${res.data.result.order_id}&pay_key=${res.data.result.pay_key}`
  296. });
  297. } else {
  298. uni.hideLoading();
  299. that.formContent = res.data.result.jsConfig;
  300. that.$nextTick(() => {
  301. document.getElementById('alipaysubmit').submit();
  302. });
  303. }
  304. //#endif
  305. // #ifdef MP
  306. uni.navigateTo({
  307. url: `/pages/users/alipay_invoke/index?id=${res.data.result.order_id}&link=${res.data.result.jsConfig.qrCode}`
  308. });
  309. // #endif
  310. // #ifdef APP-PLUS
  311. uni.requestPayment({
  312. provider: 'alipay',
  313. orderInfo: jsConfig,
  314. success: (e) => {
  315. uni.showToast({
  316. title: "支付成功"
  317. })
  318. setTimeout(res => {
  319. that.$emit('onChangeFun', {
  320. action: 'pay_complete'
  321. });
  322. }, 2000)
  323. },
  324. fail: (e) => {
  325. uni.showModal({
  326. content: "支付失败",
  327. showCancel: false,
  328. success: function(res) {
  329. if (res.confirm) {
  330. that.$emit('onChangeFun', {
  331. action: 'pay_fail'
  332. });
  333. } else if (res.cancel) {}
  334. }
  335. })
  336. },
  337. complete: () => {
  338. uni.hideLoading();
  339. },
  340. });
  341. // #endif
  342. break;
  343. }
  344. }).catch(err => {
  345. uni.hideLoading();
  346. return that.$util.Tips({
  347. title: err
  348. }, () => {
  349. that.$emit('onChangeFun', {
  350. action: 'pay_fail'
  351. });
  352. });
  353. })
  354. }
  355. }
  356. }
  357. </script>
  358. <style scoped lang="scss">
  359. .bgcolor{
  360. background-color: var(--view-theme)
  361. }
  362. .payment {
  363. position: fixed;
  364. bottom: 0;
  365. left: 0;
  366. width: 100%;
  367. border-radius: 16rpx 16rpx 0 0;
  368. background-color: #fff;
  369. padding-bottom: 60rpx;
  370. z-index: 999;
  371. transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  372. transform: translate3d(0, 100%, 0);
  373. .payMoney {
  374. font-size: 28rpx;
  375. color: #333333;
  376. text-align: center;
  377. margin-top: 50rpx;
  378. .font-color {
  379. margin-left: 10rpx;
  380. .money {
  381. font-size: 40rpx;
  382. }
  383. }
  384. }
  385. .button {
  386. width: 690rpx;
  387. height: 90rpx;
  388. border-radius: 45rpx;
  389. color: #FFFFFF;
  390. margin: 20rpx auto 0 auto;
  391. }
  392. }
  393. .payment.on {
  394. transform: translate3d(0, 0, 0);
  395. }
  396. .payment .title {
  397. text-align: center;
  398. height: 123rpx;
  399. font-size: 32rpx;
  400. color: #282828;
  401. font-weight: bold;
  402. padding-right: 30rpx;
  403. margin-left: 30rpx;
  404. position: relative;
  405. border-bottom: 1rpx solid #eee;
  406. }
  407. .payment .title .iconfont {
  408. position: absolute;
  409. right: 30rpx;
  410. top: 50%;
  411. transform: translateY(-50%);
  412. font-size: 38rpx;
  413. color: #8a8a8a;
  414. font-weight: normal;
  415. }
  416. .payment .item {
  417. border-bottom: 1rpx solid #eee;
  418. height: 130rpx;
  419. margin-left: 30rpx;
  420. padding-right: 30rpx;
  421. }
  422. .payment .item .left {
  423. width: 610rpx;
  424. }
  425. .payment .item .left .text {
  426. width: 540rpx;
  427. }
  428. .payment .item .left .text .name {
  429. font-size: 32rpx;
  430. color: #282828;
  431. }
  432. .payment .item .left .text .info {
  433. font-size: 24rpx;
  434. color: #999;
  435. }
  436. .payment .item .left .text .info .money {
  437. color: #ff9900;
  438. }
  439. .payment .item .left .iconfont {
  440. font-size: 45rpx;
  441. color: #09bb07;
  442. }
  443. .payment .item .left .iconfont.icon-zhifubao {
  444. color: #00aaea;
  445. }
  446. .payment .item .left .iconfont.icon-yuezhifu {
  447. color: #ff9900;
  448. }
  449. .payment .item .left .iconfont.icon-yuezhifu1 {
  450. color: #eb6623;
  451. }
  452. .payment .item .iconfont {
  453. font-size: 40rpx;
  454. color: #ccc;
  455. }
  456. </style>