金诚优选前端代码
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.

397 lines
9.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <template>
  2. <view>
  3. <lf-nav title="支付收银台" :showIcon="true" bgColor="#fff"></lf-nav>
  4. <view class="content">
  5. <view class="card lf-flex-column lf-row-center">
  6. <view class="lf-font-28 lf-color-222">需要支付</view>
  7. <view class="lf-m-t-10 lf-m-b-10">
  8. <text class="symbol"></text>
  9. <text class="price">{{ amount }}</text>
  10. </view>
  11. <view class="tips">
  12. <view>剩余支付时间</view>
  13. <view>
  14. <!-- <countdown-timer :time="time" :autoStart="true" @finish="dateFinish">
  15. <template v-slot="{minute, second}">
  16. <view class="lf-flex">
  17. <view>{{ minute >= 10 ? minute : "0" + minute }}</view>
  18. <view>:</view>
  19. <view>{{ second >= 10 ? second : "0" + second }}</view>
  20. </view>
  21. </template>
  22. </countdown-timer> -->
  23. <countdown-time :minute="last_pay_time[2]" :second="last_pay_time[3]" :showDay="false" :showHour="false" color="#FF9D9D" splitorColor="#FF9D9D">
  24. </countdown-time>
  25. </view>
  26. </view>
  27. </view>
  28. <label class="card lf-row-between" v-for="(item, index) in pay_list" :key="index"
  29. style="padding: 16rpx 40rpx;">
  30. <view>
  31. <text class="lf-iconfont lf-font-50 lf-text-vertical" :class="item.icon"
  32. :style="{color: item.color}"></text>
  33. <text class="lf-m-l-10 lf-font-28 lf-color-222">{{ item.name }}</text>
  34. </view>
  35. <radio-group @change="checkChange($event, index)">
  36. <radio :checked="item.checked"></radio>
  37. </radio-group>
  38. </label>
  39. </view>
  40. <view class="fixed-btn" hover-class="lf-opacity" @click="confirm">立即支付</view>
  41. <view class="fixed-agreement">购买须知</view>
  42. <lf-pay-password v-if="show_pw" @comfirm="payComfirm" title="请输入支付密码" buttonText="确认支付"></lf-pay-password>
  43. </view>
  44. </template>
  45. <script>
  46. import countdownTime from '@/components/uni-countdown/uni-countdown.vue';
  47. import lfPayPassword from '@/components/lf-payPassword/lf-payPassword.vue'
  48. export default {
  49. components: {
  50. countdownTime,
  51. lfPayPassword
  52. },
  53. data() {
  54. return {
  55. pay_list: [{
  56. name: '余额支付',
  57. icon: 'icon-yuebao',
  58. type: 'balance',
  59. checked: false,
  60. color: '#15716E'
  61. }, {
  62. name: '微信支付',
  63. icon: 'icon-weixinzhifu',
  64. type: 'wx_lite',
  65. checked: true,
  66. color: '#09BB07'
  67. }],
  68. time: new Date('2021/09/8 14:15:00').getTime() - new Date('2021/09/8 14:10:00').getTime(),
  69. is_date_finish: false,
  70. amount: '',
  71. order_no: '',
  72. token: '',
  73. balance_sum: 0,
  74. show_pw: false,
  75. user_pw: '',
  76. clickContinue: true,
  77. last_pay_time: []
  78. }
  79. },
  80. onLoad(options) {
  81. this.token = this.$cookieStorage.get('user_token');
  82. this.last_pay_time = this.$cookieStorage.get('last_pay_time') || [0,0,29,58];
  83. this.amount = options.amount;
  84. this.order_no = options.order_no;
  85. this.getBalanceSum();
  86. },
  87. onUnload(){
  88. this.$cookieStorage.clear('last_pay_time');
  89. },
  90. methods: {
  91. // 获取余额
  92. getBalanceSum() {
  93. this.$http.get({
  94. api: 'api/users/balance/sum',
  95. header: {
  96. Authorization: this.token
  97. }
  98. }).then(res => {
  99. this.balance_sum = res.data.data.sum;
  100. })
  101. },
  102. // 改变支付方式
  103. checkChange(event, current) {
  104. let list = this.pay_list.map((item, index) => {
  105. if (index == current) {
  106. item.checked = true;
  107. } else {
  108. item.checked = false;
  109. }
  110. return item;
  111. })
  112. this.pay_list = list;
  113. },
  114. // 倒计时结束
  115. dateFinish() {
  116. console.log("倒计时结束");
  117. this.is_date_finish = true;
  118. this.$msg('订单超时', {
  119. icon: 'error'
  120. }).then(() => {
  121. this.$toBack();
  122. })
  123. },
  124. // 支付密码输入完成
  125. payComfirm(event) {
  126. this.user_pw = event;
  127. this.clickContinue = true;
  128. this.confirm();
  129. },
  130. // 支付
  131. confirm(event) {
  132. if (this.clickContinue == true) {
  133. this.clickContinue = false;
  134. if (this.is_date_finish) return this.$msg('订单超时未支付');
  135. let channel = '';
  136. this.pay_list.map(item => {
  137. if (item.checked) {
  138. channel = item.type;
  139. }
  140. })
  141. if (channel == 'balance' && !this.user_pw) {
  142. this.show_pw = true;
  143. return;
  144. }
  145. uni.showLoading({
  146. title: '正在支付,请稍后'
  147. })
  148. this.getOpenid().then(res => {
  149. var data = {
  150. channel: 'wx_lite',
  151. openid: res,
  152. order_no: this.order_no,
  153. balance: 0
  154. };
  155. if (channel == 'balance') {
  156. data.pay_pwd = this.user_pw;
  157. data.balance = Number(this.amount);
  158. data.channel = 'wx_lite';
  159. }
  160. this.$http.post({
  161. api: `api/shopping/order/charge`,
  162. data: data,
  163. header: {
  164. Authorization: this.token
  165. }
  166. }).then(res => {
  167. uni.hideLoading()
  168. res = res.data;
  169. if (res.status) {
  170. // this.formId = e.detail.formId || '';
  171. if (res.data.name == 'balance') {
  172. this.balanceCharge();
  173. } else {
  174. this.newcharge(true, res.data.charge);
  175. }
  176. } else {
  177. this.newcharge(false, res.message);
  178. this.show_pw = false;
  179. }
  180. this.clickContinue = true;
  181. })
  182. }).catch(() => {
  183. this.clickContinue = true;
  184. this.show_pw = false;
  185. this.setData({
  186. loading: false
  187. });
  188. uni.hideLoading()
  189. wx.showModal({
  190. content: '支付失败',
  191. showCancel: false
  192. });
  193. });
  194. }
  195. },
  196. // 获取openid
  197. getOpenid() {
  198. return new Promise((resolve, reject) => {
  199. wx.login({
  200. success: res => {
  201. this.$http.get({
  202. api: `api/oauth/miniprogram/openid`,
  203. data: {
  204. code: res.code
  205. }
  206. }).then(res => {
  207. res = res.data;
  208. resolve(res.data.openid);
  209. }).catch(() => {
  210. reject('获取openid失败');
  211. });
  212. },
  213. fail: () => {
  214. wx.showModal({
  215. content: "接口请求失败",
  216. showCancel: false
  217. });
  218. }
  219. });
  220. });
  221. },
  222. // 新版支付
  223. newcharge(success, charge) {
  224. if (success) {
  225. var that = this;
  226. if (charge.pay_scene == 'test') {
  227. wx.showModal({
  228. content: '不支持模拟支付',
  229. showCancel: false
  230. });
  231. this.setData({
  232. loading: false
  233. });
  234. } else {
  235. wx.requestPayment({
  236. "timeStamp": charge.credential.wechat.timeStamp,
  237. "nonceStr": charge.credential.wechat.nonceStr,
  238. "package": charge.credential.wechat.package,
  239. "signType": charge.credential.wechat.signType,
  240. "paySign": charge.credential.wechat.paySign,
  241. success: res => {
  242. if (res.errMsg == 'requestPayment:ok') {
  243. this.setData({
  244. loading: false
  245. });
  246. // wx.redirectTo({
  247. // url: `/pages/store/success/success?order_no=${that.order_no}&amount=${that.amount}&channel=${that.channel}&formId=${this.formId}` //&charge_id=${charge.charge_id} charge_id 支付测试使用
  248. // });
  249. uni.redirectTo({
  250. url: '/pages/aboutpay/paystate?payState=1&amount=' + that
  251. .amount
  252. })
  253. } else {
  254. wx.showModal({
  255. content: '调用支付失败!',
  256. showCancel: false
  257. });
  258. }
  259. },
  260. fail: err => {
  261. this.setData({
  262. loading: false
  263. });
  264. if (err.errMsg == 'requestPayment:fail cancel') {
  265. // wx.redirectTo({
  266. // url: `/pages/order/detail/detail?no=${that.order_no}`
  267. // });
  268. uni.redirectTo({
  269. url: '/pages/order/index/onlineorder'
  270. })
  271. } else {
  272. wx.showModal({
  273. content: '调用支付失败!',
  274. showCancel: false
  275. });
  276. }
  277. }
  278. });
  279. }
  280. } else {
  281. this.setData({
  282. loading: false
  283. });
  284. wx.showModal({
  285. content: charge || '请求支付失败,请重试!',
  286. showCancel: false
  287. });
  288. this.user_pw = '';
  289. }
  290. },
  291. // 纯余额支付
  292. balanceCharge() {
  293. this.setData({
  294. loading: false
  295. });
  296. // wx.redirectTo({
  297. // url: `/pages/store/success/success?order_no=${this.order_no}&amount=${this.amount}&channel=${this.channel}&formId=${this.formId}`
  298. // });
  299. uni.redirectTo({
  300. url: '/pages/aboutpay/paystate?payState=1&amount=' + this.amount
  301. })
  302. },
  303. setData: function(obj) {
  304. let that = this;
  305. let keys = [];
  306. let val, data;
  307. Object.keys(obj).forEach(function(key) {
  308. keys = key.split('.');
  309. val = obj[key];
  310. data = that.$data;
  311. keys.forEach(function(key2, index) {
  312. if (index + 1 == keys.length) {
  313. that.$set(data, key2, val);
  314. } else {
  315. if (!data[key2]) {
  316. that.$set(data, key2, {});
  317. }
  318. }
  319. data = data[key2];
  320. });
  321. });
  322. }
  323. }
  324. }
  325. </script>
  326. <style>
  327. page {
  328. background-color: #F8F8F8;
  329. }
  330. </style>
  331. <style lang="scss" scoped="scoped">
  332. .content {
  333. padding: 30rpx 32rpx;
  334. width: 750rpx;
  335. height: max-content;
  336. box-sizing: border-box;
  337. .card {
  338. width: 100%;
  339. height: max-content;
  340. padding: 30rpx 40rpx;
  341. background-color: #FFFFFF;
  342. border-radius: 20rpx;
  343. &:nth-child(n+2) {
  344. margin-top: 30rpx;
  345. }
  346. .symbol {
  347. color: #15716E;
  348. font-size: 32rpx;
  349. }
  350. .price {
  351. font-size: 72rpx;
  352. color: #15716E;
  353. font-weight: bold;
  354. }
  355. .tips {
  356. font-size: 24rpx;
  357. color: #FF9D9D;
  358. display: flex;
  359. align-items: center;
  360. }
  361. }
  362. }
  363. .fixed-agreement {
  364. position: fixed;
  365. bottom: 5vh;
  366. font-size: 28rpx;
  367. color: #15716E;
  368. left: calc(50% - 84rpx);
  369. width: 168rpx;
  370. }
  371. .fixed-btn {
  372. position: fixed;
  373. bottom: 10vh;
  374. left: calc(50% - 275rpx);
  375. width: 550rpx;
  376. height: 100rpx;
  377. background-color: #15716E;
  378. color: #FFFFFF;
  379. text-align: center;
  380. line-height: 100rpx;
  381. font-size: 32rpx;
  382. border-radius: 50rpx;
  383. }
  384. </style>