金诚优选前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

734 lines
19 KiB

  1. <template>
  2. <view id="store-payment">
  3. <form @submit="formSubmit" :report-submit="report">
  4. <view class="order-item" v-if="order.status === 1 && init">
  5. <view class="title mx-1px-bottom">
  6. 商品清单
  7. </view>
  8. <view class="goods info" v-for="(item, index) in order.items" :key="index">
  9. <view class="goods-item">
  10. <view class="item-left">
  11. <image :src="item.item_meta.image"></image>
  12. </view>
  13. <view class="item-right">
  14. <view class="goods-name item">
  15. <view class="name">
  16. {{item.item_name}}
  17. </view>
  18. <view>
  19. {{item.quantity}}
  20. </view>
  21. </view>
  22. <view class="goods-money item">
  23. <view>
  24. {{item.item_meta.specs_text}}
  25. </view>
  26. <view>
  27. {{item.total / 100}}
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. <view class="order-item" v-if="order.balance_paid == 0">
  34. <view class="title mx-1px-bottom">
  35. 余额
  36. </view>
  37. <view class="balance info" v-if="balance">
  38. <view class="num">
  39. <span></span>
  40. <input type="digit" @input="modifyBalance" :value="inputBalance" :placeholder="'可使用' + paybalance.balance / 100 + '元'"></input>
  41. <i class="iconfont icon-delete" v-if="inputBalance" @tap="cancel"></i>
  42. </view>
  43. <view class="text" @tap="useAll">
  44. 全部使用
  45. </view>
  46. </view>
  47. <view class="no-balance" v-else>
  48. 您暂无可用余额
  49. </view>
  50. </view>
  51. <view class="pay-balance" v-else>
  52. 您已使用余额支付{{order.balance_paid / 100}}
  53. </view>
  54. <view class="order-item" v-if="paybalance.balance != (inputBalance * 100) || paybalance.balance == 0">
  55. <view class="title mx-1px-bottom">
  56. 支付方式
  57. </view>
  58. <view class="type info">
  59. <radio-group class="radio-group">
  60. <label class="radio">
  61. <radio checked="true" color="red"></radio>
  62. <!-- #ifdef H5 -->
  63. <text v-if="env.isWechat">微信支付</text>
  64. <text v-else>支付宝支付</text>
  65. <!-- #endif -->
  66. <!-- #ifdef APP-PLUS || MP-WEIXIN -->
  67. <text>微信支付</text>
  68. <!-- #endif -->
  69. </label>
  70. </radio-group>
  71. </view>
  72. </view>
  73. <view class="order-info">
  74. <view v-if="order.balance_paid == 0">
  75. <view class="item">
  76. <view class="left">
  77. 余额支付
  78. </view>
  79. <view class="num">
  80. {{inputBalance || 0}}
  81. </view>
  82. </view>
  83. <view class="item">
  84. <!-- #ifdef H5 -->
  85. <view class="left" v-if="env.isWechat">
  86. 微信支付
  87. </view>
  88. <view class="left" v-else>
  89. 支付宝支付
  90. </view>
  91. <!-- #endif -->
  92. <!-- #ifdef APP-PLUS || MP-WEIXIN -->
  93. <view class="left">
  94. 微信支付
  95. </view>
  96. <!-- #endif -->
  97. <view class="num">
  98. {{countMoney || order.total / 100}}
  99. </view>
  100. </view>
  101. </view>
  102. <view v-else>
  103. <view class="item">
  104. <view class="left" >
  105. 余额支付
  106. </view>
  107. <view class="num">
  108. {{order.balance_paid / 100}}
  109. </view>
  110. </view>
  111. <!-- #ifdef H5 -->
  112. <view class="item">
  113. <view class="left" v-if="env.isWechat">
  114. 微信支付
  115. </view>
  116. <view class="left" v-else>
  117. 支付宝支付
  118. </view>
  119. <view class="num">
  120. {{((order.total - order.balance_paid) / 100)}}
  121. </view>
  122. </view>
  123. <!-- #endif -->
  124. <!-- #ifdef APP-PLUS || MP-WEIXIN -->
  125. <view class="item">
  126. <view class="left">
  127. 微信支付
  128. </view>
  129. <view class="num">
  130. {{((order.total - order.balance_paid) / 100)}}
  131. </view>
  132. </view>
  133. <!-- #endif -->
  134. </view>
  135. </view>
  136. <button :style="'background: ' + config.mainColor" form-type="submit" :loading="loading">立即支付</button>
  137. </view>
  138. <view class="order-over" v-if="order.status != 1 && init">
  139. <view>
  140. 订单已支付
  141. </view>
  142. <view class="over-btn" @tap="jumpOrderDetail">
  143. 查看订单详情
  144. </view>
  145. </view>
  146. </form>
  147. </view>
  148. </template>
  149. <script>
  150. var app = getApp();
  151. import {pageLogin, getUrl,config,is} from '@/common/js/utils.js';
  152. export default {
  153. data() {
  154. return {
  155. order: {},
  156. order_no: '',
  157. channel: 'wx_lite',
  158. amount: 0,
  159. loading: false,
  160. inputBalance: '',
  161. balance: '',
  162. paybalance: {
  163. balance: 0,
  164. inputBalance: 0
  165. },
  166. countMoney: '',
  167. config: '',
  168. report: true,
  169. formId: '',
  170. init: false,
  171. // #ifdef H5
  172. env:{
  173. isIPad: /ipad/i.test(window.navigator.userAgent),
  174. isIphone: /iphone|ipad|ipod/i.test(window.navigator.userAgent),
  175. isWechat: /MicroMessenger/i.test(window.navigator.userAgent)
  176. }
  177. // #endif
  178. };
  179. },
  180. onShow() {
  181. this.queryUserSum();
  182. },
  183. onLoad(e) {
  184. // 第三方平台配置颜色
  185. var gbConfig = this.$cookieStorage.get('globalConfig') || '';
  186. this.setData({
  187. config: gbConfig
  188. });
  189. this.setData({
  190. order_no: e.order_no,
  191. loading: false
  192. });
  193. },
  194. methods: {
  195. jumpOrderDetail() {
  196. wx.redirectTo({
  197. url: `/pages/order/detail/detail?no=${this.order_no}`
  198. });
  199. },
  200. modifyBalance(e) {
  201. var val = e.detail.value;
  202. var min = 0;
  203. var balance = this.paybalanceF(val);
  204. var max = (balance.balance / 100).toFixed(2);
  205. if (!val) {
  206. val = '';
  207. } else if (/\S*$/.test(val)) {
  208. val = val.replace(/[^\d\.]|^\./g, '').replace(/\.{2}/g, '.').replace(/^([1-9]\d*|0)(\.\d{1,2})(\.|\d{1})?$/, '$1$2').replace(/^0\d{1}/g, '0');
  209. }
  210. if (Number(val) < min) {
  211. val = min;
  212. } else if (Number(val) > max) {
  213. val = max;
  214. }
  215. this.setData({
  216. inputBalance: val
  217. });
  218. this.paybalanceF(val);
  219. this.countMoneyF();
  220. return val;
  221. },
  222. useAll() {
  223. var balance = this.paybalanceF(this.order.total / 100);
  224. this.setData({
  225. inputBalance: (balance.balance / 100).toFixed(2)
  226. });
  227. this.countMoneyF();
  228. },
  229. cancel() {
  230. this.setData({
  231. inputBalance: '',
  232. channel: 'wx_lite'
  233. });
  234. this.countMoneyF();
  235. },
  236. paybalanceF(val) {
  237. var total = this.order.total;
  238. var balance = Math.min(this.balance, total);
  239. var inputBalance = val;
  240. /*if ((inputBalance * 100) == balance && balance != 0) {
  241. this.setData({
  242. channel: 'balance'
  243. })
  244. } else {
  245. this.setData({
  246. channel: 'wx_lite'
  247. })
  248. }*/
  249. var data = {
  250. balance,
  251. inputBalance
  252. };
  253. this.setData({
  254. paybalance: data
  255. });
  256. return data;
  257. },
  258. queryOrderDetail(order_no) {
  259. var oauth = this.$cookieStorage.get('user_token');
  260. this.$http.get({
  261. api: `api/order/${order_no}`,
  262. header: {
  263. Authorization: oauth
  264. }
  265. }).then(res => {
  266. if (res.statusCode == 200) {
  267. res = res.data;
  268. if (res.status) {
  269. this.$cookieStorage.set('service_retreat', res.data);
  270. this.setData({
  271. order: res.data,
  272. init: true
  273. });
  274. this.paybalanceF(0);
  275. } else {
  276. wx.showModal({
  277. content: res.message || '获取订单数据失败',
  278. showCancel: false
  279. });
  280. }
  281. wx.hideLoading();
  282. } else {
  283. wx.showModal({
  284. content: '获取订单数据失败',
  285. showCancel: false
  286. });
  287. wx.hideLoading();
  288. }
  289. }).catch(rej => {
  290. wx.hideLoading();
  291. wx.showModal({
  292. content: '获取订单数据失败',
  293. showCancel: false
  294. });
  295. });
  296. },
  297. // 新版支付
  298. newcharge(success, charge) {
  299. if (success) {
  300. var that = this;
  301. if (charge.pay_scene == 'test') {
  302. wx.showModal({
  303. content: '不支持模拟支付',
  304. showCancel: false
  305. });
  306. this.setData({
  307. loading: false
  308. });
  309. } else {
  310. wx.requestPayment({
  311. "timeStamp": charge.credential.wechat.timeStamp,
  312. "nonceStr": charge.credential.wechat.nonceStr,
  313. "package": charge.credential.wechat.package,
  314. "signType": charge.credential.wechat.signType,
  315. "paySign": charge.credential.wechat.paySign,
  316. success: res => {
  317. if (res.errMsg == 'requestPayment:ok') {
  318. this.setData({
  319. loading: false
  320. });
  321. wx.redirectTo({
  322. url: `/pages/store/success/success?order_no=${that.order_no}&amount=${that.amount}&channel=${that.channel}&formId=${this.formId}`
  323. });
  324. } else {
  325. wx.showModal({
  326. content: '调用支付失败!',
  327. showCancel: false
  328. });
  329. }
  330. },
  331. fail: err => {
  332. this.setData({
  333. loading: false
  334. });
  335. if (err.errMsg == 'requestPayment:fail cancel') {
  336. wx.redirectTo({
  337. url: `/pages/order/detail/detail?no=${that.order_no}`
  338. });
  339. } else {
  340. wx.showModal({
  341. content: '调用支付失败!',
  342. showCancel: false
  343. });
  344. }
  345. }
  346. });
  347. }
  348. } else {
  349. this.setData({
  350. loading: false
  351. });
  352. wx.showModal({
  353. content: charge || '请求支付失败,请重试!',
  354. showCancel: false
  355. });
  356. }
  357. },
  358. //app支付
  359. appPayment(success,orderInfo) {
  360. var that = this;
  361. if (success) {
  362. // 获取服务供应商
  363. uni.getProvider({
  364. service:'payment',
  365. success:ret=>{
  366. uni.requestPayment({
  367. provider:'wxpay',
  368. orderInfo:orderInfo,
  369. success: res => {
  370. if (res.errMsg == 'requestPayment:ok') {
  371. this.setData({
  372. loading: false
  373. });
  374. wx.redirectTo({
  375. url: `/pages/store/success/success?order_no=${that.order_no}&amount=${that.amount}&channel=${that.channel}&formId=${this.formId}`
  376. });
  377. } else {
  378. wx.showModal({
  379. content: '调用支付失败!',
  380. showCancel: false
  381. });
  382. }
  383. },
  384. fail: err => {
  385. this.setData({
  386. loading: false
  387. });
  388. if (err.errMsg == 'requestPayment:fail:[payment微信:-2]User canceled') {
  389. wx.redirectTo({
  390. url: `/pages/order/detail/detail?no=${that.order_no}`
  391. });
  392. } else {
  393. wx.showModal({
  394. content: '调用支付失败!',
  395. showCancel: false
  396. });
  397. }
  398. }
  399. });
  400. }
  401. })
  402. } else {
  403. this.setData({
  404. loading: false
  405. });
  406. wx.showModal({
  407. content: charge || '请求支付失败,请重试!',
  408. showCancel: false
  409. });
  410. }
  411. },
  412. // 纯余额支付
  413. balanceCharge() {
  414. this.setData({
  415. loading: false
  416. });
  417. wx.redirectTo({
  418. url: `/pages/store/success/success?order_no=${this.order_no}&amount=${this.amount}&channel=${this.channel}&formId=${this.formId}`
  419. });
  420. },
  421. // 查询用户余额信息
  422. queryUserSum() {
  423. var oauth = this.$cookieStorage.get('user_token');
  424. wx.showLoading({
  425. title: '加载中',
  426. mask: true
  427. });
  428. this.$http.get({
  429. api: 'api/users/balance/sum',
  430. header: {
  431. Authorization: oauth
  432. }
  433. }).then(res => {
  434. if (res.statusCode == 200) {
  435. res = res.data;
  436. if (res.status) {
  437. this.setData({
  438. balance: res.data.sum
  439. });
  440. this.queryOrderDetail(this.order_no);
  441. } else {
  442. wx.hideLoading();
  443. wx.showModal({
  444. content: res.message || '请求失败',
  445. showCancel: false
  446. });
  447. }
  448. } else {
  449. wx.hideLoading();
  450. wx.showModal({
  451. content: '请求失败',
  452. showCancel: false
  453. });
  454. }
  455. });
  456. },
  457. getOpenid() {
  458. return new Promise((resolve, reject) => {
  459. wx.login({
  460. success: res => {
  461. this.$http.get({
  462. api: `api/oauth/miniprogram/openid`,
  463. data: {
  464. code: res.code
  465. }
  466. }).then(res => {
  467. res = res.data;
  468. resolve(res.data.openid);
  469. }).catch(() => {
  470. reject('获取openid失败');
  471. });
  472. },
  473. fail: () => {
  474. wx.showModal({
  475. content: "接口请求失败",
  476. showCancel: false
  477. });
  478. }
  479. });
  480. });
  481. },
  482. // #ifdef MP-WEIXIN
  483. formSubmit(e) {
  484. if (this.loading) return;
  485. this.setData({
  486. loading: true
  487. });
  488. var oauth = this.$cookieStorage.get('user_token');
  489. this.getOpenid().then(res => {
  490. var data = {
  491. channel: this.channel,
  492. openid: res,
  493. order_no: this.order_no,
  494. balance: Number(this.inputBalance)
  495. };
  496. if (this.$cookieStorage.get('agent_code')) {
  497. data.agent_code = this.$cookieStorage.get('agent_code');
  498. }
  499. this.$http.post({
  500. api: `api/shopping/order/charge`,
  501. data: data,
  502. header: {
  503. Authorization: oauth
  504. }
  505. }).then(res => {
  506. res = res.data;
  507. if (res.status) {
  508. this.formId = e.detail.formId || '';
  509. if (res.data.name == 'balance') {
  510. this.balanceCharge();
  511. } else {
  512. this.newcharge(true, res.data.charge);
  513. }
  514. } else {
  515. this.newcharge(false, res.message);
  516. }
  517. })
  518. }).catch(() => {
  519. this.setData({
  520. loading: false
  521. });
  522. wx.showModal({
  523. content: '支付失败',
  524. showCancel: false
  525. });
  526. });
  527. },
  528. // #endif
  529. //h5支付
  530. // #ifdef H5
  531. formSubmit(e) {
  532. if (this.loading) return;
  533. this.setData({
  534. loading: true
  535. });
  536. let env = {
  537. isIPad: /ipad/i.test(window.navigator.userAgent),
  538. isIphone: /iphone|ipad|ipod/i.test(window.navigator.userAgent),
  539. isWechat: /MicroMessenger/i.test(window.navigator.userAgent)
  540. }
  541. if(this.channel=='wx_lite'){
  542. if(env.isWechat){
  543. this.channel='wx_pub';
  544. } else{
  545. this.channel='alipay_wap';
  546. }
  547. }
  548. var oauth = this.$cookieStorage.get('user_token');
  549. if(env.isWechat){
  550. var openid = this.$cookieStorage.get('openid');
  551. } else{
  552. var openid = '';
  553. }
  554. let origin = window.location.origin;
  555. let pathname = window.location.pathname;
  556. var url = origin+'/pages/store/success/success?order_no='+this.order_no;
  557. var fail_url = origin+'/pages/order/detail/detail?no='+this.order_no;
  558. var data = {
  559. channel: this.channel,
  560. order_no: this.order_no,
  561. balance: Number(this.inputBalance),
  562. extra:{
  563. openid:openid,
  564. successUrl:url,
  565. failUrl:fail_url
  566. }
  567. };
  568. this.$http.post({
  569. api:'api/shopping/order/charge',
  570. data:data,
  571. header:{
  572. Authorization: oauth
  573. }
  574. }).then(res=>{
  575. res = res.data;
  576. if(res.status){
  577. if(res.data.redirect_url){
  578. var redirect_url = res.data.redirect_url
  579. window.location.href=redirect_url;
  580. }
  581. }else{
  582. wx.showModal({
  583. content: res.message||'支付失败',
  584. showCancel: false
  585. });
  586. }
  587. }).catch(rej=>{
  588. this.setData({
  589. loading: false
  590. });
  591. wx.showModal({
  592. content: rej.message||'支付失败',
  593. showCancel: false
  594. });
  595. })
  596. },
  597. // #endif
  598. // app支付
  599. // #ifdef APP-PLUS
  600. formSubmit(e) {
  601. if (this.loading) return;
  602. this.setData({
  603. loading: true
  604. });
  605. if(this.channel=='wx_lite'){
  606. this.channel='wx_app';
  607. }
  608. var oauth = this.$cookieStorage.get('user_token');
  609. var data = {
  610. channel: this.channel,
  611. order_no: this.order_no,
  612. balance: Number(this.inputBalance)
  613. };
  614. if (this.$cookieStorage.get('agent_code')) {
  615. data.agent_code = this.$cookieStorage.get('agent_code');
  616. }
  617. this.$http.post({
  618. api: `api/shopping/order/charge`,
  619. data: data,
  620. header: {
  621. Authorization: oauth
  622. }
  623. }).then(res => {
  624. res = res.data;
  625. if (res.status) {
  626. this.formId = e.detail.formId || '';
  627. if (res.data.name == 'balance') {
  628. this.balanceCharge();
  629. } else{
  630. this.appPayment(true,JSON.stringify(res.data))
  631. }
  632. } else{
  633. this.appPayment(false,res.message)
  634. }
  635. }).catch(rej=>{
  636. this.setData({
  637. loading: false
  638. });
  639. wx.showModal({
  640. content: rej.message||'支付失败',
  641. showCancel: false
  642. });
  643. })
  644. },
  645. // #endif
  646. countMoneyF() {
  647. this.setData({
  648. countMoney: (this.order.total / 100 - this.inputBalance).toFixed(2)
  649. });
  650. },
  651. setData: function (obj) {
  652. let that = this;
  653. let keys = [];
  654. let val, data;
  655. Object.keys(obj).forEach(function (key) {
  656. keys = key.split('.');
  657. val = obj[key];
  658. data = that.$data;
  659. keys.forEach(function (key2, index) {
  660. if (index + 1 == keys.length) {
  661. that.$set(data, key2, val);
  662. } else {
  663. if (!data[key2]) {
  664. that.$set(data, key2, {});
  665. }
  666. }
  667. data = data[key2];
  668. });
  669. });
  670. }
  671. }
  672. };
  673. </script>
  674. <style rel="stylesheet/less" lang="less">
  675. @import "payment";
  676. </style>