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

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