index.vue 12 KB

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