feat(platform): 开源发布 - 初始化 Open AI Canvas

This commit is contained in:
ddCat
2026-07-22 14:18:14 +08:00
commit aea35896eb
365 changed files with 66410 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
import { App } from "antd";
import copy from "copy-to-clipboard";
export function useCopyText() {
const { message } = App.useApp();
return (value: string, successText = "已复制") => {
copy(value);
message.success(successText);
};
}

View File

@@ -0,0 +1,12 @@
import { useEffect, useState } from "react";
export function useDebouncedValue<T>(value: T, delay = 300) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = window.setTimeout(() => setDebouncedValue(value), delay);
return () => window.clearTimeout(timer);
}, [delay, value]);
return debouncedValue;
}

View File

@@ -0,0 +1,50 @@
import { useCallback, useEffect, useState } from "react";
import { getWallet } from "@/services/api/wallet";
const WALLET_REFRESH_INTERVAL_MS = 30_000;
export function useWalletBalance(userId?: string, enabled = true) {
const [availableMicrocredits, setAvailableMicrocredits] = useState<number | null>(null);
const [refreshing, setRefreshing] = useState(false);
const refresh = useCallback(async () => {
if (!enabled || !userId) {
setAvailableMicrocredits(null);
return;
}
setRefreshing(true);
try {
const wallet = await getWallet(1, 1);
setAvailableMicrocredits(wallet.account.availableMicrocredits);
} catch {
// 顶栏余额是只读辅助信息,读取失败时保留上次成功值,避免短暂网络错误造成闪烁。
} finally {
setRefreshing(false);
}
}, [enabled, userId]);
useEffect(() => {
if (!enabled || !userId) {
setAvailableMicrocredits(null);
return;
}
void refresh();
const timer = window.setInterval(() => void refresh(), WALLET_REFRESH_INTERVAL_MS);
const handleFocus = () => void refresh();
const handleVisibility = () => {
if (document.visibilityState === "visible") void refresh();
};
window.addEventListener("focus", handleFocus);
window.addEventListener("wallet:updated", handleFocus);
document.addEventListener("visibilitychange", handleVisibility);
return () => {
window.clearInterval(timer);
window.removeEventListener("focus", handleFocus);
window.removeEventListener("wallet:updated", handleFocus);
document.removeEventListener("visibilitychange", handleVisibility);
};
}, [enabled, refresh, userId]);
return { availableMicrocredits, refreshing, refresh };
}