index.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <template>
  2. <form class="form" @submit="checkForm">
  3. <view class="input-section">
  4. <view class="section-hd">支付金额</view>
  5. <view class="section-bd">
  6. <view class="input-group">
  7. <input v-model.number="money" class="input" name="money" type="digit" @input="inputChange" placeholder="0.00" />
  8. </view>
  9. <view v-if="payPrice" class="discount">会员优惠价:¥{{ payPrice }}</view>
  10. </view>
  11. </view>
  12. <view class="radio-section">
  13. <view class="section-hd">支付方式</view>
  14. <radio-group class="section-bd" name="method">
  15. <label class="item" v-if="yuePay">
  16. <text class="iconfont icon-yue"></text>
  17. <text class="name">
  18. 余额支付
  19. <text class="money">可用余额:{{ now_money || 0 }}¥</text>
  20. </text>
  21. <radio value="yue" :checked="payType === 'yue'" />
  22. </label>
  23. <label v-if="wxpay" class="item">
  24. <text class="iconfont icon-weixinzhifu"></text>
  25. <text class="name">微信支付</text>
  26. <radio value="weixin" :checked="payType === 'weixin'" />
  27. </label>
  28. </radio-group>
  29. </view>
  30. <button class="button" form-type="submit">确认</button>
  31. <view class="alipay" v-html="alipayHtml"></view>
  32. </form>
  33. </template>
  34. <script>
  35. import {
  36. offlineCheckPrice,
  37. offlineCreate,
  38. orderOfflinePayType
  39. } from '@/api/order.js';
  40. import {
  41. toLogin
  42. } from '@/libs/login.js';
  43. import {
  44. mapGetters
  45. } from "vuex";
  46. const app = getApp();
  47. export default {
  48. data() {
  49. return {
  50. money: '',
  51. payPrice: '',
  52. payType: 'weixin',
  53. alipayHtml: '',
  54. alipay: false,
  55. wxpay: false,
  56. yuePay: false,
  57. paying: false,
  58. now_money: 0,
  59. isWeixin: false,
  60. site_name: '',
  61. isCommitted: false
  62. };
  63. },
  64. watch: {
  65. money(newValue, oldValue) {
  66. if (newValue && typeof newValue === 'number') {
  67. this.checkPrice();
  68. } else {
  69. this.payPrice = '';
  70. }
  71. }
  72. },
  73. computed: mapGetters(['isLogin']),
  74. onLoad(options) {
  75. if (!this.isLogin) {
  76. toLogin()
  77. }
  78. // #ifdef H5
  79. if (options.code) {
  80. let spread = app.globalData.spid ? app.globalData.spid : '';
  81. wechatAuthV2(options.code, spread).then(res => {
  82. location.href = decodeURIComponent(
  83. decodeURIComponent(options.back_url)
  84. )
  85. })
  86. }
  87. // #endif
  88. },
  89. onShow() {
  90. if (this.isLogin) {
  91. this.getPayType();
  92. }
  93. //#ifdef H5
  94. this.isWeixin = this.$wechat.isWeixin();
  95. //#endif
  96. },
  97. methods: {
  98. inputChange(e){
  99. var that = this
  100. e.target.value = (e.target.value.match(/^\d*(.?\d{0,2})/g)[0]) || ""
  101. this.$nextTick(() => {
  102. this.money = e.target.value
  103. this.checkPrice()
  104. })
  105. },
  106. getPayType() {
  107. orderOfflinePayType()
  108. .then(res => {
  109. const {
  110. ali_pay_status,
  111. pay_weixin_open,
  112. yue_pay_status,
  113. offline_pay_status,
  114. site_name,
  115. now_money
  116. } = res.data;
  117. this.alipay = ali_pay_status === '1' ? true : false;
  118. this.wxpay = pay_weixin_open === 1 ? true : false;
  119. this.yuePay = yue_pay_status === 1 ? true : false;
  120. this.now_money = now_money;
  121. this.site_name = site_name;
  122. if (!offline_pay_status) {
  123. uni.showModal({
  124. title: '支付提醒',
  125. content: '线下支付已关闭,请点击确认按钮返回主页',
  126. showCancel: false,
  127. success() {
  128. uni.switchTab({
  129. url: '/pages/index/index'
  130. })
  131. }
  132. });
  133. }
  134. if (site_name) {
  135. uni.setNavigationBarTitle({
  136. title: site_name
  137. });
  138. }
  139. })
  140. .catch(err => {
  141. uni.showToast({
  142. title: err,
  143. icon: 'none'
  144. });
  145. });
  146. },
  147. checkForm(e) {
  148. const {
  149. money,
  150. method
  151. } = e.detail.value;
  152. if (money) {
  153. this.combData(method);
  154. } else {
  155. uni.showToast({
  156. title: '请输入支付金额',
  157. icon: 'none'
  158. });
  159. }
  160. },
  161. // 优惠价
  162. checkPrice() {
  163. offlineCheckPrice({
  164. pay_price: this.money
  165. })
  166. .then(res => {
  167. this.payPrice = res.data.pay_price;
  168. })
  169. .catch(err => {
  170. uni.showToast({
  171. title: err,
  172. icon: 'none'
  173. });
  174. });
  175. },
  176. // 组合数据
  177. combData(payType) {
  178. let data = {
  179. type: 3,
  180. pay_type: payType,
  181. from: 'weixinh5',
  182. price: this.payPrice || this.money,
  183. money: this.money
  184. };
  185. // #ifdef H5
  186. if (this.isWeixin) {
  187. data.from = 'weixin';
  188. }
  189. // #endif
  190. // #ifdef MP
  191. data.from = 'routine';
  192. // #endif
  193. if (this.paying) {
  194. return;
  195. }
  196. this.paying = true;
  197. uni.showLoading({
  198. title: '正在确认…'
  199. });
  200. offlineCreate(data)
  201. .then(res => {
  202. uni.hideLoading();
  203. this.callPay(res);
  204. })
  205. .catch(err => {
  206. this.paying = false;
  207. uni.showToast({
  208. title: err,
  209. icon: 'none'
  210. });
  211. });
  212. },
  213. // 调用支付
  214. callPay(res) {
  215. const {
  216. status,
  217. result
  218. } = res.data, {
  219. orderId,
  220. jsConfig
  221. } = result,
  222. goPages = '/pages/annex/offline_result/index?site_name=' + this.site_name;
  223. switch (status) {
  224. case 'ORDER_EXIST':
  225. case 'EXTEND_ORDER':
  226. case 'PAY_ERROR':
  227. this.paying = false;
  228. this.$util.Tips({
  229. title: res.msg
  230. }, {
  231. tab: 5,
  232. url: goPages
  233. });
  234. break;
  235. case 'SUCCESS':
  236. this.paying = false;
  237. this.money = '';
  238. this.$util.Tips({
  239. title: res.msg,
  240. icon: 'success'
  241. }, {
  242. tab: 5,
  243. url: goPages
  244. });
  245. break;
  246. case 'WECHAT_PAY':
  247. // #ifdef MP
  248. let that = this;
  249. uni.requestPayment({
  250. timeStamp: jsConfig.timestamp,
  251. nonceStr: jsConfig.nonceStr,
  252. package: jsConfig.package,
  253. signType: jsConfig.signType,
  254. paySign: jsConfig.paySign,
  255. success: function(res) {
  256. that.$util.Tips({
  257. title: '支付成功',
  258. icon: 'success'
  259. }, {
  260. tab: 5,
  261. url: '/pages/annex/offline_result/index'
  262. });
  263. },
  264. fail: function() {
  265. uni.showToast({
  266. title: '取消支付',
  267. icon: 'none',
  268. success: function() {
  269. that.paying = false;
  270. }
  271. });
  272. },
  273. complete: function() {
  274. that.paying = false;
  275. uni.hideLoading();
  276. }
  277. });
  278. // #endif
  279. // #ifndef MP
  280. this.$wechat
  281. .pay(result.jsConfig)
  282. .then(res => {
  283. this.paying = false;
  284. this.$util.Tips({
  285. title: '支付成功',
  286. icon: 'success'
  287. }, {
  288. tab: 5,
  289. url: '/pages/annex/offline_result/index'
  290. });
  291. })
  292. .catch(err => {
  293. this.paying = false;
  294. if (err.errMsg == 'chooseWXPay:cancel') {
  295. uni.showToast({
  296. title: '取消支付',
  297. icon: 'none'
  298. });
  299. }
  300. });
  301. // #endif
  302. break;
  303. case 'PAY_DEFICIENCY':
  304. this.paying = false;
  305. this.$util.Tips({
  306. title: res.msg
  307. });
  308. break;
  309. case 'WECHAT_H5_PAY':
  310. this.paying = false;
  311. uni.showToast({
  312. title: res.msg,
  313. success() {
  314. location.href = jsConfig.mweb_url;
  315. }
  316. });
  317. break;
  318. case 'ALIPAY_PAY':
  319. this.paying = false;
  320. // #ifdef H5
  321. if (this.$wechat.isWeixin()) {
  322. uni.navigateTo({
  323. url: `/pages/users/alipay_invoke/index?id=${orderId}&link=${jsConfig.qrCode}`
  324. });
  325. } else {
  326. this.alipayHtml = jsConfig;
  327. this.$nextTick(() => {
  328. document.getElementById('alipaysubmit').submit();
  329. });
  330. }
  331. // #endif
  332. // #ifdef MP
  333. uni.navigateTo({
  334. url: `/pages/users/alipay_invoke/index?id=${orderId}&link=${jsConfig.qrCode}`
  335. });
  336. // #endif
  337. break;
  338. }
  339. }
  340. }
  341. };
  342. </script>
  343. <style>
  344. page {
  345. background-color: #ffffff;
  346. }
  347. </style>
  348. <style lang="scss" scoped>
  349. /deep/uni-radio .uni-radio-input.uni-radio-input-checked {
  350. border: 1px solid #FDC383 !important;
  351. background-color: #FDC383 !important;
  352. }
  353. .input-section {
  354. .section-hd {
  355. padding: 30rpx;
  356. font-size: 28rpx;
  357. color: #666666;
  358. }
  359. .section-bd {
  360. padding-right: 30rpx;
  361. padding-left: 30rpx;
  362. }
  363. .input-group {
  364. display: flex;
  365. align-items: flex-end;
  366. padding: 45rpx 20rpx 47rpx;
  367. font-size: 80rpx;
  368. color: #999999;
  369. }
  370. .input {
  371. flex: 1;
  372. height: 110rpx;
  373. margin-left: 15rpx;
  374. font-size: 100rpx;
  375. color: #282828;
  376. }
  377. .discount {
  378. padding: 27rpx 20rpx;
  379. border-top: 1rpx solid #eeeeee;
  380. font-size: 28rpx;
  381. color: #e93323;
  382. }
  383. }
  384. .radio-section {
  385. border-top: 20rpx solid #f5f5f5;
  386. .section-hd {
  387. padding: 30rpx;
  388. font-size: 28rpx;
  389. color: #666666;
  390. }
  391. .section-bd {
  392. padding-left: 50rpx;
  393. }
  394. .item {
  395. display: flex;
  396. align-items: center;
  397. padding-top: 30rpx;
  398. padding-right: 30rpx;
  399. padding-bottom: 30rpx;
  400. border-bottom: 1rpx solid #f5f5f5;
  401. }
  402. .iconfont {
  403. font-size: 44rpx;
  404. }
  405. .icon-yue {
  406. color: #fe960f;
  407. }
  408. .icon-weixinzhifu {
  409. color: #41b035;
  410. }
  411. .icon-zhifubao {
  412. color: #099bdf;
  413. }
  414. .name {
  415. flex: 1;
  416. margin-left: 30rpx;
  417. font-size: 30rpx;
  418. color: #333333;
  419. }
  420. .money {
  421. float: right;
  422. padding-right: 20rpx;
  423. font-size: 20rpx;
  424. }
  425. }
  426. .button {
  427. height: 86rpx;
  428. border-radius: 43rpx;
  429. margin: 114rpx 30rpx 30rpx;
  430. background: linear-gradient(90deg, #FEE2B7 0%, #FDC383 100%);
  431. font-size: 30rpx;
  432. line-height: 86rpx;
  433. color: #5D3324;
  434. }
  435. .alipay {
  436. display: none;
  437. }
  438. </style>