feat(dcauth): 新增常驻托盘客户端与版本显示

Windows 改为单实例托盘常驻,协议唤起只弹一个确认窗口;补充 macOS 后台守护进程
与客户端版本显示。
This commit is contained in:
yml2213
2026-10-21 20:46:25 +08:00
parent 040100f290
commit cb916d7750
12 changed files with 1087 additions and 73 deletions
@@ -25,6 +25,9 @@ type LoginForm = {
smsCode: string
}
const isMacPlatform =
typeof navigator !== 'undefined' && /Macintosh|Mac OS X|iPhone|iPad/i.test(navigator.userAgent)
const brandFeatures = [
{
icon: <DashboardOutlined />,
@@ -54,6 +57,7 @@ export default function AdminLoginPage() {
const [waiting, setWaiting] = useState(false)
const [devLaunchUrl, setDevLaunchUrl] = useState('')
const timerRef = useRef<number | null>(null)
const submittingRef = useRef(false)
useEffect(() => {
return () => {
@@ -94,6 +98,8 @@ export default function AdminLoginPage() {
}
async function submitLogin(values: LoginForm) {
if (submittingRef.current) return
submittingRef.current = true
setLoading(true)
setWaiting(false)
try {
@@ -105,7 +111,7 @@ export default function AdminLoginPage() {
})
setPhoneMasked(prepared.data.phoneMasked)
setWaiting(true)
setDevLaunchUrl(import.meta.env.DEV ? prepared.data.launchUrl : '')
setDevLaunchUrl(import.meta.env.DEV && isMacPlatform ? prepared.data.launchUrl : '')
message.info('已发起本机验证,请在弹出的 DCAuth 窗口中确认')
launchProtocol(prepared.data.launchUrl)
@@ -121,6 +127,7 @@ export default function AdminLoginPage() {
message.error(error instanceof Error ? error.message : '登录失败')
}
} finally {
submittingRef.current = false
setLoading(false)
setWaiting(false)
setDevLaunchUrl('')
@@ -128,12 +135,14 @@ export default function AdminLoginPage() {
}
async function submitLegacyLogin() {
if (submittingRef.current) return
let values: Pick<LoginForm, 'username' | 'password'>
try {
values = await form.validateFields(['username', 'password'])
} catch {
return
}
submittingRef.current = true
setLoading(true)
try {
const response = await loginAdmin({
@@ -146,6 +155,7 @@ export default function AdminLoginPage() {
} catch (error) {
message.error(error instanceof Error ? error.message : '账号密码登录失败')
} finally {
submittingRef.current = false
setLoading(false)
}
}