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

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