| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- import { cryptoFramework } from "@kit.CryptoArchitectureKit";
- import { LogUtil, PreferencesUtil, StrUtil, ToastUtil } from "@pura/harmony-utils";
- import { CommonConstants } from "../constants/CommonConstants";
- import { http } from "@kit.NetworkKit";
- import { bundleManager } from "@kit.AbilityKit";
- import { BusinessError } from '@kit.BasicServicesKit';
- import { hilog } from "@kit.PerformanceAnalysisKit";
- // 用户相关接口定义
- export interface WechatUserInfo {
- openid?: string;
- nickname?: string;
- sex?: number;
- language?: string;
- city?: string;
- province?: string;
- country?: string;
- headimgurl?: string;
- privilege?: string[];
- unionid?: string;
- }
- export interface Subscription {
- plan_id: string;
- plan_name: string;
- plan_description: string;
- price: string;
- start_date: string;
- end_date: string;
- status: string;
- auto_renew: string;
- features: string[];
- }
- export interface SubscriptionInfo {
- has_active_subscription: boolean;
- subscriptions: Subscription[];
- }
- export interface responseData {
- token_info?: object;
- user_info: WechatUserInfo;
- }
- export interface WechatUserInfoData {
- token_info?: object;
- user_info: WechatUserInfo;
- system_info?: SystemInfo;
- subscription_info?: SubscriptionInfo;
- }
- export interface WechatUserInfoApiResponse {
- code: number;
- msg: string;
- data: WechatUserInfoData;
- }
- export interface HuaweiUserInfo {
- openid: string;
- unionid?: string;
- nickname: string;
- headimgurl: string;
- }
- export interface SystemInfo {
- user_id: number | string;
- token: string;
- }
- export interface HuaweiUserInfoApiData {
- user_info: HuaweiUserInfo;
- system_info?: SystemInfo;
- subscription_info?: SubscriptionInfo;
- }
- export interface HuaweiUserInfoApiResponse {
- code: number;
- msg: string;
- data: HuaweiUserInfoApiData;
- }
- export interface VipFeature {
- icon: Resource;
- title: string;
- description: string;
- isVipOnly: boolean;
- }
- export interface VipPlanApi {
- id: string;
- name: string;
- description: string;
- price: string;
- duration: string;
- features: string;
- sort_order: string;
- status: string;
- created_at: string;
- updated_at: string;
- }
- export interface VipPlanListApiData {
- plans: VipPlanApi[];
- }
- export interface VipPlanListApiResponse {
- code: number;
- msg: string;
- data: VipPlanListApiData;
- }
- export interface WeChatPrepayId {
- prepay_id: string;
- }
- export interface UserInfoApiData {
- user_info: WechatUserInfo;
- system_info: SystemInfo;
- subscription_info: SubscriptionInfo;
- }
- export interface UserInfoApiResponse {
- code: number;
- msg: string;
- data: UserInfoApiData;
- }
- export default class UserUtil {
- // 微信是否安装
- static async isHasWX(): Promise<boolean> {
- try {
- let link = 'weixin://';
- let data = bundleManager.canOpenLink(link);
- if (data) {
- return true;
- } else {
- ToastUtil.showToast('微信未安装');
- return false;
- }
- } catch (err) {
- let message = (err as BusinessError).message;
- console.error('canOpenLink failed: %{public}s', message);
- return false;
- }
- }
- // 创建微信订单
- static async 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 = {
- method: http.RequestMethod.GET,
- readTimeout: 6000,
- connectTimeout: 6000,
- };
- try {
- const response: http.HttpResponse = await httpRequest.request(requestUrl, options);
- if (response.responseCode === 200) {
- let responseData: WeChatPrepayId;
- if (typeof response.result === 'string') {
- responseData = JSON.parse(response.result) as WeChatPrepayId;
- } else if (response.result instanceof Object) {
- responseData = response.result as WeChatPrepayId;
- } else {
- throw new Error('Unexpected response format');
- }
- const prepayId: string = responseData.prepay_id;
- return prepayId;
- } else {
- ToastUtil.showToast('微信下单失败');
- return '';
- }
- } catch (error) {
- ToastUtil.showToast('微信下单异常');
- return '';
- }
- }
- // 构造签名串
- static constructSignatureString(appId: string, timestamp: string, nonceStr: string, prepayId: string): string {
- return `${appId}\n${timestamp}\n${nonceStr}\n${prepayId}\n`;
- }
- // 微信支付签名
- static async rsaSign2048( message: string): Promise<Uint8Array> {
- try {
- let keyGen = cryptoFramework.createAsyKeyGenerator("RSA2048")
- let key = keyGen.convertPemKeySync(null, CommonConstants.WX_PAY_RSA_PRIVATE_KEY)
- let sign = cryptoFramework.createSign('RSA2048|PKCS1|SHA256');
- let msgBlob: cryptoFramework.DataBlob = {data: StrUtil.strToUint8Array(message)}
- sign.initSync(key.priKey)
- let signature = await sign.sign(msgBlob)
- return signature.data
- } catch (error) {
- console.error(error, `onecold error code: ${error.code}`)
- return new Uint8Array()
- }
- }
- // 通过code换取用户信息
- static async getUserInfoByCode(code: string): Promise<UserInfoApiData |WechatUserInfoData| null> {
- try {
- const url = `https://pay.ss5.xyz/wechat/user_info?code=${encodeURIComponent(code)}`;
- 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("getUserInfoByCode res =" + res)
- let json: WechatUserInfoApiResponse = JSON.parse(res) as WechatUserInfoApiResponse;
- if (json.code === 0 && json.data && json.data.user_info) {
- const userId = json.data.system_info?.user_id ? Number(json.data.system_info?.user_id) : 0;
- hilog.info(0x0000, 'UserUtil', `getUserInfoByCode: userId set to ${userId}`);
- const userName = json.data.user_info.nickname || '微信用户';
- const userAvatarUrl = json.data.user_info.headimgurl && json.data.user_info.headimgurl.length > 0 ? json.data.user_info.headimgurl : '';
- // 解析订阅信息
- const subInfo = json.data.subscription_info;
- let hasActiveSubscription = false;
- let subscriptionName = '';
- let subscriptionEndDate = '';
- if (subInfo && subInfo.has_active_subscription && subInfo.subscriptions && subInfo.subscriptions.length > 0) {
- hasActiveSubscription = true;
- subscriptionName = subInfo.subscriptions[0].plan_name;
- subscriptionEndDate = subInfo.subscriptions[0].end_date;
- }
- // 保存登录状态和用户信息
- PreferencesUtil.putSync('isLogin', true);
- PreferencesUtil.putSync('userId', userId);
- PreferencesUtil.putSync('userName', userName);
- PreferencesUtil.putSync('userAvatarUrl', userAvatarUrl);
- PreferencesUtil.putSync('subscriptionName', subscriptionName);
- PreferencesUtil.putSync('subscriptionEndDate', subscriptionEndDate);
- PreferencesUtil.putSync('hasActiveSubscription', hasActiveSubscription);
- PreferencesUtil.putSync('userToken', json.data.system_info?.token || '');
- ToastUtil.showToast('微信登录成功');
- return json.data;
- } else {
- ToastUtil.showToast('用户信息解析失败');
- return null;
- }
- } else {
- ToastUtil.showToast('获取用户信息失败');
- return null;
- }
- } catch (e) {
- ToastUtil.showToast('登录失败' + (e && e.message ? (': ' + e.message) : ''));
- return null;
- }
- }
- // 通过华为账号信息换取用户信息和会员状态
- static async getUserInfoByHuawei(openID: string, unionID: string, nickname: string, avatarUri: string): Promise<HuaweiUserInfoApiData | null> {
- try {
- const url = `https://pay.ss5.xyz/user/huawei?openID=${encodeURIComponent(openID)}&unionID=${encodeURIComponent(unionID)}&nickname=${encodeURIComponent(nickname)}&avatarUri=${encodeURIComponent(avatarUri)}`;
- 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("getUserInfoByHuawei res =" + res)
- let json: HuaweiUserInfoApiResponse = JSON.parse(res) as HuaweiUserInfoApiResponse;
- if (json.code === 0 && json.data && json.data.user_info) {
- const userId = json.data.system_info?.user_id ? Number(json.data.system_info?.user_id) : 0;
- hilog.info(0x0000, 'UserUtil', `getUserInfoByHuawei: userId set to ${userId}`);
- const userName = json.data.user_info.nickname || '华为用户';
- const userAvatarUrl = json.data.user_info.headimgurl || '';
- // 处理会员信息
- const subInfo = json.data.subscription_info;
- let hasActiveSubscription = false;
- let subscriptionName = '';
- let subscriptionEndDate = '';
- if (subInfo && subInfo.has_active_subscription && subInfo.subscriptions && subInfo.subscriptions.length > 0) {
- hasActiveSubscription = true;
- subscriptionName = subInfo.subscriptions[0].plan_name;
- subscriptionEndDate = subInfo.subscriptions[0].end_date;
- }
- // 保存登录状态
- PreferencesUtil.putSync('isLogin', true);
- PreferencesUtil.putSync('userId', userId);
- PreferencesUtil.putSync('userName', userName);
- PreferencesUtil.putSync('userAvatarUrl', userAvatarUrl);
- PreferencesUtil.putSync('subscriptionName', subscriptionName);
- PreferencesUtil.putSync('subscriptionEndDate', subscriptionEndDate);
- PreferencesUtil.putSync('hasActiveSubscription', hasActiveSubscription);
- PreferencesUtil.putSync('userToken', json.data.system_info?.token || '');
- ToastUtil.showToast('华为登录成功');
- return json.data;
- } else {
- ToastUtil.showToast('用户信息解析失败');
- return null;
- }
- } else {
- ToastUtil.showToast('获取用户信息失败');
- return null;
- }
- } catch (e) {
- ToastUtil.showToast('登录失败' + (e && e.message ? (': ' + e.message) : ''));
- return null;
- }
- }
- // 刷新用户信息
- static async fetchUserInfo(token: string): Promise<UserInfoApiData | null> {
- 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;
- let hasActiveSubscription = false;
- let subscriptionName = '';
- let subscriptionEndDate = '';
- if (subInfo && subInfo.has_active_subscription && subInfo.subscriptions && subInfo.subscriptions.length > 0) {
- hasActiveSubscription = true;
- subscriptionName = subInfo.subscriptions[0].plan_name;
- subscriptionEndDate = subInfo.subscriptions[0].end_date;
- }
- // ToastUtil.showToast('用户信息已更新');
- return json.data;
- } else {
- ToastUtil.showToast('刷新用户信息失败');
- return null;
- }
- } else {
- ToastUtil.showToast('获取用户信息失败');
- return null;
- }
- } catch (e) {
- ToastUtil.showToast('获取用户信息异常' + (e && e.message ? (': ' + e.message) : ''));
- hilog.error(0x0000, 'UserUtil', `fetchUserInfo error: ${e.message}`);
- return null;
- }
- }
- // 华为登录错误处理
- static dealHuaweiLoginError(error: BusinessError): void {
- if (error.code === 1001) {
- ToastUtil.showToast('未登录华为账号');
- } else if (error.code === 1002) {
- ToastUtil.showToast('网络异常');
- } else if (error.code === 1003) {
- ToastUtil.showToast('内部错误');
- } else if (error.code === 1004) {
- ToastUtil.showToast('用户取消授权');
- } else if (error.code === 1005) {
- ToastUtil.showToast('系统服务异常');
- } else if (error.code === 1006) {
- ToastUtil.showToast('请求被拒绝');
- } else if (error.code === 1007) {
- ToastUtil.showToast('无权限');
- } else {
- ToastUtil.showToast('登录失败');
- }
- }
- }
|