Browse Source

update pay

warrior 2 months ago
parent
commit
de22d16b9a

+ 1 - 1
projects/live-app/src/app/components/pay-comp/pay-comp.component.ts

@@ -187,7 +187,7 @@ export class PayCompComponent implements OnInit {
       company: this.accServ.company,
       out_trade_no: this.tradeNo,
       total_fee: this.price,
-      body: 'title',
+      body: this.title,
     };
     Parse.Cloud.run('pay_code2', params)
       .then(async (res) => {

+ 41 - 18
projects/live-app/src/modules/account/recharge/recharge.component.html

@@ -2,27 +2,50 @@
 <div class="recharge-content">
   <div class="options">
     @for (val of options; track $index) {
-    <div class="select" (click)="onChange(val)">{{ val }}</div>
+    <div class="select" (click)="onChange(val)">
+      {{ val * 10 }}钻石
+    <span>¥{{val}}</span>
+    </div>
     }
   </div>
+  <div class="h3">
+    <span>充值记录</span>
+  </div>
   <div class="li">
-    <input
-      type="number"
-      [(ngModel)]="price"
-      maxlength="8"
-      name="price"
-      autocomplete="off"
-      placeholder="请输入充值金额"
-      class="input"
-    />
+    <div class="int">
+      充值金额(¥)
+      <input
+        type="number"
+        [(ngModel)]="price"
+        maxlength="8"
+        name="price"
+        autocomplete="off"
+        min="10"
+        placeholder="最低充值金额不少于1元"
+        class="input"
+        (blur)="onChangeInput()"
+      />
+    </div>
+    <div class="desc">
+      钻石:{{price * 10}}
+    </div>
   </div>
 
-  <div class="confirm" (click)="showPay()">充值</div>
-  <ion-alert
-    [isOpen]="modal"
-    trigger="present-alert"
-    header="Select your favorite color"
-    [buttons]="alertButtons"
-    [inputs]="alertInputs"
-  ></ion-alert>
+  <div
+    class="confirm"
+    [style.background]="price > 0 ? '#92a1ff' : '#b7b7b7'"
+    (click)="onShowPay()"
+  >
+    下一步
+  </div>
 </div>
+@if (showPay) {
+  <app-pay-comp
+    (payResult)="onComplete($event)"
+    [tradeNo]="tradeNo"
+    [orderType]="'balance'"
+    [price]="price"
+    #paycomp
+  ></app-pay-comp>
+  }
+  

+ 96 - 67
projects/live-app/src/modules/account/recharge/recharge.component.scss

@@ -1,74 +1,103 @@
 .recharge-content {
-	background-image: url("https://file-cloud.fmode.cn/uiZD6NisQm/20220831/g1bkbm102855.png");
-	background-repeat: no-repeat;
-	background-position: center top;
-	background-size: 100% 100%;
-	height: 100%;
-	padding-top: 10px;
-	width: 100%;
-	text-align: center;
-	.options{
-		display: grid;
-		grid-template-columns: repeat(4, 1fr);
-		grid-gap: 10px;
-		padding: 6px;
-		.select{
-			padding: 10px 0;
-			border: 1px solid;
+  background-image: url("https://file-cloud.fmode.cn/uiZD6NisQm/20220831/g1bkbm102855.png");
+  background-repeat: no-repeat;
+  background-position: center top;
+  background-size: 100% 100%;
+  height: 100%;
+  padding-top: 10px;
+  width: 100%;
+  text-align: center;
+  .options {
+    display: grid;
+    grid-template-columns: repeat(4, 1fr);
+    grid-gap: 10px;
+    padding: 6px;
+		background: white;
+    .select {
+      display: flex;
+      flex-direction: column;
+      padding: 10px 0;
+      border: 1px solid #ebebeb;
+      border-radius: 4px;
+      font-size: 14px;
+      span {
+        font-size: 12px;
+        color: #c5000f;
+      }
+    }
+		.select:active{
+      border: 1px solid #92a1ff;
 		}
-	}
-
-	.li {
-		display: flex;
-		align-items: center;
-		width: 93.3333vw;
-		padding: 2.6667vw;
-		margin: 0 auto;
-		margin-top: 20px;
-		border-radius: 2.6667vw;
-		font-size: 5.2667vw;
-		font-family: Source Han Sans CN;
-		font-weight: 500;
-		// color: #FFFFFF;
-		// background: #353C4D;
-		border: 1px solid #000000;
-
-		.input {
-			margin-left: 10px;
-			border-radius: 1.6vw;
-			border: none;
-			// background: #353c4d;
-			color: #000000;
-			font-size: 14px;
-			flex: 1;
-			width: 200px;
-			background: none;
+  }
+  .h3 {
+    margin-top: 20px;
+    text-align: left;
+    padding: 2.6667vw;
+    span {
+      // color: #000000;
+      font-size: 12px;
+    }
+  }
+  .li {
+		background: white;
+    // border: 1px solid #000000;
+    padding: 2.6667vw;
+    width: 370px;
+    margin: 0 auto;
+    border-radius: 2.6667vw;
+    .int {
+      display: flex;
+      align-items: center;
+      // margin-top: 20px;
+      font-size: 14px;
+      font-family: Source Han Sans CN;
+      font-weight: 500;
+      // color: #FFFFFF;
+      // background: #353C4D;
+      .input {
+				padding: 4px 6px;
+        margin-left: 10px;
+        border-radius: 1.6vw;
+        border: 1px solid #d3d3d3;
+        // background: #353c4d;
+        color: #c5000f;
+        font-size: 16px;
+        flex: 1;
+        width: 200px;
+        background: none;
+				outline: none;
+      }
+    }
+		.desc{
+			margin-top: 4px;
+			font-size: 12px;
+			text-align: left;
 		}
-	}
+  }
 
-	.confirm {
-		width: 150px;
-		background: #92a1ff;
-		border-radius: 4px;
-		padding: 10px 0 10px 0;
-		margin: 0 auto;
-		margin-top: 70px;
-		color: #fff;
-	}
+  .confirm {
+    width: 280px;
+    background: #92a1ff;
+    border-radius: 4px;
+    padding: 10px 0 10px 0;
+    margin: 0 auto;
+    margin-top: 70px;
+    color: #fff;
+  }
 
-	modal {
-		margin-top: -100px;
+  modal {
+    margin-top: -100px;
 
-		.confirm {
-			margin-top: 10px;
-			margin-bottom: -10px;
-			color: #fff;
-			text-align: center;
-			background: #d81e06;
+    .confirm {
+      margin-top: 10px;
+      margin-bottom: -10px;
+      color: #fff;
+      text-align: center;
+      background: #d81e06;
 
-			&:active {
-				background: #a11d0b;
-			}
-		}
-	}
-}
+      &:active {
+        background: #a11d0b;
+      }
+    }
+  }
+}

+ 23 - 273
projects/live-app/src/modules/account/recharge/recharge.component.ts

@@ -1,9 +1,8 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 import * as Parse from 'parse';
 import { HttpClient } from '@angular/common/http';
 import { Router } from '@angular/router';
-import { catchError } from 'rxjs/operators';
 import {
   LoadingController,
   ToastController,
@@ -12,112 +11,33 @@ import {
 } from '@ionic/angular';
 import { Wechat } from '@ionic-native/wechat/ngx';
 import { NavComponent } from '../../../app/components/nav/nav.component';
-declare var wx: any;
-
+import { PayCompComponent } from '../../../app/components/pay-comp/pay-comp.component';
 @Component({
   selector: 'app-recharge',
   templateUrl: './recharge.component.html',
   styleUrls: ['./recharge.component.scss'],
   standalone: true,
-  imports: [IonicModule, NavComponent, FormsModule],
+  imports: [IonicModule, NavComponent, FormsModule, PayCompComponent],
 })
 export class RechargeComponent implements OnInit {
+  @ViewChild('paycomp') paycomp!: PayCompComponent;
   options: Array<number> = [30, 50, 100, 200, 500, 1000, 2000, 5000];
   price: any = 0;
   loading: any;
   company = localStorage.getItem('company');
   account?: Parse.Object;
-  public modal: boolean = false;
-  public method: any = { value: 'wx', name: '微信支付' };
-  public alertInputs = [
-    {
-      label: '微信支付',
-      type: 'radio',
-      value: 'wx',
-    },
-    {
-      label: '其他支付',
-      type: 'radio',
-      value: 'zfb',
-    },
-  ];
-  public alertButtons = [
-    {
-      text: 'Cancel',
-      role: 'cancel',
-      handler: () => {
-        console.log('Alert canceled');
-      },
-    },
-    {
-      text: 'OK',
-      role: 'confirm',
-      handler: () => {
-        this.confirmRechare();
-      },
-    },
-  ];
-  public data: Array<object> = [
-    {
-      value: 'wx',
-      name: '微信支付',
-      icon: 'https://file-cloud.fmode.cn/uiZD6NisQm/20220810/kvp1el034906.png',
-    },
-    {
-      value: 'zfb',
-      name: '其他支付',
-      icon: 'https://file-cloud.fmode.cn/uiZD6NisQm/20220810/6pr338034905.png',
-    },
-  ];
-  wxpayEnabled = false;
-  wxAppId = '';
+  showPay: boolean = false;
+  tradeNo: string = ''; //支付单号
+  orderId?: string;
   constructor(
-    private http: HttpClient,
     public toastController: ToastController,
     public loadingController: LoadingController,
-    // private wxSDK: Wechat,
-    private router: Router,
-    private platform: Platform
+    private router: Router
   ) {}
   ngOnInit() {
-    let ua = navigator.userAgent.toLowerCase();
-    let isWeixin = ua.indexOf('micromessenger') != -1;
-    if (isWeixin) {
-      this.getWXSignPackageInWechat();
-    }
     this.getAccount();
   }
 
-  // 获取微信签名
-  getWXSignPackageInWechat() {
-    let that = this;
-    let params = {
-      company: localStorage.getItem('company'),
-      href: encodeURIComponent(location.href.split('#')[0]),
-    };
-    this.http
-      .post(`https://test.fmode.cn/api/wechat/getconfig`, params)
-      .subscribe((response) => {
-        // 返回的签名信息
-        let res: any = response;
-        const signPackage = res.data;
-        that.wxAppId = signPackage.appid;
-        this.wxpayEnabled = true;
-        wx.config({
-          debug: false, // 开启调试模式
-          appId: signPackage.appid, // 必填,公众号的唯一标识
-          timestamp: signPackage.timestamp, // 必填,生成签名的时间戳
-          nonceStr: signPackage.nonceStr, // 必填,生成签名的随机串
-          signature: signPackage.signature, // 必填,签名,见附录1
-          jsApiList: [
-            'chooseWXPay', // JSAPI微信支付
-          ], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
-        });
-        wx.ready(() => {});
-        wx.error(() => {});
-      });
-  }
-
   back() {
     history.back();
   }
@@ -129,12 +49,16 @@ export class RechargeComponent implements OnInit {
     console.log(this.account);
   }
 
-  onChange(event: any) {
-    this.method = JSON.parse(JSON.stringify(event));
-    console.log(this.method);
+  onChange(val: number) {
+    console.log(val);
+    this.price = val;
   }
-
-  async showPay() {
+  onChangeInput() {
+    this.price = this.price < 1 ? 1 : Math.floor(this.price);
+    console.log(this.price);
+  }
+  async onShowPay() {
+    if (this.price <= 0) return;
     if (this.price <= 0 || isNaN(this.price)) {
       return this.presentToast(
         `充值错误,请重新确认充值金额!`,
@@ -143,154 +67,12 @@ export class RechargeComponent implements OnInit {
       );
     }
     if (this.price > 100000) {
-      return this.presentToast('单笔充值最多不超过100000元', 1500, 'danger');
+      return this.presentToast('单笔充值最多不超过100000元', 1500, 'danger');
     }
-    this.modal = true;
     this.price = parseInt(this.price);
+    this.showPay = true;
+    this.paycomp.isOpen = true;
   }
-
-  async confirmRechare() {
-    let now = new Date();
-    let tradeNo =
-      'C' +
-      String(now.getFullYear()) +
-      (now.getMonth() + 1) +
-      now.getDate() +
-      now.getHours() +
-      now.getMinutes() +
-      now.getSeconds() +
-      Math.random().toString().slice(-6); //生成六位随机数
-    console.log('订单编号:', tradeNo);
-    console.log(this.method.value);
-
-    // if (this.method.value == 'outline') {
-    // 	await this.updataOrder(tradeNo, 'outline')
-    // 	this.presentToast(`请选择支付方式`, 1500, "success");
-    // 	return
-    // } else
-    if (this.method.value == 'wx') {
-      let ua = navigator.userAgent.toLowerCase();
-
-      let isWeixin = ua.indexOf('micromessenger') != -1;
-      if (isWeixin) {
-        // 微信支付
-        await this.wxPay(tradeNo);
-      } else if (this.platform.is('cordova')) {
-        // APP 调起微信支付
-        this.presentToast(
-          `APP内暂不支持微信支付请前往微信端网页进行支付`,
-          3000,
-          'success'
-        );
-        return;
-        await this.openWxPay(tradeNo);
-      } else {
-        this.presentToast(`微信支付请在微信进入应用`, 1500, 'success');
-      }
-    } else {
-      this.presentToast(`待开通支付通道`, 1500, 'success');
-    }
-  }
-
-  // 调起微信支付
-  async openWxPay(tradeNo: string) {
-    let loading = await this.loadingController.create({
-      cssClass: 'my-custom-class',
-      message: '支付跳转...',
-      duration: 1500,
-    });
-    loading.present();
-    let params = {
-      company: this.company,
-      out_trade_no: tradeNo,
-      total_fee: this.price,
-    };
-    try {
-      this.http
-        .post(`https://server.fmode.cn/api/wxpay/newsdkorder`, params)
-        .pipe(
-          catchError(async (e) => {
-            // 显示报错
-            loading.present();
-            await this.presentToast(
-              `服务器请求错误,请稍后重试`,
-              1500,
-              'danger'
-            );
-          })
-        )
-        .subscribe(async (response) => {
-          let payParams: any = response;
-          console.log(payParams);
-
-          // this.wxSDK
-          // 	.sendPaymentRequest({
-          // 		appid: payParams.appid, // merchant id
-          // 		partnerid: payParams.partnerid, // merchant id
-          // 		prepayid: payParams.prepayid, // prepay id
-          // 		package: payParams.package, // nonce
-          // 		noncestr: payParams.noncestr, // nonce
-          // 		timestamp: payParams.timestamp, // timestamp
-          // 		sign: payParams.sign, // signed string
-          // 	})
-          // 	.then(async (data) => {
-          // 		if (data) {
-          // 			loading.present();
-          // 			console.log('支付成功返回结果:', data);
-          // 			await this.updataOrder(tradeNo, '微信')
-          // 		}
-          // 	})
-          // 	.catch(async (error) => {
-          // 		loading.present();
-          // 		await this.presentToast(`支付失败`, 1500, "danger");
-          // 		console.log('调起微信失败', error);
-          // 	});
-        });
-    } catch (error) {
-      loading.present();
-      await this.presentToast(`支付失败`, 1500, 'danger');
-      console.log(error);
-    }
-  }
-
-  // 微信浏览器内支付
-  async wxPay(tradeNo: string) {
-    let openid = localStorage.getItem('openid');
-    if (openid) {
-      let params = {
-        company: this.company,
-        out_trade_no: tradeNo,
-        total_fee: this.price,
-        openid: openid,
-        appid: 'wxb4579e09e263afa9',
-      };
-      let that = this;
-      this.http
-        .post(`https://test.fmode.cn/api/wxpay/neworder`, params)
-        .subscribe(async (response) => {
-          let accountLog: any = await this.updataOrder(tradeNo, '微信');
-          let payinfo: any = response;
-          wx.chooseWXPay({
-            timestamp: payinfo.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
-            nonceStr: payinfo.nonceStr, // 支付签名随机串,不长于 32 位
-            package: payinfo.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
-            signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
-            paySign: payinfo.paySign, // 支付签名
-            success: async (res: any) => {
-              // 支付成功后的回调函数
-              if (res) {
-                accountLog.set('isVerified', true);
-                await accountLog.save();
-                that.presentToast(`充值成功`, 1500, 'success');
-                that.modal = false;
-                that.price = 0;
-              }
-            },
-          });
-        });
-    }
-  }
-
   async presentToast(title: string, time: number, color: string) {
     const toast = await this.toastController.create({
       message: title,
@@ -299,40 +81,8 @@ export class RechargeComponent implements OnInit {
     });
     toast.present();
   }
-  //充值记录
-  async updataOrder(tradeNo: string, type: string) {
-    let AccountLog = Parse.Object.extend('AccountLog');
-    let account = new AccountLog();
-    account.set('isVerified', false);
-    account.set('company', {
-      __type: 'Pointer',
-      className: 'Company',
-      objectId: this.company,
-    });
-    account.set('targetAccount', {
-      __type: 'Pointer',
-      className: 'Account',
-      objectId: this.account?.id,
-    });
-    account.set('fromName', 'system');
-    account.set('fromAccountName', 'system');
-    account.set('orderNumber', tradeNo);
-    account.set('desc', `${type}充值${this.price}`);
-    account.set('assetType', 'balance');
-    account.set('orderType', `${type}recharge`);
-    account.set('assetCount', this.price);
-    account.save().then((res: any) => {
-      return res;
-      // res.set("isVerified", true)
-      // res.save().then(res => {
-      // 	this.presentToast(`充值成功`, 1500, "success");
-      // 	this.modal = false
-      // 	this.price = 0
-      // })
-    });
-  }
-
-  onClose() {
-    this.modal = false;
+  onComplete(evet: any) {
+    console.log(evet);
+    this.tradeNo = evet.tradeNo;
   }
 }

+ 1 - 1
projects/live-app/src/modules/account/wattle/wattle.component.html

@@ -5,7 +5,7 @@
       <div class="account_info">
         <div class="balance">
           <div class="count">{{ account?.balance?.toFixed(2) || 0 }}</div>
-          <div class="title">我的余额</div>
+          <div class="title">钻石余额</div>
         </div>
       </div>
       <div class="figure">

+ 9 - 19
projects/live-app/src/modules/goods/vip/vip.component.html

@@ -6,29 +6,19 @@
       <img class="img" [src]="user?.get('avatar')" mode="aspectFill" />
       <div class="name">{{ user.get("nickname") || user.get("mobile") }}</div>
       <div class="text-info">
+        @if (myVip) {
         <div class="text-top">
-          @if (myVip) {
-          <div class="text1">
+          <div class="text-span">
             {{ myVip.validity ? myVip.grade : "会员已过期" }}
           </div>
-          } @else{
-          <div class="text1">未开通</div>
-          }
-          <!-- <div class="text2">
-            钥匙:{{ account.seeKeys ? account.seeKeys : 0 }}
-          </div>
-          <div class="text3">
-            牵线次数:{{ account.together ? account.together : 0 }}
+          <div class="text-span">
+            <div class="date">有效期至:{{ myVip.expiredAt }}</div>
           </div>
-          <div class="text3">
-            金币余额:{{ account.credit ? account.credit : 0 }}
-          </div> -->
-        </div>
-        <div class="text-bot">
-          @if (myVip) {
-          <div class="date">有效期至:{{ myVip.expiredAt }}</div>
-          }
+          <div class="text-span">开通记录</div>
         </div>
+        } @else{
+        <div class="text-top">未开通</div>
+        }
       </div>
     </div>
     @for (item of goodsList; track $index) {
@@ -107,7 +97,7 @@
         </div> -->
       </div>
       <div class="price-btn" (click)="openpay()">
-        <div class="open-pay">确认支付</div>
+        <div class="open-pay">立即购买</div>
       </div>
     </div>
   </div>

+ 74 - 31
projects/live-app/src/services/account.service.ts

@@ -180,7 +180,8 @@ export class AccountService {
       now.getHours() +
       now.getMinutes() +
       now.getSeconds() +
-      now.getMilliseconds()+Math.floor(Math.random() * 10000)
+      now.getMilliseconds() +
+      Math.floor(Math.random() * 10000);
     return tradeNo;
   }
 
@@ -191,7 +192,7 @@ export class AccountService {
     price: number;
     total_fee: number;
     tradeNo: string;
-    out_trade_no:string;
+    out_trade_no: string;
     payType: string;
     code?: string;
   }): Promise<any> {
@@ -203,7 +204,7 @@ export class AccountService {
           uid: Parse.User.current()?.id,
           type: params.type,
           gid: params.gid,
-          invite:Parse.User.current()?.get('invite')?.id,
+          invite: Parse.User.current()?.get('invite')?.id,
           params: params,
         })
         .subscribe(
@@ -217,7 +218,50 @@ export class AccountService {
         );
     });
   }
-  // 生成一条 AccountLog 记录
+  //充值记录
+  async updataOrder(param: {
+    tradeNo: string;
+    payType: string;
+    price: number;
+  }) {
+    const user = Parse.User.current()!;
+    //查询账户
+    let Account = new Parse.Query('Account');
+    Account.equalTo('company', this.company);
+    Account.equalTo('user', user?.id);
+    Account.select('objectId');
+    let account = await Account.first();
+    if (!account?.id) {
+      account = await this.createdAccount(user.id);
+    }
+    let parseAccountLog = Parse.Object.extend('AccountLog');
+    let accountLog = new parseAccountLog();
+    accountLog.set('isVerified', false);
+    accountLog.set('user', {
+      __type: 'Pointer',
+      className: '_User',
+      objectId: user.id,
+    });
+    accountLog.set('company', {
+      __type: 'Pointer',
+      className: 'Company',
+      objectId: this.company,
+    });
+    accountLog.set('targetAccount', {
+      __type: 'Pointer',
+      className: 'Account',
+      objectId: account?.id,
+    });
+    accountLog.set('fromName', 'system');
+    accountLog.set('fromAccountName', 'system');
+    accountLog.set('orderNumber', param.tradeNo);
+    accountLog.set('desc', `${param.payType}充值${param.price}`);
+    accountLog.set('assetType', 'balance');
+    accountLog.set('orderType', `${param.payType}recharge`);
+    accountLog.set('assetCount', param.price);
+    return await accountLog.save();
+  }
+  // 生成一条待支付AccountLog记录
   async saveAccountLog(param: {
     price: number;
     tradeNo: string;
@@ -301,33 +345,32 @@ export class AccountService {
     return account;
   }
 
-  async updateAccountLog(info: object, orderid:string) {
-    let url = "https://server.fmode.cn/api/apig/saveAccountLog";
-    return new Promise((res,rej)=>{
+  async updateAccountLog(info: object, orderid: string) {
+    let url = 'https://server.fmode.cn/api/apig/saveAccountLog';
+    return new Promise((res, rej) => {
       this.http
-      .post(url, {
-        company: this.company,
-        uid: Parse.User.current()?.id,
-        orderid: orderid,
-        info: info,
-      })
-      .subscribe(
-        (data: any) => {
-          console.log(data);
-          res (true)
-        },
-        async (err) => {
-          console.warn(err);
-          const toast = await this.toast.create({
-            message: '支付成功,订单记录异常',
-            color: 'warning',
-            duration: 1500,
-          });
-          toast.present();
-          rej()
-        }
-      );
-    })
-    
+        .post(url, {
+          company: this.company,
+          uid: Parse.User.current()?.id,
+          orderid: orderid,
+          info: info,
+        })
+        .subscribe(
+          (data: any) => {
+            console.log(data);
+            res(true);
+          },
+          async (err) => {
+            console.warn(err);
+            const toast = await this.toast.create({
+              message: '支付成功,订单记录异常',
+              color: 'warning',
+              duration: 1500,
+            });
+            toast.present();
+            rej();
+          }
+        );
+    });
   }
 }