|
|
@@ -55,17 +55,17 @@ interface responseData {
|
|
|
user_info: WechatUserInfo;
|
|
|
}
|
|
|
|
|
|
-interface GeneratedTypeLiteralInterface_1 {
|
|
|
+interface WechatUserInfoData {
|
|
|
token_info?: object;
|
|
|
user_info: WechatUserInfo;
|
|
|
- system_info?: object;
|
|
|
+ system_info?: SystemInfo;
|
|
|
subscription_info?: SubscriptionInfo;
|
|
|
}
|
|
|
|
|
|
interface WechatUserInfoApiResponse {
|
|
|
code: number;
|
|
|
msg: string;
|
|
|
- data: GeneratedTypeLiteralInterface_1;
|
|
|
+ data: WechatUserInfoData;
|
|
|
}
|
|
|
|
|
|
interface HuaweiUserInfo {
|
|
|
@@ -75,14 +75,14 @@ interface HuaweiUserInfo {
|
|
|
headimgurl: string;
|
|
|
}
|
|
|
|
|
|
-interface HuaweiSystemInfo {
|
|
|
- user_id: number;
|
|
|
+interface SystemInfo {
|
|
|
+ user_id: number | string;
|
|
|
token: string;
|
|
|
}
|
|
|
|
|
|
interface HuaweiUserInfoApiData {
|
|
|
user_info: HuaweiUserInfo;
|
|
|
- system_info?: HuaweiSystemInfo;
|
|
|
+ system_info?: SystemInfo;
|
|
|
subscription_info?: SubscriptionInfo;
|
|
|
}
|
|
|
|
|
|
@@ -126,6 +126,18 @@ interface WeChatPrepayId {
|
|
|
prepay_id: string;
|
|
|
}
|
|
|
|
|
|
+// user/info 接口的返回结构
|
|
|
+interface UserInfoApiData {
|
|
|
+ user_info: WechatUserInfo; // 可以复用 WechatUserInfo
|
|
|
+ system_info: SystemInfo;
|
|
|
+ subscription_info: SubscriptionInfo;
|
|
|
+}
|
|
|
+
|
|
|
+interface UserInfoApiResponse {
|
|
|
+ code: number;
|
|
|
+ msg: string;
|
|
|
+ data: UserInfoApiData;
|
|
|
+}
|
|
|
|
|
|
// 自定义主题颜色
|
|
|
|
|
|
@@ -152,12 +164,14 @@ async function isHasWX(): Promise<boolean> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-async function createWeChatOrder(app_id: string, mch_id: string, description: string, amount: number, out_trade_no_pre: string): Promise<string> {
|
|
|
+async function createWeChatOrder(app_id: string, mch_id: string, description: string, amount: number, out_trade_no_pre: string, uid: number, plan_id: string): Promise<string> {
|
|
|
let requestUrl = CommonConstants.WX_PAY_API
|
|
|
+ '?app_id=' + encodeURIComponent(app_id.trim())
|
|
|
+ '&mch_id=' + encodeURIComponent(mch_id.trim())
|
|
|
+ '&description=' + encodeURIComponent(description.trim())
|
|
|
+ '&amount=' + encodeURIComponent(amount)
|
|
|
+ + '&uid=' + encodeURIComponent(uid)
|
|
|
+ + '&plan_id=' + encodeURIComponent(plan_id)
|
|
|
+ '&out_trade_no_pre=' + encodeURIComponent(out_trade_no_pre);
|
|
|
const httpRequest: http.HttpRequest = http.createHttp();
|
|
|
const options: http.HttpRequestOptions = {
|
|
|
@@ -213,6 +227,7 @@ async function rsaSign2048(message: string): Promise<Uint8Array> {
|
|
|
@Entry
|
|
|
export struct UserCenter {
|
|
|
@State userName: string = '未登录用户';
|
|
|
+ @State userId: number = 0;
|
|
|
@State userAvatar: Resource = $r('app.media.icon_person2');
|
|
|
@State userAvatarUrl: string = '';
|
|
|
@State isVip: boolean = false;
|
|
|
@@ -221,6 +236,7 @@ export struct UserCenter {
|
|
|
@State hasActiveSubscription: boolean = false;
|
|
|
@State subscriptionName: string = '';
|
|
|
@State subscriptionEndDate: string = '';
|
|
|
+ @State userToken: string = '';
|
|
|
private wxApi = WXApi
|
|
|
private wxEventHandler = WXEventHandler
|
|
|
@StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD;
|
|
|
@@ -241,15 +257,33 @@ export struct UserCenter {
|
|
|
|
|
|
// 微信回调处理
|
|
|
private onWXResp: OnWXResp = (resp): void => {
|
|
|
- let authResultText = JSON.stringify(resp ?? {}, null, 2)
|
|
|
if (resp.errCode === ErrCode.ERR_OK) {
|
|
|
- // 提取code并请求用户信息
|
|
|
+ // 判断回调类型
|
|
|
+ if (resp.type === wxopensdk.Command.kCommandSendAuth) {
|
|
|
+ // 微信登录成功回调
|
|
|
+ const authResp = resp as wxopensdk.SendAuthResp; // 转换为授权响应类型,以便访问code
|
|
|
this.getUserInfoByCode(resp?.['code'])
|
|
|
- ToastUtil.showToast('登录成功!')
|
|
|
+ ToastUtil.showToast('登录成功!');
|
|
|
+ } else if (resp.type === wxopensdk.Command.kCommandPay) {
|
|
|
+ // 微信支付成功回调
|
|
|
+ ToastUtil.showToast('支付成功!');
|
|
|
+ // 可在此处刷新会员状态或其他支付成功后的业务逻辑
|
|
|
+ this.fetchVipPlans(); // 刷新会员套餐信息
|
|
|
+ } else {
|
|
|
+ // 其他类型的成功回调
|
|
|
+ ToastUtil.showToast('操作成功!');
|
|
|
+ }
|
|
|
} else {
|
|
|
- ToastUtil.showToast('微信登录失败!')
|
|
|
+ // 处理错误情况
|
|
|
+ if (resp.type === wxopensdk.Command.kCommandSendAuth) {
|
|
|
+ ToastUtil.showToast('微信登录失败!');
|
|
|
+ } else if (resp.type === wxopensdk.Command.kCommandPay) {
|
|
|
+ ToastUtil.showToast('支付失败!');
|
|
|
+ } else {
|
|
|
+ ToastUtil.showToast('操作失败!');
|
|
|
+ }
|
|
|
}
|
|
|
- console.log('微信回调结果:' + authResultText)
|
|
|
+ console.log('微信回调结果:' + JSON.stringify(resp ?? {}, null, 2));
|
|
|
}
|
|
|
|
|
|
// 通过code换取用户信息
|
|
|
@@ -270,6 +304,8 @@ export struct UserCenter {
|
|
|
if (json.code === 0 && json.data && json.data.user_info) {
|
|
|
let userInfo: WechatUserInfo = json.data.user_info;
|
|
|
this.isLogin = true;
|
|
|
+ this.userId = json.data.system_info?.user_id ? Number(json.data.system_info?.user_id) : 0;
|
|
|
+ hilog.info(0x0000, 'UserCenter', `getUserInfoByCode: this.userId set to ${this.userId}`);
|
|
|
this.userName = userInfo.nickname || '微信用户';
|
|
|
if (userInfo.headimgurl && userInfo.headimgurl.length > 0) {
|
|
|
this.userAvatarUrl = userInfo.headimgurl;
|
|
|
@@ -291,11 +327,13 @@ export struct UserCenter {
|
|
|
}
|
|
|
// 保存登录状态和用户信息
|
|
|
PreferencesUtil.putSync('isLogin', true);
|
|
|
+ PreferencesUtil.putSync('userId', this.userId);
|
|
|
PreferencesUtil.putSync('userName', this.userName);
|
|
|
PreferencesUtil.putSync('userAvatarUrl', this.userAvatarUrl);
|
|
|
PreferencesUtil.putSync('subscriptionName', this.subscriptionName);
|
|
|
PreferencesUtil.putSync('subscriptionEndDate', this.subscriptionEndDate);
|
|
|
PreferencesUtil.putSync('hasActiveSubscription', this.hasActiveSubscription);
|
|
|
+ PreferencesUtil.putSync('userToken', json.data.system_info?.token || '');
|
|
|
ToastUtil.showToast('微信登录成功');
|
|
|
} else {
|
|
|
ToastUtil.showToast('用户信息解析失败');
|
|
|
@@ -326,6 +364,8 @@ export struct UserCenter {
|
|
|
if (json.code === 0 && json.data && json.data.user_info) {
|
|
|
// 登录成功处理
|
|
|
this.isLogin = true;
|
|
|
+ this.userId = json.data.system_info?.user_id ? Number(json.data.system_info?.user_id) : 0;
|
|
|
+ hilog.info(0x0000, 'UserCenter', `getUserInfoByHuawei: this.userId set to ${this.userId}`);
|
|
|
this.userName = json.data.user_info.nickname || '华为用户';
|
|
|
this.userAvatarUrl = json.data.user_info.headimgurl || '';
|
|
|
// 处理会员信息
|
|
|
@@ -341,11 +381,13 @@ export struct UserCenter {
|
|
|
}
|
|
|
// 保存登录状态
|
|
|
PreferencesUtil.putSync('isLogin', true);
|
|
|
+ PreferencesUtil.putSync('userId', this.userId);
|
|
|
PreferencesUtil.putSync('userName', this.userName);
|
|
|
PreferencesUtil.putSync('userAvatarUrl', this.userAvatarUrl);
|
|
|
PreferencesUtil.putSync('subscriptionName', this.subscriptionName);
|
|
|
PreferencesUtil.putSync('subscriptionEndDate', this.subscriptionEndDate);
|
|
|
PreferencesUtil.putSync('hasActiveSubscription', this.hasActiveSubscription);
|
|
|
+ PreferencesUtil.putSync('userToken', json.data.system_info?.token || '');
|
|
|
ToastUtil.showToast('华为登录成功');
|
|
|
} else {
|
|
|
ToastUtil.showToast('用户信息解析失败');
|
|
|
@@ -364,19 +406,18 @@ export struct UserCenter {
|
|
|
this.themeColor = themeColor;
|
|
|
// 自动恢复本地登录状态
|
|
|
this.isLogin = PreferencesUtil.getBooleanSync('isLogin', false);
|
|
|
+ this.userId = PreferencesUtil.getNumberSync('userId', 0);
|
|
|
this.userName = PreferencesUtil.getStringSync('userName', '未登录用户');
|
|
|
this.userAvatarUrl = PreferencesUtil.getStringSync('userAvatarUrl', '');
|
|
|
this.subscriptionName = PreferencesUtil.getStringSync('subscriptionName', '');
|
|
|
this.subscriptionEndDate = PreferencesUtil.getStringSync('subscriptionEndDate', '');
|
|
|
this.hasActiveSubscription = PreferencesUtil.getBooleanSync('hasActiveSubscription', false);
|
|
|
+ this.userToken = PreferencesUtil.getStringSync('userToken', '');
|
|
|
this.wxEventHandler.registerOnWXRespCallback(this.onWXResp)
|
|
|
this.fetchVipPlans();
|
|
|
- // 这里可以加载用户信息
|
|
|
- // this.isLogin = ...
|
|
|
- // this.userName = ...
|
|
|
- // this.userAvatar = ...
|
|
|
- // this.isVip = ...
|
|
|
- // this.vipExpire = ...
|
|
|
+ if (this.isLogin && this.userToken) {
|
|
|
+ void this.fetchUserInfo(this.userToken);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
aboutToDisappear() {
|
|
|
@@ -854,8 +895,9 @@ export struct UserCenter {
|
|
|
return;
|
|
|
}
|
|
|
const appName = PreferencesUtil.getStringSync('appName', 'TTMusic');
|
|
|
+ hilog.info(0x0000, 'UserCenter', `doWxPay: current this.userId is ${this.userId}`);
|
|
|
const prepayId = await createWeChatOrder(CommonConstants.WX_PAY_APPID, CommonConstants.WX_PAY_MCHID,
|
|
|
- appName, Number(plan.price) * 100, CommonConstants.OUT_TRADE_NO_PRE);
|
|
|
+ appName, Number(plan.price) * 100, CommonConstants.OUT_TRADE_NO_PRE, this.userId, plan.id);
|
|
|
if (prepayId) {
|
|
|
await this.wechatPay(prepayId);
|
|
|
} else {
|
|
|
@@ -897,4 +939,52 @@ export struct UserCenter {
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+ // 每次进入页面时刷新用户数据
|
|
|
+ async fetchUserInfo(token: string) {
|
|
|
+ try {
|
|
|
+ const url = `https://pay.ss5.xyz/user/info?token=${encodeURIComponent(token)}`;
|
|
|
+ const httpRequest = http.createHttp();
|
|
|
+ const options: http.HttpRequestOptions = {
|
|
|
+ method: http.RequestMethod.GET,
|
|
|
+ readTimeout: 3000,
|
|
|
+ connectTimeout: 3000,
|
|
|
+ };
|
|
|
+ const response: http.HttpResponse = await httpRequest.request(url, options);
|
|
|
+ if (response.responseCode === 200) {
|
|
|
+ let res = response.result as string;
|
|
|
+ LogUtil.debug("fetchUserInfo res =" + res);
|
|
|
+ let json: UserInfoApiResponse = JSON.parse(res) as UserInfoApiResponse;
|
|
|
+
|
|
|
+ if (json.code === 0 && json.data) {
|
|
|
+ const userInfo = json.data.user_info;
|
|
|
+ const systemInfo = json.data.system_info;
|
|
|
+ const subInfo = json.data.subscription_info;
|
|
|
+
|
|
|
+ this.isLogin = true;
|
|
|
+ this.userId = systemInfo.user_id ? Number(systemInfo.user_id) : 0;
|
|
|
+ this.userName = userInfo.nickname || '用户';
|
|
|
+ this.userAvatarUrl = userInfo.headimgurl || '';
|
|
|
+
|
|
|
+ if (subInfo && subInfo.has_active_subscription && subInfo.subscriptions && subInfo.subscriptions.length > 0) {
|
|
|
+ this.hasActiveSubscription = true;
|
|
|
+ this.subscriptionName = subInfo.subscriptions[0].plan_name;
|
|
|
+ this.subscriptionEndDate = subInfo.subscriptions[0].end_date;
|
|
|
+ } else {
|
|
|
+ this.hasActiveSubscription = false;
|
|
|
+ this.subscriptionName = '';
|
|
|
+ this.subscriptionEndDate = '';
|
|
|
+ }
|
|
|
+ ToastUtil.showToast('用户信息已更新');
|
|
|
+ } else {
|
|
|
+ ToastUtil.showToast('刷新用户信息失败');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ToastUtil.showToast('获取用户信息失败');
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ ToastUtil.showToast('获取用户信息异常' + (e && e.message ? (': ' + e.message) : ''));
|
|
|
+ hilog.error(0x0000, 'UserCenter', `fetchUserInfo error: ${e.message}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|