这版是公共号授权版
This commit is contained in:
+2
-11
@@ -15,7 +15,8 @@
|
|||||||
"pages/common/red/red",
|
"pages/common/red/red",
|
||||||
"pages/live/room/room",
|
"pages/live/room/room",
|
||||||
"pages/live/h5Room/index",
|
"pages/live/h5Room/index",
|
||||||
"pages/live/wxroom/index"
|
"pages/live/wxroom/index",
|
||||||
|
"pages/webview-auth/index"
|
||||||
],
|
],
|
||||||
"subPackages": [
|
"subPackages": [
|
||||||
{
|
{
|
||||||
@@ -52,16 +53,6 @@
|
|||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
},
|
},
|
||||||
"rendererOptions": {
|
|
||||||
"skyline": {
|
|
||||||
"defaultDisplayBlock": true,
|
|
||||||
"defaultContentBox": true,
|
|
||||||
"tagNameStyleIsolation": "legacy",
|
|
||||||
"disableABTest": true,
|
|
||||||
"sdkVersionBegin": "3.0.0",
|
|
||||||
"sdkVersionEnd": "15.255.255"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"componentFramework": "glass-easel",
|
"componentFramework": "glass-easel",
|
||||||
"sitemapLocation": "sitemap.json",
|
"sitemapLocation": "sitemap.json",
|
||||||
"lazyCodeLoading": "requiredComponents",
|
"lazyCodeLoading": "requiredComponents",
|
||||||
|
|||||||
+24
-13
@@ -1,31 +1,42 @@
|
|||||||
// app.ts
|
// app.ts
|
||||||
import { startSSE, stopSSE } from './utils/server-sent-events'
|
import { startSSE, stopSSE } from './utils/server-sent-events'
|
||||||
import { checkUpdate } from './utils/updateManager'
|
import { checkUpdate } from './utils/updateManager'
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const systemInfo = wx.getWindowInfo();
|
const systemInfo = wx.getWindowInfo();
|
||||||
|
|
||||||
|
// 登录相关 storage key 常量
|
||||||
|
const LOGIN_KEYS = ["mbuId", "userName", "openId", "unionId", "addressId", "defualtAddress"] as const;
|
||||||
|
|
||||||
export { };
|
export { };
|
||||||
|
|
||||||
App<IAppOption>({
|
App<IAppOption>({
|
||||||
globalData: {
|
globalData: {
|
||||||
isLogin: false, // 当前是否登录
|
isLogin: false,
|
||||||
wasLogin: false, // 之前是否登录过,用来判断是不是 登录状态失效
|
wasLogin: false,
|
||||||
safeBottom: systemInfo.safeArea.bottom - systemInfo.safeArea.height,
|
safeBottom: systemInfo.safeArea.bottom - systemInfo.safeArea.height,
|
||||||
safeTop: systemInfo.safeArea.top * 2,
|
safeTop: systemInfo.safeArea.top * 2,
|
||||||
store: {},
|
store: {},
|
||||||
joinedArray: [], //加入的频道,加入了就不会重复加入
|
joinedArray: [],
|
||||||
|
template: null,
|
||||||
|
showStock: false,
|
||||||
|
tabbarMap: {},
|
||||||
|
tabbarItems: [],
|
||||||
sseStore: {
|
sseStore: {
|
||||||
chat: [],
|
chat: [],
|
||||||
system: [],
|
system: [],
|
||||||
product: []
|
product: []
|
||||||
},
|
},
|
||||||
isModalShowing: false, //防止有多个登录弹窗打开
|
isModalShowing: false,
|
||||||
},
|
},
|
||||||
async onLaunch(props: any) {
|
async onLaunch(props: any) {
|
||||||
wx.removeStorageSync("state");
|
// 处理 state 参数
|
||||||
if (props.query.state) {
|
if (props.query.state) {
|
||||||
wx.setStorageSync("state", props.query.state)
|
wx.setStorageSync("state", props.query.state)
|
||||||
} else {
|
} else {
|
||||||
wx.removeStorageSync("state")
|
wx.removeStorageSync("state")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查小程序版本更新
|
// 检查小程序版本更新
|
||||||
checkUpdate();
|
checkUpdate();
|
||||||
|
|
||||||
@@ -43,13 +54,8 @@ App<IAppOption>({
|
|||||||
const ok = openId && unionId && userId;
|
const ok = openId && unionId && userId;
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// 清理
|
// 清理登录相关数据
|
||||||
wx.removeStorageSync("mbuId");
|
LOGIN_KEYS.forEach(key => wx.removeStorageSync(key));
|
||||||
wx.removeStorageSync("userName");
|
|
||||||
wx.removeStorageSync("openId");
|
|
||||||
wx.removeStorageSync("unionId");
|
|
||||||
wx.removeStorageSync("addressId");
|
|
||||||
wx.removeStorageSync("defualtAddress");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存上一次的登录状态,用来判断是否从 已登录 变成 未登录
|
// 保存上一次的登录状态,用来判断是否从 已登录 变成 未登录
|
||||||
@@ -65,9 +71,14 @@ App<IAppOption>({
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
getPageParams() {
|
||||||
|
return this.globalData.store;
|
||||||
|
},
|
||||||
|
async getTemplate() {
|
||||||
|
return this.globalData.template;
|
||||||
|
},
|
||||||
redirectLogin() {
|
redirectLogin() {
|
||||||
if (!this.checkLoginState()) {
|
if (!this.checkLoginState()) {
|
||||||
//已有modal在展示,就不展示了
|
|
||||||
if (this.globalData.isModalShowing) {
|
if (this.globalData.isModalShowing) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -3,8 +3,8 @@ const accountInfo = wx.getAccountInfoSync();
|
|||||||
const baseURLMap: Record<string, string> = {
|
const baseURLMap: Record<string, string> = {
|
||||||
develop: "https://rsc.test.rsjk.org.cn",
|
develop: "https://rsc.test.rsjk.org.cn",
|
||||||
trial: "https://rsc.test.rsjk.org.cn",
|
trial: "https://rsc.test.rsjk.org.cn",
|
||||||
release: "https://mp.qbxfu.cn"
|
// release: "https://mp.qbxfu.cn"
|
||||||
// release: "https://rsc.test.rsjk.org.cn"
|
release: "https://rsc.test.rsjk.org.cn"
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BASE_URL = baseURLMap[accountInfo.miniProgram.envVersion]
|
export const BASE_URL = baseURLMap[accountInfo.miniProgram.envVersion]
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { request } from "../../utils/request";
|
import { request } from "../../utils/request";
|
||||||
import { appId } from "../../env";
|
|
||||||
import { receiveRedPacket } from "../../utils/util";
|
import { receiveRedPacket } from "../../utils/util";
|
||||||
|
|
||||||
const app = getApp<IAppOption>();
|
const app = getApp<IAppOption>();
|
||||||
|
|
||||||
const formatDate = (isoString: string): string => {
|
const formatDate = (isoString: string): string => {
|
||||||
const date = new Date(isoString);
|
const date = new Date(isoString);
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
@@ -41,6 +41,13 @@ const isRetry = (state: number) => {
|
|||||||
return FAILED_STATES.includes(state);
|
return FAILED_STATES.includes(state);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 领取后延迟刷新的定时器 ID,用于在切 tab 或页面卸载时取消
|
||||||
|
let refreshTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
|
// 缓存登录信息,避免每次请求重复读取 storage
|
||||||
|
let cachedOpenId = wx.getStorageSync("openId");
|
||||||
|
let cachedAppId = wx.getStorageSync("appId");
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
list: [] as any[],
|
list: [] as any[],
|
||||||
@@ -60,7 +67,6 @@ Page({
|
|||||||
pendingAmount: '0.00',
|
pendingAmount: '0.00',
|
||||||
expiredAmount: '0.00',
|
expiredAmount: '0.00',
|
||||||
},
|
},
|
||||||
store: {},
|
|
||||||
safeBottom: app.globalData.safeBottom,
|
safeBottom: app.globalData.safeBottom,
|
||||||
safeTop: app.globalData.safeTop,
|
safeTop: app.globalData.safeTop,
|
||||||
},
|
},
|
||||||
@@ -71,6 +77,8 @@ Page({
|
|||||||
|
|
||||||
onReachBottom() {
|
onReachBottom() {
|
||||||
if (this.data.loading || !this.data.hasMore) return;
|
if (this.data.loading || !this.data.hasMore) return;
|
||||||
|
// 有延迟刷新待执行时,不触发滚动加载,避免重复请求
|
||||||
|
if (refreshTimer) return;
|
||||||
const nextPage = this.data.current + 1;
|
const nextPage = this.data.current + 1;
|
||||||
this.fetchRecords(nextPage, true, this.data.tabs[this.data.activeTab].type);
|
this.fetchRecords(nextPage, true, this.data.tabs[this.data.activeTab].type);
|
||||||
},
|
},
|
||||||
@@ -79,15 +87,31 @@ Page({
|
|||||||
const index = e.detail.index;
|
const index = e.detail.index;
|
||||||
const tab = this.data.tabs[index];
|
const tab = this.data.tabs[index];
|
||||||
this.setData({ activeTab: index });
|
this.setData({ activeTab: index });
|
||||||
|
// 切换 tab 时取消待执行的延迟刷新,避免用旧 tab 发无效请求
|
||||||
|
if (refreshTimer) {
|
||||||
|
clearTimeout(refreshTimer);
|
||||||
|
refreshTimer = null;
|
||||||
|
}
|
||||||
this.fetchRecords(1, false, tab.type);
|
this.fetchRecords(1, false, tab.type);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onUnload() {
|
||||||
|
// 页面卸载时取消待执行的延迟刷新
|
||||||
|
if (refreshTimer) {
|
||||||
|
clearTimeout(refreshTimer);
|
||||||
|
refreshTimer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async handleReceive(e: any) {
|
async handleReceive(e: any) {
|
||||||
const { id, outrewardsid } = e.currentTarget.dataset;
|
const { id, outrewardsid } = e.currentTarget.dataset;
|
||||||
|
|
||||||
|
// 防止重复点击
|
||||||
|
if (this.data.loading) return;
|
||||||
|
|
||||||
const params: Record<string, any> = {
|
const params: Record<string, any> = {
|
||||||
appId: appId,
|
appId: cachedAppId,
|
||||||
outRewardsId: outrewardsid,
|
openId: cachedOpenId,
|
||||||
openId: wx.getStorageSync("openId"),
|
|
||||||
};
|
};
|
||||||
if (outrewardsid) params.outRewardsId = outrewardsid;
|
if (outrewardsid) params.outRewardsId = outrewardsid;
|
||||||
if (id) params.redId = id;
|
if (id) params.redId = id;
|
||||||
@@ -96,11 +120,11 @@ Page({
|
|||||||
await receiveRedPacket(
|
await receiveRedPacket(
|
||||||
params,
|
params,
|
||||||
'/app/general/receive-red',
|
'/app/general/receive-red',
|
||||||
appId
|
cachedAppId
|
||||||
);
|
);
|
||||||
|
|
||||||
// 乐观更新:先立即更新本地数据,避免后端状态同步延迟导致展示不友好
|
// 乐观更新:先立即更新本地数据,避免后端状态同步延迟导致展示不友好
|
||||||
const { list, summary, activeTab, tabs } = this.data;
|
const { list, summary } = this.data;
|
||||||
const targetItem = list.find((item: any) => item.id === id);
|
const targetItem = list.find((item: any) => item.id === id);
|
||||||
|
|
||||||
if (targetItem) {
|
if (targetItem) {
|
||||||
@@ -122,22 +146,21 @@ Page({
|
|||||||
this.setData({ list: updatedList, summary: updatedSummary });
|
this.setData({ list: updatedList, summary: updatedSummary });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保后端有足够时间同步,直接刷新
|
// 确保后端有足够时间同步后刷新,使用实时 activeTab 避免闭包过期
|
||||||
setTimeout(() => {
|
this.setData({ loading: true });
|
||||||
this.fetchRecords(1, false, tabs[activeTab].type);
|
refreshTimer = setTimeout(() => {
|
||||||
|
refreshTimer = null;
|
||||||
|
this.setData({ loading: false });
|
||||||
|
this.fetchRecords(1, false, this.data.tabs[this.data.activeTab].type);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
this.setData({ loading: false });
|
||||||
console.error('领取红包失败:', err);
|
console.error('领取红包失败:', err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchRecords(page: number, append = false, type: number) {
|
async fetchRecords(page: number, append = false, type: number) {
|
||||||
const openId = wx.getStorageSync("openId");
|
if (!cachedOpenId) {
|
||||||
|
|
||||||
this.setData({
|
|
||||||
store: app.globalData.store,
|
|
||||||
});
|
|
||||||
if (!openId) {
|
|
||||||
wx.showToast({ title: "请先登录", icon: "none" });
|
wx.showToast({ title: "请先登录", icon: "none" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -149,20 +172,18 @@ Page({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params: Record<string, any> = {};
|
|
||||||
params.openId = openId;
|
|
||||||
params.appId = appId;
|
|
||||||
params.current = page;
|
|
||||||
params.pageSize = 15;
|
|
||||||
params.type = type;
|
|
||||||
|
|
||||||
const res = await request({
|
const res = await request({
|
||||||
options: {
|
options: {
|
||||||
url: "/app/saas/query-red",
|
url: "/app/saas/query-red",
|
||||||
data: params,
|
data: {
|
||||||
|
openId: cachedOpenId,
|
||||||
|
appId: cachedAppId,
|
||||||
|
current: page,
|
||||||
|
pageSize: this.data.pageSize,
|
||||||
|
type,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
isLoading: !append,
|
isLoading: !append,
|
||||||
// needLogin: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const records = res.data?.records || res.records || [];
|
const records = res.data?.records || res.records || [];
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// package-live/wxroom/index.ts
|
// package-live/wxroom/index.ts
|
||||||
import VolcMiniSdk, { EVENTS } from "../volc-mini-sdk/index";
|
import VolcMiniSdk, { EVENTS } from "../volc-mini-sdk/index";
|
||||||
import { request } from "../../utils/request";
|
import { request } from "../../utils/request";
|
||||||
import { appId } from "../../env";
|
|
||||||
import { aesDecrypt, aesEncrypt } from "../../utils/crypto";
|
import { aesDecrypt, aesEncrypt } from "../../utils/crypto";
|
||||||
import { AES_KEY, AES_IV } from "../../env";
|
import { AES_KEY, AES_IV } from "../../env";
|
||||||
import { receiveRedPacket, lockPromise } from "../../utils/util";
|
import { receiveRedPacket, lockPromise } from "../../utils/util";
|
||||||
@@ -206,6 +205,7 @@ Page({
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
handleReceive: lockPromise(async function (data: any) {
|
handleReceive: lockPromise(async function (data: any) {
|
||||||
|
const appId = wx.getStorageSync("appId");
|
||||||
const params = {
|
const params = {
|
||||||
appId: appId,
|
appId: appId,
|
||||||
outRewardsId: data.redPacketId,
|
outRewardsId: data.redPacketId,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { appId } from "../../../env";
|
|
||||||
import { request } from "../../../utils/request";
|
import { request } from "../../../utils/request";
|
||||||
import { receiveRedPacket } from "../../../utils/util";
|
import { receiveRedPacket } from "../../../utils/util";
|
||||||
|
|
||||||
@@ -76,7 +75,7 @@ Page({
|
|||||||
async handleReceive(e: any) {
|
async handleReceive(e: any) {
|
||||||
const { id } = e.currentTarget.dataset;
|
const { id } = e.currentTarget.dataset;
|
||||||
const { code } = app.globalData.store || {};
|
const { code } = app.globalData.store || {};
|
||||||
|
const appId = wx.getStorageSync("appId");
|
||||||
try {
|
try {
|
||||||
await receiveRedPacket(
|
await receiveRedPacket(
|
||||||
{ appId, code, openId: wx.getStorageSync("openId"), redId: id },
|
{ appId, code, openId: wx.getStorageSync("openId"), redId: id },
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { appId } from "../../../env";
|
|
||||||
import { request } from "../../../utils/request";
|
import { request } from "../../../utils/request";
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
@@ -118,7 +117,7 @@ Page({
|
|||||||
seeId: wx.getStorageSync("seeId") || '',
|
seeId: wx.getStorageSync("seeId") || '',
|
||||||
code: wx.getStorageSync("code") || '',
|
code: wx.getStorageSync("code") || '',
|
||||||
openId: wx.getStorageSync("openId") || '',
|
openId: wx.getStorageSync("openId") || '',
|
||||||
appId,
|
appId: wx.getStorageSync("appId") || '',
|
||||||
type: this.data.selectedReason,
|
type: this.data.selectedReason,
|
||||||
description: this.data.description,
|
description: this.data.description,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,6 +5,31 @@ page {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* loading 遮罩:未登录时显示,防止页面内容一闪 */
|
||||||
|
.fullscreen-loading {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #f9f9f9;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
.fullscreen-loading .loading-spinner {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border: 4rpx solid #e0e0e0;
|
||||||
|
border-top-color: #07c160;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: fullscreen-spin 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
@keyframes fullscreen-spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
.scrollarea {
|
.scrollarea {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { htmlToWxNodes } from "../../../utils/html-to-wx-nodes";
|
|||||||
import { request } from "../../../utils/request";
|
import { request } from "../../../utils/request";
|
||||||
import { version, appversion, appId } from "../../../env";
|
import { version, appversion, appId } from "../../../env";
|
||||||
import { receiveRedPacket } from "../../../utils/util";
|
import { receiveRedPacket } from "../../../utils/util";
|
||||||
|
const app = getApp<IAppOption>()
|
||||||
const isMobileEnvironment = (): boolean => {
|
const isMobileEnvironment = (): boolean => {
|
||||||
const platform = wx.getSystemInfoSync().platform?.toLowerCase() || '';
|
const platform = wx.getSystemInfoSync().platform?.toLowerCase() || '';
|
||||||
return platform !== 'windows' && platform !== 'mac';
|
return platform !== 'windows' && platform !== 'mac';
|
||||||
@@ -24,18 +24,34 @@ Page({
|
|||||||
active: 0,
|
active: 0,
|
||||||
canSubmit: false,
|
canSubmit: false,
|
||||||
safeBottom: 0,
|
safeBottom: 0,
|
||||||
|
initialLoading: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生命周期函数--监听页面加载
|
* 生命周期函数--监听页面加载
|
||||||
*/
|
*/
|
||||||
async onLoad(options: any) {
|
async onLoad(options: any) {
|
||||||
const app = getApp<IAppOption>();
|
const openId = wx.getStorageSync("openId");
|
||||||
|
if (!openId) {
|
||||||
|
// 未登录:保持 loading 遮罩,跳转 web-view 授权
|
||||||
|
const code = options.code || "";
|
||||||
|
const url = `/pages/webview-auth/index?back=video&code=${code}`
|
||||||
|
wx.navigateTo({ url });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已登录(含授权返回):隐藏 loading 遮罩,直接进入页面
|
||||||
|
this.setData({ initialLoading: true });
|
||||||
|
|
||||||
wx.hideShareMenu({
|
wx.hideShareMenu({
|
||||||
menus: ["shareAppMessage"], // 单独禁用好友分享
|
menus: ["shareAppMessage"], // 单独禁用好友分享
|
||||||
});
|
});
|
||||||
new UrlParamsHandler(options);
|
new UrlParamsHandler(options);
|
||||||
app.globalData.store = options;
|
// 合并 URL 参数与 globalData.store 中已有的登录信息(来自 webview-auth)
|
||||||
|
app.globalData.store = {
|
||||||
|
...app.globalData.store,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
let safeBottom = 0;
|
let safeBottom = 0;
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (wx.getWindowInfo) {
|
if (wx.getWindowInfo) {
|
||||||
@@ -52,7 +68,7 @@ Page({
|
|||||||
}
|
}
|
||||||
this.setData({
|
this.setData({
|
||||||
safeBottom: safeBottom,
|
safeBottom: safeBottom,
|
||||||
store: options,
|
store: app.globalData.store,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isMobileEnvironment()) {
|
if (!isMobileEnvironment()) {
|
||||||
@@ -95,6 +111,9 @@ Page({
|
|||||||
* 生命周期函数--监听页面显示
|
* 生命周期函数--监听页面显示
|
||||||
*/
|
*/
|
||||||
onShow() {
|
onShow() {
|
||||||
|
const openId = wx.getStorageSync("openId");
|
||||||
|
if (!openId) return;
|
||||||
|
this.setData({ initialLoading: true });
|
||||||
this.search();
|
this.search();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<!--pages/video/video.wxml-->
|
<!--pages/video/video.wxml-->
|
||||||
|
<view wx:if="{{!initialLoading}}" class="fullscreen-loading">
|
||||||
|
<view class="loading-spinner"></view>
|
||||||
|
</view>
|
||||||
|
<view wx:else>
|
||||||
<navigation-bar title="" back="{{false}}" bind:handleBack="handleBack" color="black" background="#FFF">
|
<navigation-bar title="" back="{{false}}" bind:handleBack="handleBack" color="black" background="#FFF">
|
||||||
<view slot="left" class="report-nav-btn" bind:tap="handleCustomReport">举报</view>
|
<view slot="left" class="report-nav-btn" bind:tap="handleCustomReport">举报</view>
|
||||||
</navigation-bar>
|
</navigation-bar>
|
||||||
@@ -37,3 +41,4 @@
|
|||||||
</view>
|
</view>
|
||||||
</van-tabs>
|
</van-tabs>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
|||||||
@@ -3,261 +3,13 @@ import { LoginRes } from "./login.d";
|
|||||||
import { wxLogin, wxRequest } from "../../utils/wx-api";
|
import { wxLogin, wxRequest } from "../../utils/wx-api";
|
||||||
|
|
||||||
const app = getApp<IAppOption>();
|
const app = getApp<IAppOption>();
|
||||||
const defaultAvatarUrl =
|
|
||||||
"https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0";
|
|
||||||
|
|
||||||
type LoginDisplayConfig = {
|
|
||||||
showLoginImage: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PartialLoginDisplayConfig = Partial<LoginDisplayConfig>;
|
|
||||||
|
|
||||||
const loginConfigKeys = [
|
|
||||||
"login",
|
|
||||||
"loginConfig",
|
|
||||||
"loginPage",
|
|
||||||
"auth",
|
|
||||||
"authConfig",
|
|
||||||
"authPage",
|
|
||||||
];
|
|
||||||
const WXROOM_REDIRECT_PATH_KEY = "wxroomRedirectPath";
|
const WXROOM_REDIRECT_PATH_KEY = "wxroomRedirectPath";
|
||||||
|
|
||||||
function isPlainObject(value: unknown): value is Record<string, any> {
|
|
||||||
return Object.prototype.toString.call(value) === "[object Object]";
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasOwnValue(source: Record<string, any>, keys: string[]) {
|
|
||||||
return keys.some((key) => source[key] !== undefined && source[key] !== null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeString(value: unknown) {
|
|
||||||
return typeof value === "string" ? value.trim() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeBoolean(value: unknown) {
|
|
||||||
if (typeof value === "boolean") return value;
|
|
||||||
if (typeof value === "number") return value > 0;
|
|
||||||
if (typeof value !== "string") return undefined;
|
|
||||||
|
|
||||||
const normalized = value.trim().toLowerCase();
|
|
||||||
if (["1", "true", "yes", "show", "visible", "enabled"].includes(normalized)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (["0", "false", "no", "hide", "hidden", "disabled"].includes(normalized)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeSwitchValue(value: unknown) {
|
|
||||||
const normalized = normalizeBoolean(value);
|
|
||||||
if (normalized !== undefined) return normalized;
|
|
||||||
if (typeof value === "string") return value.trim().length > 0;
|
|
||||||
if (Array.isArray(value)) return value.length > 0;
|
|
||||||
if (isPlainObject(value)) {
|
|
||||||
const innerToggle = getBooleanValue(value, ["show", "visible", "enabled", "value"]);
|
|
||||||
if (innerToggle !== undefined) return innerToggle;
|
|
||||||
return !!getStringValue(value, [
|
|
||||||
"url",
|
|
||||||
"src",
|
|
||||||
"image",
|
|
||||||
"imageUrl",
|
|
||||||
"background",
|
|
||||||
"backgroundImage",
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getObjectValue(source: Record<string, any>, keys: string[]) {
|
|
||||||
for (const key of keys) {
|
|
||||||
const value = source[key];
|
|
||||||
if (value !== undefined && value !== null && value !== "") {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStringValue(source: Record<string, any>, keys: string[]):string {
|
|
||||||
const value = getObjectValue(source, keys);
|
|
||||||
if (value === undefined) return "";
|
|
||||||
|
|
||||||
if (isPlainObject(value)) {
|
|
||||||
return getStringValue(value, [
|
|
||||||
"url",
|
|
||||||
"src",
|
|
||||||
"image",
|
|
||||||
"imageUrl",
|
|
||||||
"background",
|
|
||||||
"backgroundImage",
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return normalizeString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBooleanValue(source: Record<string, any>, keys: string[]) {
|
|
||||||
const value = getObjectValue(source, keys);
|
|
||||||
return normalizeBoolean(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function pushConfigCandidate(list: Record<string, any>[], value: unknown) {
|
|
||||||
if (isPlainObject(value)) {
|
|
||||||
list.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function collectLoginConfigCandidates(template: unknown) {
|
|
||||||
const candidates: Record<string, any>[] = [];
|
|
||||||
if (!isPlainObject(template)) return candidates;
|
|
||||||
|
|
||||||
if (
|
|
||||||
hasOwnValue(template, [
|
|
||||||
"showLoginImage",
|
|
||||||
"showLoginBackground",
|
|
||||||
"showBackgroundImage",
|
|
||||||
"showImage",
|
|
||||||
"imageSwitch",
|
|
||||||
"backgroundSwitch",
|
|
||||||
"loginImage",
|
|
||||||
"heroImage",
|
|
||||||
"loginBg",
|
|
||||||
"loginBackground",
|
|
||||||
"backgroundImage",
|
|
||||||
"backgroundUrl",
|
|
||||||
"background",
|
|
||||||
"image",
|
|
||||||
])
|
|
||||||
) {
|
|
||||||
candidates.push(template);
|
|
||||||
}
|
|
||||||
|
|
||||||
loginConfigKeys.forEach((key) => {
|
|
||||||
pushConfigCandidate(candidates, template[key]);
|
|
||||||
pushConfigCandidate(candidates, template.pageConfig?.[key]);
|
|
||||||
pushConfigCandidate(candidates, template.pages?.[key]);
|
|
||||||
pushConfigCandidate(candidates, template.property?.[key]);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Array.isArray(template.pages?.login)) {
|
|
||||||
template.pages.login.forEach((item: any) => {
|
|
||||||
pushConfigCandidate(candidates, item);
|
|
||||||
pushConfigCandidate(candidates, item?.props);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.entries(template).forEach(([key, value]) => {
|
|
||||||
if (!/login|auth/i.test(key)) return;
|
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
value.forEach((item) => {
|
|
||||||
if (!isPlainObject(item)) return;
|
|
||||||
pushConfigCandidate(candidates, item);
|
|
||||||
pushConfigCandidate(candidates, item.props);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pushConfigCandidate(candidates, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
return candidates;
|
|
||||||
}
|
|
||||||
|
|
||||||
function readLoginImageSwitch(source: Record<string, any>) {
|
|
||||||
const imageValue = getObjectValue(source, [
|
|
||||||
"showLoginImage",
|
|
||||||
"showLoginBackground",
|
|
||||||
"showBackgroundImage",
|
|
||||||
"showImage",
|
|
||||||
"imageSwitch",
|
|
||||||
"backgroundSwitch",
|
|
||||||
"loginImage",
|
|
||||||
"heroImage",
|
|
||||||
"loginBackground",
|
|
||||||
"loginBg",
|
|
||||||
"backgroundImage",
|
|
||||||
"backgroundUrl",
|
|
||||||
"background",
|
|
||||||
"image",
|
|
||||||
"imageUrl",
|
|
||||||
]);
|
|
||||||
|
|
||||||
return normalizeSwitchValue(imageValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveLoginDisplayConfigFromSource(source: unknown): PartialLoginDisplayConfig {
|
|
||||||
if (!isPlainObject(source)) return {};
|
|
||||||
|
|
||||||
const showLoginImage = readLoginImageSwitch(source);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...(showLoginImage !== undefined ? { showLoginImage } : {}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergeLoginDisplayConfig(
|
|
||||||
current: PartialLoginDisplayConfig,
|
|
||||||
next: PartialLoginDisplayConfig
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
...current,
|
|
||||||
...(next.showLoginImage !== undefined ? { showLoginImage: next.showLoginImage } : {}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
back: "",
|
back: "",
|
||||||
agree: false,
|
agree: false,
|
||||||
nickFocus: true,
|
|
||||||
showPopup: false,
|
|
||||||
safeBottom: app.globalData.safeBottom,
|
safeBottom: app.globalData.safeBottom,
|
||||||
showLoginImage: false,
|
|
||||||
userInfo: {
|
|
||||||
avatarUrl: defaultAvatarUrl,
|
|
||||||
nickName: "微信用户",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
applyLoginDisplayConfig(options: Record<string, any> = {}) {
|
|
||||||
const template = app.globalData.template as Record<string, any> | null;
|
|
||||||
const config = collectLoginConfigCandidates(template).reduce(
|
|
||||||
(result, item) =>
|
|
||||||
mergeLoginDisplayConfig(result, resolveLoginDisplayConfigFromSource(item)),
|
|
||||||
{} as PartialLoginDisplayConfig
|
|
||||||
);
|
|
||||||
const optionConfig = resolveLoginDisplayConfigFromSource(options);
|
|
||||||
const merged = mergeLoginDisplayConfig(config, optionConfig);
|
|
||||||
|
|
||||||
this.setData({
|
|
||||||
showLoginImage: merged.showLoginImage ?? false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
async onChooseAvatar(e: any) {
|
|
||||||
const { avatarUrl } = e.detail;
|
|
||||||
wx.uploadFile({
|
|
||||||
url: `${BASE_URL}/api/operation/sys-media/upload-oss`,
|
|
||||||
filePath: avatarUrl,
|
|
||||||
name: "media",
|
|
||||||
success: (res: any) => {
|
|
||||||
const { data } = JSON.parse(res.data);
|
|
||||||
this.setData({
|
|
||||||
userInfo: {
|
|
||||||
...this.data.userInfo,
|
|
||||||
avatarUrl: data,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
wx.showToast({
|
|
||||||
title: "上传头像失败",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
buildQueryString(params: Record<string, any>): string {
|
buildQueryString(params: Record<string, any>): string {
|
||||||
@@ -288,56 +40,55 @@ Page({
|
|||||||
"/package-live/wxroom/index";
|
"/package-live/wxroom/index";
|
||||||
wx.removeStorageSync(WXROOM_REDIRECT_PATH_KEY);
|
wx.removeStorageSync(WXROOM_REDIRECT_PATH_KEY);
|
||||||
} else {
|
} else {
|
||||||
const store = app.globalData.store;
|
const store = app.globalData.store;
|
||||||
const state = wx.getStorageSync("state") ?? undefined;
|
const state = wx.getStorageSync("state") ?? undefined;
|
||||||
const code = wx.getStorageSync("code") ?? undefined;
|
const code = wx.getStorageSync("code") ?? undefined;
|
||||||
const groupId = wx.getStorageSync("groupId") ?? undefined;
|
const groupId = wx.getStorageSync("groupId") ?? undefined;
|
||||||
|
|
||||||
if (state && !code) {
|
if (state && !code) {
|
||||||
if (self.data.back === "video") {
|
if (self.data.back === "video") {
|
||||||
const storeParams =
|
const storeParams =
|
||||||
typeof store === "string" ? store : this.buildQueryString(store);
|
typeof store === "string" ? store : this.buildQueryString(store);
|
||||||
fullPath = `/pages/live/video/video?${storeParams}`;
|
fullPath = `/pages/live/video/video?${storeParams}`;
|
||||||
} else if (self.data.back === "red") {
|
} else if (self.data.back === "red") {
|
||||||
fullPath = `/pages/common/red/red`;
|
fullPath = `/pages/common/red/red`;
|
||||||
} else if (self.data.back === "user") {
|
} else if (self.data.back === "user") {
|
||||||
fullPath = `/pages/tab-bar/user/user`;
|
fullPath = `/pages/tab-bar/user/user`;
|
||||||
|
} else {
|
||||||
|
fullPath = `/pages/live/registration/registration?state=${state}`;
|
||||||
|
}
|
||||||
|
} else if (!state && code) {
|
||||||
|
if (self.data.back === "video") {
|
||||||
|
const storeParams =
|
||||||
|
typeof store === "string" ? store : this.buildQueryString(store);
|
||||||
|
fullPath = `/pages/live/video/video?${storeParams}`;
|
||||||
|
} else if (self.data.back === "red") {
|
||||||
|
fullPath = `/pages/common/red/red`;
|
||||||
|
} else if (self.data.back === "user") {
|
||||||
|
fullPath = `/pages/tab-bar/user/user`;
|
||||||
|
} else {
|
||||||
|
fullPath = `/pages/live/registration/registration?code=${code}`;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fullPath = `/pages/live/registration/registration?state=${state}`;
|
if (self.data.back === "room") {
|
||||||
|
fullPath = `/pages/live/room/room?groupId=${groupId}`;
|
||||||
|
} else if (self.data.back === "red") {
|
||||||
|
fullPath = `/pages/common/red/red`;
|
||||||
|
} else if (self.data.back === "user") {
|
||||||
|
fullPath = `/pages/tab-bar/user/user`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (!state && code) {
|
|
||||||
if (self.data.back === "video") {
|
|
||||||
const storeParams =
|
|
||||||
typeof store === "string" ? store : this.buildQueryString(store);
|
|
||||||
fullPath = `/pages/live/video/video?${storeParams}`;
|
|
||||||
} else if (self.data.back === "red") {
|
|
||||||
fullPath = `/pages/common/red/red`;
|
|
||||||
} else if (self.data.back === "user") {
|
|
||||||
fullPath = `/pages/tab-bar/user/user`;
|
|
||||||
} else {
|
|
||||||
fullPath = `/pages/live/registration/registration?code=${code}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (self.data.back === "room") {
|
|
||||||
fullPath = `/pages/live/room/room?groupId=${groupId}`;
|
|
||||||
} else if (self.data.back === "red") {
|
|
||||||
fullPath = `/pages/common/red/red`;
|
|
||||||
} else if (self.data.back === "user") {
|
|
||||||
fullPath = `/pages/tab-bar/user/user`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const pages = getCurrentPages();
|
const pages = getCurrentPages();
|
||||||
const currentPage = pages[pages.length - 2];
|
const currentPage = pages[pages.length - 2];
|
||||||
|
|
||||||
if (!currentPage) {
|
if (!currentPage) {
|
||||||
// 如果没有上一页,跳转到第一个可用 tab,而不是硬编码的 index
|
|
||||||
const tabbarItems = app.globalData.tabbarItems;
|
const tabbarItems = app.globalData.tabbarItems;
|
||||||
if (tabbarItems && tabbarItems.length > 0) {
|
if (tabbarItems && tabbarItems.length > 0) {
|
||||||
wx.switchTab({ url: tabbarItems[0].pagePath });
|
wx.switchTab({ url: tabbarItems[0].pagePath });
|
||||||
} else {
|
} else {
|
||||||
wx.switchTab({ url: "/pages/tab-bar/medicine-box/index" });
|
wx.switchTab({ url: "/pages/tab-bar/medicine-box/index" });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -382,33 +133,24 @@ Page({
|
|||||||
const loginRes = await wxLogin();
|
const loginRes = await wxLogin();
|
||||||
if (!loginRes.code) throw new Error(loginRes.errMsg);
|
if (!loginRes.code) throw new Error(loginRes.errMsg);
|
||||||
|
|
||||||
const { avatarUrl, nickName } = this.data.userInfo;
|
|
||||||
const state = wx.getStorageSync("state");
|
const state = wx.getStorageSync("state");
|
||||||
let loginResult: LoginRes;
|
let loginResult: LoginRes;
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
const reqData: Record<string, any> = {
|
|
||||||
state: wx.getStorageSync("state") ?? undefined,
|
|
||||||
...(nickName && nickName !== "微信用户" ? { nickName } : {}),
|
|
||||||
...(avatarUrl && avatarUrl !== defaultAvatarUrl ? { avatarUrl } : {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
loginResult = await wxRequest<LoginRes>({
|
loginResult = await wxRequest<LoginRes>({
|
||||||
url: `${BASE_URL}/api/auth/app-login?appId=${appId}&code=${loginRes.code}`,
|
url: `${BASE_URL}/api/auth/app-login?appId=${appId}&code=${loginRes.code}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: reqData,
|
data: {
|
||||||
|
state: wx.getStorageSync("state") ?? undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const reqData: Record<string, any> = {
|
|
||||||
state: wx.getStorageSync("code") ?? undefined,
|
|
||||||
...(nickName && nickName !== "微信用户" ? { nickName } : {}),
|
|
||||||
...(avatarUrl && avatarUrl !== defaultAvatarUrl ? { avatarUrl } : {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
loginResult = await wxRequest<LoginRes>({
|
loginResult = await wxRequest<LoginRes>({
|
||||||
url: `${BASE_URL}/api/auth/app-auth?appId=${appId}&code=${loginRes.code}`,
|
url: `${BASE_URL}/api/auth/app-auth?appId=${appId}&code=${loginRes.code}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: reqData,
|
data: {
|
||||||
|
state: wx.getStorageSync("code") ?? undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,10 +184,6 @@ Page({
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.globalData.isLogin = true;
|
app.globalData.isLogin = true;
|
||||||
this.triggerEvent("loginSuccess", {
|
|
||||||
userName: resNickName,
|
|
||||||
avatarUrl: resAvatarUrl,
|
|
||||||
});
|
|
||||||
wx.showToast({
|
wx.showToast({
|
||||||
title: "登录成功",
|
title: "登录成功",
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
@@ -477,12 +215,5 @@ Page({
|
|||||||
if (options.back) {
|
if (options.back) {
|
||||||
this.setData({ back: options.back });
|
this.setData({ back: options.back });
|
||||||
}
|
}
|
||||||
this.applyLoginDisplayConfig(options);
|
|
||||||
},
|
|
||||||
|
|
||||||
onShow() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.setData({ nickFocus: true });
|
|
||||||
}, 200);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"navigationBarTitleText": "授权登录",
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { BASE_URL } from "../../env";
|
||||||
|
|
||||||
|
Page({
|
||||||
|
data: {
|
||||||
|
webViewUrl: "",
|
||||||
|
loading: true,
|
||||||
|
backUrl: "",
|
||||||
|
code: "",
|
||||||
|
authCompleted: false, // 防止重复处理
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad(options: any) {
|
||||||
|
if (options.back) {
|
||||||
|
this.setData({ backUrl: decodeURIComponent(options.back) });
|
||||||
|
}
|
||||||
|
const code = options.code || "";
|
||||||
|
this.setData({ code })
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const authUrl = `${BASE_URL}/h5/oauth/auth-success.html?entryCode=${encodeURIComponent(code)}`
|
||||||
|
this.setData({
|
||||||
|
webViewUrl: authUrl,
|
||||||
|
loading: true,
|
||||||
|
});
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/** web-view 首次加载完成,隐藏骨架屏 */
|
||||||
|
onWebViewLoad() {
|
||||||
|
this.setData({ loading: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
onMessage(e: any) {
|
||||||
|
|
||||||
|
const dataList = e.detail?.data || [];
|
||||||
|
console.log("onMessage===========》", dataList);
|
||||||
|
if (dataList.length === 0) return;
|
||||||
|
|
||||||
|
const data = dataList.reduce((acc: any, curr: any) => ({ ...acc, ...curr }), {});
|
||||||
|
console.log("onMessage", data);
|
||||||
|
// 先存储缓存,再操作页面状态
|
||||||
|
const fields: Record<string, string> = {
|
||||||
|
openId: data.openId || '',
|
||||||
|
unionId: data.unionId || '',
|
||||||
|
appId: data.appId || '',
|
||||||
|
userName: data.nickname || '微信用户',
|
||||||
|
avatarUrl: data.avatar || '',
|
||||||
|
code: data.code || '',
|
||||||
|
userId: data.userId || '',
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(fields).forEach(([key, value]) => {
|
||||||
|
if (value) {
|
||||||
|
try {
|
||||||
|
wx.setStorageSync(key, value);
|
||||||
|
} catch (err: any) {
|
||||||
|
console.log("缓存写入失败 key:", key, "error:", err?.message || err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getApp<IAppOption>().globalData.isLogin = true;
|
||||||
|
|
||||||
|
getApp<IAppOption>().globalData.store = {
|
||||||
|
...getApp<IAppOption>().globalData.store,
|
||||||
|
...fields,
|
||||||
|
};
|
||||||
|
|
||||||
|
try { this.setData({ authCompleted: true }); } catch (_) { }
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<!--pages/webview-auth/index.wxml-->
|
||||||
|
<view class="container">
|
||||||
|
<view class="loading" wx:if="{{loading && webViewUrl}}">
|
||||||
|
<view class="loading-spinner"></view>
|
||||||
|
<text class="loading-text">正在加载授权页面...</text>
|
||||||
|
</view>
|
||||||
|
<web-view
|
||||||
|
wx:if="{{webViewUrl}}"
|
||||||
|
src="{{webViewUrl}}"
|
||||||
|
bindmessage="onMessage"
|
||||||
|
bindload="onWebViewLoad"
|
||||||
|
></web-view>
|
||||||
|
</view>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/* pages/webview-auth/index.wxss */
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border: 4rpx solid #e5e5e5;
|
||||||
|
border-top-color: #07c160;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 40rpx;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 300rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
line-height: 72rpx;
|
||||||
|
text-align: center;
|
||||||
|
background: #e64340;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 36rpx;
|
||||||
|
z-index: 999;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(230, 67, 64, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn:active {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BASE_URL, appId } from "../env";
|
import { BASE_URL } from "../env";
|
||||||
import { base64Encode } from "./crypto";
|
import { base64Encode } from "./crypto";
|
||||||
type RequestProps = {
|
type RequestProps = {
|
||||||
options: WechatMiniprogram.RequestOption;
|
options: WechatMiniprogram.RequestOption;
|
||||||
@@ -23,6 +23,7 @@ export const request = <T = any>(
|
|||||||
return Promise.reject(new Error('请先登录'));
|
return Promise.reject(new Error('请先登录'));
|
||||||
}
|
}
|
||||||
const openId = wx.getStorageSync("openId") || "";
|
const openId = wx.getStorageSync("openId") || "";
|
||||||
|
const appId = wx.getStorageSync("appId") || "";
|
||||||
header.Authorization = `Basic ${base64Encode(`${openId}:${appId}`)}`
|
header.Authorization = `Basic ${base64Encode(`${openId}:${appId}`)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -52,5 +52,5 @@
|
|||||||
"ignore": [],
|
"ignore": [],
|
||||||
"include": []
|
"include": []
|
||||||
},
|
},
|
||||||
"appid": "wx2bf5f8e9decdceaf"
|
"appid": "wx53f37c2f7e3a147e"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"module": "CommonJS",
|
||||||
|
"target": "ES2020",
|
||||||
|
"allowJs": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"strict": true,
|
||||||
|
"strictPropertyInitialization": true,
|
||||||
|
"ignoreDeprecations": "6.0",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"types": ["miniprogram-api-typings"],
|
||||||
|
"paths": {
|
||||||
|
"@vant/weapp/*": ["path/to/node_modules/@vant/weapp/dist/*"]
|
||||||
|
},
|
||||||
|
"lib": ["ES2020"],
|
||||||
|
"typeRoots": ["./typings"],
|
||||||
|
"rootDir": "./miniprogram",
|
||||||
|
"outDir": "./dist"
|
||||||
|
},
|
||||||
|
"include": ["./**/*.ts"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user