From 6c691c7653e28a09793054055c4f3eeef39ccea0 Mon Sep 17 00:00:00 2001 From: icssoa <615206459@qq.com> Date: Tue, 26 Aug 2025 18:46:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20useWx=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E7=99=BB=E5=BD=95=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/index.ts | 9 ++ cool/hooks/index.ts | 7 +- cool/hooks/wx.ts | 239 ++++++++++++++++++++++++++++ pages/user/components/login/wx.uvue | 56 ++++--- pages/user/login.uvue | 6 +- 5 files changed, 292 insertions(+), 25 deletions(-) create mode 100644 cool/hooks/wx.ts diff --git a/config/index.ts b/config/index.ts index 446e98a..e41d112 100644 --- a/config/index.ts +++ b/config/index.ts @@ -8,6 +8,11 @@ export const isDev = process.env.NODE_ENV == "development"; // 忽略 token 校验的接口路径 export const ignoreTokens: string[] = []; +// 微信配置 +type WxConfig = { + debug: boolean; +}; + // 配置类型定义 type Config = { name: string; // 应用名称 @@ -19,6 +24,7 @@ type Config = { showDarkButton: boolean; // 是否显示暗色模式切换按钮 isCustomTabBar: boolean; // 是否自定义 tabBar backTop: boolean; // 是否显示回到顶部按钮 + wx: WxConfig; // 微信配置 }; // 根据环境导出最终配置 @@ -30,6 +36,9 @@ export const config = { showDarkButton: isMp() ? false : true, isCustomTabBar: true, backTop: true, + wx: { + debug: false + }, ...(isDev ? dev() : prod()) } as Config; diff --git a/cool/hooks/index.ts b/cool/hooks/index.ts index 4f80866..2305990 100644 --- a/cool/hooks/index.ts +++ b/cool/hooks/index.ts @@ -1,5 +1,6 @@ -export * from "./refs"; -export * from "./pager"; -export * from "./long-press"; export * from "./cache"; +export * from "./long-press"; +export * from "./pager"; export * from "./parent"; +export * from "./refs"; +export * from "./wx"; diff --git a/cool/hooks/wx.ts b/cool/hooks/wx.ts new file mode 100644 index 0000000..e58ea40 --- /dev/null +++ b/cool/hooks/wx.ts @@ -0,0 +1,239 @@ +import { ref } from "vue"; +import { assign, getUrlParam, storage } from "../utils"; +import { service } from "../service"; +import { t } from "@/locale"; +import { config } from "@/config"; + +// #ifdef H5 +import wx from "weixin-js-sdk"; +// #endif + +// 微信配置类型 +type WxConfig = { + appId: string; +}; + +// 微信相关功能封装类 +export class Wx { + // 微信登录code + code = ref(""); + + /** + * 获取微信登录code + */ + async getCode(): Promise { + return new Promise((resolve) => { + // #ifdef MP-WEIXIN + uni.login({ + provider: "weixin", + success: (res) => { + this.code.value = res.code; + resolve(res.code); + } + }); + // #endif + + // #ifndef MP-WEIXIN + resolve(""); + // #endif + }); + } + + // #ifdef H5 + // 公众号配置 + mpConfig: WxConfig = { + appId: "" + }; + + /** + * 判断当前是否为微信浏览器 + */ + isWxBrowser() { + const ua: string = window.navigator.userAgent.toLowerCase(); + if (ua.match(/MicroMessenger/i) != null) { + return true; + } else { + return false; + } + } + + /** + * 获取公众号配置信息,并初始化微信JS-SDK + */ + getMpConfig() { + if (this.isWxBrowser()) { + service.user.comm + .wxMpConfig({ + url: `${location.origin}${location.pathname}` + }) + .then((res) => { + wx.config({ + debug: config.wx.debug, + jsApiList: ["chooseWXPay"], + ...res + }); + + // 合并配置到mpConfig + assign(this.mpConfig, res); + }); + } + } + + /** + * 跳转到微信授权页面 + */ + mpAuth() { + const { appId } = this.mpConfig; + + const redirect_uri = encodeURIComponent( + `${location.origin}${location.pathname}#/pages/user/login` + ); + const response_type = "code"; + const scope = "snsapi_userinfo"; + const state = "STATE"; + + const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}#wechat_redirect`; + + location.href = url; + } + + /** + * 公众号登录,获取code + */ + mpLogin() { + return new Promise((resolve) => { + const code = getUrlParam("code"); + const mpCode = storage.get("mpCode"); + + // 去除url中的code参数,避免重复 + const url = window.location.href.replace(/(\?[^#]*)#/, "#"); + window.history.replaceState({}, "", url); + + if (code != mpCode) { + storage.set("mpCode", code, 1000 * 60 * 5); + resolve(code); + } else { + resolve(null); + } + }); + } + + /** + * 公众号微信支付 + * @param params 支付参数 + */ + mpPay(params: wx.IchooseWXPay & { timeStamp: number }): Promise { + return new Promise((resolve, reject) => { + if (!this.isWxBrowser()) { + return reject({ message: t("请在微信浏览器中打开") }); + } + + wx.chooseWXPay({ + ...params, + timestamp: params.timeStamp, + success() { + resolve(); + }, + complete(e: { errMsg: string }) { + switch (e.errMsg) { + case "chooseWXPay:cancel": + reject({ message: t("已取消支付") }); + break; + + default: + reject({ message: t("支付失败") }); + } + } + }); + }); + } + // #endif + + // #ifdef MP + /** + * 小程序登录,获取用户信息和code + */ + miniLogin(): Promise<{ + code: string; + iv: string; + encryptedData: string; + signature: string; + rawData: string; + }> { + return new Promise((resolve, reject) => { + // 兼容 Mac,Mac 端需用 getUserInfo + const k = uni.getDeviceInfo().platform === "mac" ? "getUserInfo" : "getUserProfile"; + + uni[k]({ + lang: "zh_CN", + desc: t("授权信息仅用于用户登录"), + success: ({ iv, encryptedData, signature, rawData }) => { + const next = () => { + resolve({ + iv, + encryptedData, + signature, + rawData, + code: this.code.value + }); + }; + + // 检查登录状态是否过期 + uni.checkSession({ + success: () => { + next(); + }, + fail: () => { + this.getCode().then(() => { + next(); + }); + } + }); + }, + fail: (err) => { + console.error(`[useWx.miniLogin] error`, err); + this.getCode(); + + reject(t("登录授权失败")); + } + }); + }); + } + + /** + * 小程序微信支付 + * @param params 支付参数 + */ + miniPay(params: any): Promise { + return new Promise((resolve, reject) => { + uni.requestPayment({ + provider: "wxpay", + ...params, + success() { + resolve(); + }, + fail() { + reject(t("已取消支付")); + } + }); + }); + } + // #endif +} + +/** + * useWx 钩子函数,后续可扩展 + */ +export const useWx = (): Wx => { + const wx = new Wx(); + + onReady(() => { + wx.getCode(); + + // #ifdef H5 + wx.getMpConfig(); + // #endif + }); + + return wx; +}; diff --git a/pages/user/components/login/wx.uvue b/pages/user/components/login/wx.uvue index f3053ee..0cf9e3a 100644 --- a/pages/user/components/login/wx.uvue +++ b/pages/user/components/login/wx.uvue @@ -74,7 +74,7 @@