Files
2026-06-19 18:45:55 +08:00

288 lines
7.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {ipcMain, shell} from "electron";
import {AppConfig} from "../../../src/config";
import {ResultType} from "../../lib/api";
import {Events} from "../event/main";
import {platformUUID} from "../../lib/env";
import {AppsMain} from "../app/main";
import Apps from "../app";
import StorageMain from "../storage/main";
import {Log} from "../log/main";
const init = async () => {
// 用户功能未启用,跳过自动刷新
console.log('[User.init] 跳过用户信息自动刷新(userEnable=false');
Log.info('User.init', '跳过用户信息自动刷新(userEnable=false');
return null;
// 注释:原来的代码会调用 refresh() API,但用户功能未启用,所以永久禁用
// setTimeout(() => {
// refresh().then();
// }, 1000);
};
const userData = {
isInit: false,
apiToken: "",
user: {
id: "",
name: "",
avatar: "",
deviceCode: "",
},
data: {},
basic: {},
};
const get = async (): Promise<{
apiToken: string;
user: {
id: string;
name: string;
avatar: string;
deviceCode: string;
};
data: {
[key: string]: any;
};
basic: {
[key: string]: any;
};
}> => {
if (!userData.isInit) {
const userStorageData = await StorageMain.get("user", "data", {});
userData.apiToken = userStorageData.apiToken || "";
userData.user = userStorageData.user || {};
userData.data = userStorageData.data || {};
userData.basic = userStorageData.basic || {};
userData.isInit = true;
}
userData.user.id = userData.user.id || "";
return {
apiToken: userData.apiToken,
user: userData.user,
data: userData.data,
basic: userData.basic,
};
};
ipcMain.handle(
"user:open",
async (
event,
option?: {
readyParam: {
page?: string;
[key: string]: any;
};
}
) => {
option = Object.assign(
{
readyParam: null,
},
option || {}
);
await AppsMain.windowOpen("user", option);
if (option.readyParam) {
await Events.callPage("user", "ready", option.readyParam);
}
}
);
ipcMain.handle("user:get", async event => {
return get();
});
const save = async (data: {apiToken: string; user: any; data: any; basic: {}}) => {
userData.apiToken = data.apiToken || "";
userData.user = data.user || {};
userData.data = data.data || {};
userData.user.id = userData.user.id || "";
Events.broadcast("UserChange", {});
await StorageMain.set("user", "data", {
apiToken: data.apiToken,
user: data.user,
data: data.data,
basic: data.basic,
});
};
ipcMain.handle("user:save", async (event, data) => {
return save(data);
});
const refresh = async () => {
const result = await userInfoApi();
// console.log("user.refresh", JSON.stringify(result, null, 2));
await save({
apiToken: result.data.apiToken,
user: result.data.user,
data: result.data.data,
basic: result.data.basic,
});
};
ipcMain.handle("user:refresh", async event => {
return refresh();
});
const getApiToken = async (): Promise<string> => {
await get();
return userData.apiToken;
};
ipcMain.handle("user:getApiToken", async event => {
return getApiToken();
});
const getWebEnterUrl = async (url: string) => {
let param = [];
const apiToken = await getApiToken();
if (apiToken) {
param.push(`api_token=${apiToken}`);
}
if (await AppsMain.shouldDarkMode()) {
param.push(`is_dark=1`);
}
param.push(`device_uuid=${platformUUID()}`);
param.push(`url=${encodeURIComponent(url)}`);
return `${AppConfig.apiBaseUrl}/app_manager/enter?${param.join("&")}`;
};
ipcMain.handle("user:getWebEnterUrl", async (event, url) => {
return getWebEnterUrl(url);
});
const openWebUrl = async (url: string) => {
url = await getWebEnterUrl(url);
await shell.openExternal(url);
};
ipcMain.handle("user:openWebUrl", async (event, url) => {
return openWebUrl(url);
});
const apiPost = async (
url: string,
data: Record<string, any>,
option?: {
throwException?: boolean;
}
) => {
return post(url, data, option);
};
ipcMain.handle("user:apiPost", async (event, url, data, option) => {
return apiPost(url, data, option);
});
export const User = {
init,
get,
save,
getApiToken,
getWebEnterUrl,
openWebUrl,
};
export default User;
const post = async <T>(
api: string,
data: Record<string, any>,
option?: {
throwException?: boolean;
retry?: number;
retryTimes?: number;
retryInterval?: number;
}
): Promise<ResultType<T>> => {
option = Object.assign(
{
throwException: true,
retry: 0,
retryTimes: 0,
retryInterval: 5,
},
option
);
let url = api;
if (!api.startsWith("http:") && !api.startsWith("https:")) {
url = `${AppConfig.apiBaseUrl}/${api}`;
}
const apiToken = await User.getApiToken();
let json = null,
res = null;
try {
res = await fetch(url, {
method: "POST",
headers: {
"User-Agent": Apps.getUserAgent(),
"Content-Type": "application/json",
"Api-Token": apiToken,
},
body: JSON.stringify(data),
});
if (res.status !== 200) {
if (option.retry > 0 && option.retryTimes < option.retry) {
option.retryTimes++;
Log.info("user.post.retry", {api, data, res, retryTimes: option.retryTimes});
await new Promise(resolve => setTimeout(resolve, option.retryInterval * 1000));
return await post(api, data, option);
}
Log.error("user.post.error", {api, data, res});
if (option.throwException) {
throw `RequestError(code:${res.status},text:${res.statusText})`;
}
return {
code: 10000,
msg: `RequestError(code:${res.status},text:${res.statusText})`,
} as ResultType<T>;
}
json = await res.json();
} catch (e) {
res = `RequestError(${e})`;
}
// console.log('post', JSON.stringify({api, data, json}, null, 2))
if (!json || !("code" in json)) {
if (option.retry > 0 && option.retryTimes < option.retry) {
option.retryTimes++;
Log.info("user.post.retry", {api, data, res, retryTimes: option.retryTimes});
await new Promise(resolve => setTimeout(resolve, option.retryInterval * 1000));
return await post(api, data, option);
}
Log.error("user.post.error", {api, data, res});
if (option.throwException) {
throw "ResponseError";
}
return {code: 10000, msg: "ResponseError"};
}
if (json.code) {
// login required
if (json.code === 1001) {
if (userData.user && userData.user.id) {
await refresh();
}
}
if (option.throwException) {
throw json.msg;
}
}
return json;
};
const userInfoApi = async (): Promise<
ResultType<{
apiToken: string;
user: object;
data: any;
basic: object;
}>
> => {
return await post("app_manager/user_info", {});
};
export const UserApi = {
post,
userInfoApi,
};